activemerchant 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +226 -0
- data/CONTRIBUTERS +52 -0
- data/README +34 -24
- data/Rakefile +152 -0
- data/gem-public_cert.pem +20 -0
- data/init.rb +3 -0
- data/lib/active_merchant.rb +3 -1
- data/lib/active_merchant/billing/credit_card.rb +21 -17
- data/lib/active_merchant/billing/credit_card_methods.rb +17 -19
- data/lib/active_merchant/billing/gateway.rb +160 -44
- data/lib/active_merchant/billing/gateways.rb +2 -15
- data/lib/active_merchant/billing/gateways/authorize_net.rb +21 -21
- data/lib/active_merchant/billing/gateways/bogus.rb +6 -6
- data/lib/active_merchant/billing/gateways/brain_tree.rb +191 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +207 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +402 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +41 -97
- data/lib/active_merchant/billing/gateways/efsnet.rb +256 -0
- data/lib/active_merchant/billing/gateways/eway.rb +77 -29
- data/lib/active_merchant/billing/gateways/exact.rb +230 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -33
- data/lib/active_merchant/billing/gateways/moneris.rb +155 -125
- data/lib/active_merchant/billing/gateways/net_registry.rb +257 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +407 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +163 -25
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +56 -38
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +10 -1
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +9 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +36 -11
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +6 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +7 -3
- data/lib/active_merchant/billing/gateways/payment_express.rb +261 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +18 -4
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +31 -15
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +8 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +33 -8
- data/lib/active_merchant/billing/gateways/plugnpay.rb +300 -0
- data/lib/active_merchant/billing/gateways/protx.rb +285 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +13 -12
- data/lib/active_merchant/billing/gateways/psl_card.rb +297 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +197 -0
- data/lib/active_merchant/billing/gateways/realex.rb +212 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +136 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +43 -20
- data/lib/active_merchant/billing/gateways/usa_epay.rb +6 -5
- data/lib/active_merchant/billing/gateways/verifi.rb +235 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +171 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +0 -2
- data/lib/active_merchant/billing/integrations/helper.rb +8 -1
- data/lib/active_merchant/billing/integrations/nochex.rb +62 -1
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +9 -16
- data/lib/active_merchant/billing/integrations/notification.rb +1 -1
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +59 -46
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +14 -47
- data/lib/active_merchant/lib/error.rb +4 -0
- data/lib/active_merchant/lib/post_data.rb +22 -0
- data/lib/active_merchant/lib/posts_data.rb +23 -5
- data/lib/active_merchant/lib/requires_parameters.rb +2 -2
- data/lib/active_merchant/lib/validateable.rb +1 -1
- data/lib/support/gateway_support.rb +45 -0
- data/lib/tasks/cia.rb +1 -1
- data/script/generate +14 -0
- data/script/generator/base.rb +45 -0
- data/script/generator/generator.rb +24 -0
- data/script/generator/generators/gateway/gateway_generator.rb +14 -0
- data/script/generator/generators/gateway/templates/gateway.rb +73 -0
- data/script/generator/generators/gateway/templates/gateway_test.rb +41 -0
- data/script/generator/generators/gateway/templates/remote_gateway_test.rb +56 -0
- data/script/generator/generators/integration/integration_generator.rb +25 -0
- data/script/generator/generators/integration/templates/helper.rb +34 -0
- data/script/generator/generators/integration/templates/helper_test.rb +54 -0
- data/script/generator/generators/integration/templates/integration.rb +18 -0
- data/script/generator/generators/integration/templates/module_test.rb +9 -0
- data/script/generator/generators/integration/templates/notification.rb +100 -0
- data/script/generator/generators/integration/templates/notification_test.rb +41 -0
- data/script/generator/manifest.rb +20 -0
- data/test/extra/binding_of_caller.rb +80 -0
- data/test/extra/breakpoint.rb +547 -0
- data/test/fixtures.yml +251 -0
- data/test/remote_tests/remote_authorize_net_test.rb +113 -0
- data/test/remote_tests/remote_brain_tree_test.rb +78 -0
- data/test/remote_tests/remote_card_stream_test.rb +160 -0
- data/test/remote_tests/remote_cyber_source_test.rb +130 -0
- data/test/remote_tests/remote_data_cash_test.rb +155 -0
- data/test/remote_tests/remote_efsnet_test.rb +93 -0
- data/test/remote_tests/remote_eway_test.rb +71 -0
- data/test/remote_tests/remote_exact_test.rb +59 -0
- data/test/remote_tests/remote_gestpay_integration_test.rb +37 -0
- data/test/remote_tests/remote_linkpoint_test.rb +144 -0
- data/test/remote_tests/remote_moneris_test.rb +110 -0
- data/test/remote_tests/remote_net_registry_test.rb +120 -0
- data/test/remote_tests/remote_pay_junction_test.rb +162 -0
- data/test/remote_tests/remote_payflow_express_test.rb +50 -0
- data/test/remote_tests/remote_payflow_test.rb +241 -0
- data/test/remote_tests/remote_payflow_uk_test.rb +172 -0
- data/test/remote_tests/remote_payment_express_test.rb +136 -0
- data/test/remote_tests/remote_paypal_express_test.rb +49 -0
- data/test/remote_tests/remote_paypal_integration_test.rb +14 -0
- data/test/remote_tests/remote_paypal_test.rb +163 -0
- data/test/remote_tests/remote_plugnpay_test.rb +70 -0
- data/test/remote_tests/remote_protx_test.rb +184 -0
- data/test/remote_tests/remote_psigate_test.rb +87 -0
- data/test/remote_tests/remote_psl_card_test.rb +105 -0
- data/test/remote_tests/remote_quickpay_test.rb +182 -0
- data/test/remote_tests/remote_realex_test.rb +227 -0
- data/test/remote_tests/remote_secure_pay_test.rb +36 -0
- data/test/remote_tests/remote_trans_first_test.rb +37 -0
- data/test/remote_tests/remote_trust_commerce_test.rb +136 -0
- data/test/remote_tests/remote_usa_epay_test.rb +57 -0
- data/test/remote_tests/remote_verifi_test.rb +107 -0
- data/test/remote_tests/remote_viaklix_test.rb +53 -0
- data/test/test_helper.rb +132 -0
- data/test/unit/base_test.rb +61 -0
- data/test/unit/country_code_test.rb +33 -0
- data/test/unit/country_test.rb +64 -0
- data/test/unit/credit_card_formatting_test.rb +24 -0
- data/test/unit/credit_card_methods_test.rb +37 -0
- data/test/unit/credit_card_test.rb +365 -0
- data/test/unit/gateways/authorize_net_test.rb +140 -0
- data/test/unit/gateways/bogus_test.rb +43 -0
- data/test/unit/gateways/brain_tree_test.rb +77 -0
- data/test/unit/gateways/card_stream_test.rb +37 -0
- data/test/unit/gateways/cyber_source_test.rb +151 -0
- data/test/unit/gateways/data_cash_test.rb +23 -0
- data/test/unit/gateways/efsnet_test.rb +70 -0
- data/test/unit/gateways/eway_test.rb +105 -0
- data/test/unit/gateways/exact_test.rb +118 -0
- data/test/unit/gateways/gateway_test.rb +24 -0
- data/test/unit/gateways/linkpoint_test.rb +165 -0
- data/test/unit/gateways/moneris_test.rb +167 -0
- data/test/unit/gateways/net_registry_test.rb +478 -0
- data/test/unit/gateways/pay_junction_test.rb +61 -0
- data/test/unit/gateways/payflow_express_test.rb +165 -0
- data/test/unit/gateways/payflow_express_uk_test.rb +14 -0
- data/test/unit/gateways/payflow_test.rb +230 -0
- data/test/unit/gateways/payflow_uk_test.rb +68 -0
- data/test/unit/gateways/payment_express_test.rb +215 -0
- data/test/unit/gateways/paypal_express_test.rb +222 -0
- data/test/unit/gateways/paypal_test.rb +241 -0
- data/test/unit/gateways/plugnpay_test.rb +79 -0
- data/test/unit/gateways/protx_test.rb +110 -0
- data/test/unit/gateways/psigate_test.rb +110 -0
- data/test/unit/gateways/psl_card_test.rb +51 -0
- data/test/unit/gateways/quickpay_test.rb +125 -0
- data/test/unit/gateways/realex_test.rb +150 -0
- data/test/unit/gateways/secure_pay_test.rb +78 -0
- data/test/unit/gateways/trans_first_test.rb +125 -0
- data/test/unit/gateways/trust_commerce_test.rb +57 -0
- data/test/unit/gateways/usa_epay_test.rb +117 -0
- data/test/unit/gateways/verifi_test.rb +91 -0
- data/test/unit/gateways/viaklix_test.rb +72 -0
- data/test/unit/integrations/action_view_helper_test.rb +54 -0
- data/test/unit/integrations/bogus_module_test.rb +16 -0
- data/test/unit/integrations/chronopay_module_test.rb +9 -0
- data/test/unit/integrations/gestpay_module_test.rb +10 -0
- data/test/unit/integrations/helpers/bogus_helper_test.rb +28 -0
- data/test/unit/integrations/helpers/chronopay_helper_test.rb +67 -0
- data/test/unit/integrations/helpers/gestpay_helper_test.rb +100 -0
- data/test/unit/integrations/helpers/nochex_helper_test.rb +53 -0
- data/test/unit/integrations/helpers/paypal_helper_test.rb +162 -0
- data/test/unit/integrations/helpers/two_checkout_helper_test.rb +92 -0
- data/test/unit/integrations/nochex_module_test.rb +9 -0
- data/test/unit/integrations/notifications/chronopay_notification_test.rb +66 -0
- data/test/unit/integrations/notifications/gestpay_notification_test.rb +60 -0
- data/test/unit/integrations/notifications/nochex_notification_test.rb +51 -0
- data/test/unit/integrations/notifications/notification_test.rb +41 -0
- data/test/unit/integrations/notifications/paypal_notification_test.rb +85 -0
- data/test/unit/integrations/notifications/two_checkout_notification_test.rb +55 -0
- data/test/unit/integrations/paypal_module_test.rb +24 -0
- data/test/unit/integrations/two_checkout_module_test.rb +9 -0
- data/test/unit/post_data_test.rb +55 -0
- data/test/unit/response_test.rb +14 -0
- data/test/unit/validateable_test.rb +56 -0
- metadata +160 -7
- metadata.gz.sig +0 -0
- data/lib/active_merchant/billing/gateways/payflow/f73e89fd.0 +0 -17
@@ -30,8 +30,6 @@ module ActiveMerchant #:nodoc:
|
|
30
30
|
:expiry_year => 'PAY1_EXPYEAR',
|
31
31
|
:verification_value => 'PAY1_CVV'
|
32
32
|
|
33
|
-
mapping :billing_address, {}
|
34
|
-
|
35
33
|
def customer(params = {})
|
36
34
|
add_field(mappings[:customer][:email], params[:email])
|
37
35
|
add_field('PAY1_CHNAME', "#{params[:first_name]} #{params[:last_name]}")
|
@@ -7,6 +7,11 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
class_inheritable_hash :mappings
|
8
8
|
class_inheritable_accessor :country_format
|
9
9
|
self.country_format = :alpha2
|
10
|
+
|
11
|
+
# The application making the calls to the gateway
|
12
|
+
# Useful for things like the PayPal build notation (BN) id fields
|
13
|
+
class_inheritable_accessor :application_id
|
14
|
+
self.application_id = 'ActiveMerchant'
|
10
15
|
|
11
16
|
def initialize(order, account, options = {})
|
12
17
|
options.assert_valid_keys([:amount, :currency, :test])
|
@@ -49,8 +54,10 @@ module ActiveMerchant #:nodoc:
|
|
49
54
|
private
|
50
55
|
|
51
56
|
def add_address(key, params)
|
57
|
+
return if mappings[key].nil?
|
58
|
+
|
52
59
|
code = lookup_country_code(params.delete(:country))
|
53
|
-
add_field(mappings[key][:country], code)
|
60
|
+
add_field(mappings[key][:country], code)
|
54
61
|
add_fields(key, params)
|
55
62
|
end
|
56
63
|
|
@@ -4,6 +4,65 @@ require File.dirname(__FILE__) + '/nochex/notification.rb'
|
|
4
4
|
module ActiveMerchant #:nodoc:
|
5
5
|
module Billing #:nodoc:
|
6
6
|
module Integrations #:nodoc:
|
7
|
+
# To start with Nochex, follow the instructions for installing
|
8
|
+
# ActiveMerchant as a plugin, as described on
|
9
|
+
# http://www.activemerchant.org/.
|
10
|
+
#
|
11
|
+
# The plugin will automatically add the ActionView helper for
|
12
|
+
# ActiveMerchant, which will allow you to make the Nochex payments.
|
13
|
+
# The idea behind the helper is that it generates an invisible
|
14
|
+
# forwarding screen that will automatically redirect the user.
|
15
|
+
# So you would collect all the information about the order and then
|
16
|
+
# simply render the hidden form, which redirects the user to Nochex.
|
17
|
+
#
|
18
|
+
# The syntax of the helper is as follows:
|
19
|
+
#
|
20
|
+
# <% payment_service_for 'order id', 'nochex_user_id',
|
21
|
+
# :amount => 50.00,
|
22
|
+
# :service => :nochex,
|
23
|
+
# :html => { :id => 'nochex-form' } do |service| %>
|
24
|
+
#
|
25
|
+
# <% service.customer :first_name => 'Cody',
|
26
|
+
# :last_name => 'Fauser',
|
27
|
+
# :phone => '(555)555-5555',
|
28
|
+
# :email => 'cody@example.com' %>
|
29
|
+
#
|
30
|
+
# <% service.billing_address :city => 'Ottawa',
|
31
|
+
# :address1 => '21 Snowy Brook Lane',
|
32
|
+
# :address2 => 'Apt. 36',
|
33
|
+
# :state => 'ON',
|
34
|
+
# :country => 'CA',
|
35
|
+
# :zip => 'K1J1E5' %>
|
36
|
+
#
|
37
|
+
# <% service.invoice '#1000' %>
|
38
|
+
# <% service.shipping '0.00' %>
|
39
|
+
# <% service.tax '0.00' %>
|
40
|
+
#
|
41
|
+
# <% service.notify_url url_for(:action => 'notify', :only_path => false) %>
|
42
|
+
# <% service.return_url url_for(:action => 'done', :only_path => false) %>
|
43
|
+
# <% service.cancel_return_url 'http://mystore.com' %>
|
44
|
+
# <% end %>
|
45
|
+
#
|
46
|
+
# The notify_url is the URL that the Nochex IPN will be sent. You can
|
47
|
+
# handle the notification in your controller action as follows:
|
48
|
+
#
|
49
|
+
# class NotificationController < ApplicationController
|
50
|
+
# include ActiveMerchant::Billing::Integrations
|
51
|
+
#
|
52
|
+
# def notify
|
53
|
+
# notification = Nochex::Notification.new(request.raw_post)
|
54
|
+
#
|
55
|
+
# begin
|
56
|
+
# # Acknowledge notification with Nochex
|
57
|
+
# raise StandardError, 'Illegal Notification' unless notification.acknowledge
|
58
|
+
# # Process the payment
|
59
|
+
# rescue => e
|
60
|
+
# logger.warn("Illegal notification received: #{e.message}")
|
61
|
+
# ensure
|
62
|
+
# head(:ok)
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
# end
|
7
66
|
module Nochex
|
8
67
|
|
9
68
|
mattr_accessor :service_url
|
@@ -12,10 +71,12 @@ module ActiveMerchant #:nodoc:
|
|
12
71
|
mattr_accessor :notification_confirmation_url
|
13
72
|
self.notification_confirmation_url = 'https://www.nochex.com/nochex.dll/apc/apc'
|
14
73
|
|
74
|
+
# Simply a convenience method that returns a new
|
75
|
+
# ActiveMerchant::Billing::Integrations::Nochex::Notification
|
15
76
|
def self.notification(post)
|
16
77
|
Notification.new(post)
|
17
78
|
end
|
18
79
|
end
|
19
80
|
end
|
20
81
|
end
|
21
|
-
end
|
82
|
+
end
|
@@ -74,25 +74,18 @@ module ActiveMerchant #:nodoc:
|
|
74
74
|
# else
|
75
75
|
# ... log possible hacking attempt ...
|
76
76
|
# end
|
77
|
-
def acknowledge
|
78
|
-
|
77
|
+
def acknowledge
|
78
|
+
payload = raw
|
79
79
|
|
80
|
-
|
80
|
+
response = ssl_post(Nochex.notification_confirmation_url, payload,
|
81
|
+
'Content-Length' => "#{payload.size}",
|
82
|
+
'User-Agent' => "Active Merchant -- http://activemerchant.org",
|
83
|
+
'Content-Type' => "application/x-www-form-urlencoded"
|
84
|
+
)
|
81
85
|
|
82
|
-
|
86
|
+
raise StandardError.new("Faulty Nochex result: #{response}") unless ["AUTHORISED", "DECLINED"].include?(response)
|
83
87
|
|
84
|
-
|
85
|
-
request['User-Agent'] = "Active Merchant -- http://home.leetsoft.com/am"
|
86
|
-
request['Content-Type'] = "application/x-www-form-urlencoded"
|
87
|
-
|
88
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
89
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @ssl_strict
|
90
|
-
http.use_ssl = true
|
91
|
-
|
92
|
-
response = http.request(request, payload)
|
93
|
-
|
94
|
-
raise StandardError.new("Faulty Nochex result: #{response.body}") unless ["AUTHORISED", "DECLINED"].include?(response.body)
|
95
|
-
response.body == "AUTHORISED"
|
88
|
+
response == "AUTHORISED"
|
96
89
|
end
|
97
90
|
end
|
98
91
|
end
|
@@ -43,7 +43,7 @@ module ActiveMerchant #:nodoc:
|
|
43
43
|
def parse(post)
|
44
44
|
@raw = post.to_s
|
45
45
|
for line in @raw.split('&')
|
46
|
-
key, value = *line.scan( %r{^(
|
46
|
+
key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
|
47
47
|
params[key] = CGI.unescape(value)
|
48
48
|
end
|
49
49
|
end
|
@@ -29,7 +29,8 @@ module ActiveMerchant #:nodoc:
|
|
29
29
|
add_field('no_shipping', '1')
|
30
30
|
add_field('no_note', '1')
|
31
31
|
add_field('charset', 'utf-8')
|
32
|
-
add_field('address_override', '
|
32
|
+
add_field('address_override', '0')
|
33
|
+
add_field('bn', application_id.to_s.slice(0,32)) unless application_id.blank?
|
33
34
|
end
|
34
35
|
|
35
36
|
mapping :amount, 'amount'
|
@@ -45,57 +46,69 @@ module ActiveMerchant #:nodoc:
|
|
45
46
|
mapping :no_note, 'no_note'
|
46
47
|
mapping :address_override, 'address_override'
|
47
48
|
|
49
|
+
mapping :application_id, 'bn'
|
50
|
+
|
48
51
|
mapping :customer, :first_name => 'first_name',
|
49
52
|
:last_name => 'last_name',
|
50
|
-
:email => 'email'
|
51
|
-
:phone => 'night_phone_a'
|
53
|
+
:email => 'email'
|
52
54
|
|
53
|
-
mapping :
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
mapping :shipping_address, :city => 'city',
|
56
|
+
:address1 => 'address1',
|
57
|
+
:address2 => 'address2',
|
58
|
+
:state => 'state',
|
59
|
+
:zip => 'zip',
|
60
|
+
:country => 'country'
|
61
|
+
|
62
|
+
def shipping_address(params = {})
|
63
|
+
|
64
|
+
if params.has_key?(:phone)
|
65
|
+
phone = params.delete(:phone).to_s
|
66
|
+
|
67
|
+
# Whipe all non digits
|
68
|
+
phone.gsub!(/\D+/, '')
|
69
|
+
|
70
|
+
# Parse in the us style (555 555 5555) which seems to be the only format paypal supports. Ignore anything before this.
|
71
|
+
if phone =~ /(\d{3})(\d{3})(\d{4})$/
|
72
|
+
add_field('night_phone_a', $1)
|
73
|
+
add_field('night_phone_b', $2)
|
74
|
+
add_field('night_phone_c', $3)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get the country code in the correct format
|
79
|
+
# Use what we were given if we can't find anything
|
80
|
+
country_code = lookup_country_code(params.delete(:country))
|
81
|
+
add_field(mappings[:shipping_address][:country], country_code)
|
82
|
+
|
83
|
+
province_code = params.delete(:state)
|
84
|
+
|
85
|
+
case country_code
|
86
|
+
when 'CA'
|
87
|
+
add_field(mappings[:shipping_address][:state], CANADIAN_PROVINCES[province_code.upcase]) unless province_code.nil?
|
88
|
+
when 'US'
|
89
|
+
add_field(mappings[:shipping_address][:state], province_code)
|
90
|
+
else
|
91
|
+
add_field(mappings[:shipping_address][:state], province_code.blank? ? 'N/A' : province_code)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Everything else
|
95
|
+
params.each do |k, v|
|
96
|
+
field = mappings[:shipping_address][k]
|
97
|
+
add_field(field, v) unless field.nil?
|
98
|
+
end
|
99
|
+
end
|
62
100
|
|
63
|
-
def billing_address(params = {})
|
64
|
-
|
65
|
-
if params.has_key?(:phone)
|
66
|
-
phone = params.delete(:phone).to_s
|
67
|
-
|
68
|
-
# Whipe all non digits
|
69
|
-
phone.gsub!(/\D+/, '')
|
70
|
-
|
71
|
-
# Parse in the us style (555 555 5555) which seems to be the only format paypal supports. Ignore anything before this.
|
72
|
-
if phone =~ /(\d{3})(\d{3})(\d{4})$/
|
73
|
-
add_field(mappings[:billing_address][:phone_a], $1)
|
74
|
-
add_field(mappings[:billing_address][:phone_b], $2)
|
75
|
-
add_field(mappings[:billing_address][:phone_c], $3)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# Get the country code in the correct format
|
80
|
-
# Use what we were given if we can't find anything
|
81
|
-
country_code = lookup_country_code(params.delete(:country))
|
82
|
-
add_field(mappings[:billing_address][:country], country_code)
|
83
|
-
# Fix Canadian province if required
|
84
|
-
if country_code == 'CA'
|
85
|
-
province_code = params.delete(:state)
|
86
|
-
add_field(mappings[:billing_address][:state], CANADIAN_PROVINCES[province_code.upcase]) unless province_code.nil?
|
87
|
-
end
|
88
|
-
|
89
|
-
# Everything else
|
90
|
-
params.each do |k, v|
|
91
|
-
field = mappings[:billing_address][k]
|
92
|
-
add_field(field, v) unless field.nil?
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
|
97
101
|
mapping :tax, 'tax'
|
98
102
|
mapping :shipping, 'shipping'
|
103
|
+
mapping :cmd, 'cmd'
|
104
|
+
mapping :custom, 'custom'
|
105
|
+
mapping :src, 'src'
|
106
|
+
mapping :sra, 'sra'
|
107
|
+
%w(a p t).each do |l|
|
108
|
+
(1..3).each do |i|
|
109
|
+
mapping "#{l}#{i}".to_sym, "#{l}#{i}"
|
110
|
+
end
|
111
|
+
end
|
99
112
|
end
|
100
113
|
end
|
101
114
|
end
|
@@ -42,36 +42,8 @@ module ActiveMerchant #:nodoc:
|
|
42
42
|
# end
|
43
43
|
# end
|
44
44
|
class Notification < ActiveMerchant::Billing::Integrations::Notification
|
45
|
-
|
46
|
-
|
47
|
-
# Example:
|
48
|
-
# Paypal::Notification.paypal_cert = File::read("paypal_cert.pem")
|
49
|
-
cattr_accessor :paypal_cert
|
50
|
-
@@paypal_cert = """
|
51
|
-
-----BEGIN CERTIFICATE-----
|
52
|
-
MIIDoTCCAwqgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBmDELMAkGA1UEBhMCVVMx
|
53
|
-
EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBKb3NlMRUwEwYDVQQK
|
54
|
-
EwxQYXlQYWwsIEluYy4xFjAUBgNVBAsUDXNhbmRib3hfY2VydHMxFDASBgNVBAMU
|
55
|
-
C3NhbmRib3hfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0
|
56
|
-
MDQxOTA3MDI1NFoXDTM1MDQxOTA3MDI1NFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD
|
57
|
-
VQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEVMBMGA1UEChMMUGF5
|
58
|
-
UGFsLCBJbmMuMRYwFAYDVQQLFA1zYW5kYm94X2NlcnRzMRQwEgYDVQQDFAtzYW5k
|
59
|
-
Ym94X2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbTCBnzANBgkqhkiG
|
60
|
-
9w0BAQEFAAOBjQAwgYkCgYEAt5bjv/0N0qN3TiBL+1+L/EjpO1jeqPaJC1fDi+cC
|
61
|
-
6t6tTbQ55Od4poT8xjSzNH5S48iHdZh0C7EqfE1MPCc2coJqCSpDqxmOrO+9QXsj
|
62
|
-
HWAnx6sb6foHHpsPm7WgQyUmDsNwTWT3OGR398ERmBzzcoL5owf3zBSpRP0NlTWo
|
63
|
-
nPMCAwEAAaOB+DCB9TAdBgNVHQ4EFgQUgy4i2asqiC1rp5Ms81Dx8nfVqdIwgcUG
|
64
|
-
A1UdIwSBvTCBuoAUgy4i2asqiC1rp5Ms81Dx8nfVqdKhgZ6kgZswgZgxCzAJBgNV
|
65
|
-
BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEV
|
66
|
-
MBMGA1UEChMMUGF5UGFsLCBJbmMuMRYwFAYDVQQLFA1zYW5kYm94X2NlcnRzMRQw
|
67
|
-
EgYDVQQDFAtzYW5kYm94X2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNv
|
68
|
-
bYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAFc288DYGX+GX2+W
|
69
|
-
P/dwdXwficf+rlG+0V9GBPJZYKZJQ069W/ZRkUuWFQ+Opd2yhPpneGezmw3aU222
|
70
|
-
CGrdKhOrBJRRcpoO3FjHHmXWkqgbQqDWdG7S+/l8n1QfDPp+jpULOrcnGEUY41Im
|
71
|
-
jZJTylbJQ1b5PBBjGiP0PpK48cdF
|
72
|
-
-----END CERTIFICATE-----
|
73
|
-
"""
|
74
|
-
|
45
|
+
include PostsData
|
46
|
+
|
75
47
|
# Was the transaction complete?
|
76
48
|
def complete?
|
77
49
|
status == "Completed"
|
@@ -144,6 +116,10 @@ jZJTylbJQ1b5PBBjGiP0PpK48cdF
|
|
144
116
|
def test?
|
145
117
|
params['test_ipn'] == '1'
|
146
118
|
end
|
119
|
+
|
120
|
+
def account
|
121
|
+
params['business'] || params['receiver_email']
|
122
|
+
end
|
147
123
|
|
148
124
|
# Acknowledge the transaction to paypal. This method has to be called after a new
|
149
125
|
# ipn arrives. Paypal will verify that all the information we received are correct and will return a
|
@@ -159,26 +135,17 @@ jZJTylbJQ1b5PBBjGiP0PpK48cdF
|
|
159
135
|
# else
|
160
136
|
# ... log possible hacking attempt ...
|
161
137
|
# end
|
162
|
-
def acknowledge
|
138
|
+
def acknowledge
|
163
139
|
payload = raw
|
164
140
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
173
|
-
|
174
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @ssl_strict
|
175
|
-
http.use_ssl = true
|
176
|
-
|
177
|
-
request = http.request(request, payload)
|
178
|
-
|
179
|
-
raise StandardError.new("Faulty paypal result: #{request.body}") unless ["VERIFIED", "INVALID"].include?(request.body)
|
141
|
+
response = ssl_post(Paypal.service_url + '?cmd=_notify-validate', payload,
|
142
|
+
'Content-Length' => "#{payload.size}",
|
143
|
+
'User-Agent' => "Active Merchant -- http://activemerchant.org"
|
144
|
+
)
|
145
|
+
|
146
|
+
raise StandardError.new("Faulty paypal result: #{response}") unless ["VERIFIED", "INVALID"].include?(response)
|
180
147
|
|
181
|
-
|
148
|
+
response == "VERIFIED"
|
182
149
|
end
|
183
150
|
end
|
184
151
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
class PostData < Hash
|
4
|
+
class_inheritable_accessor :required_fields, :instance_writer => false
|
5
|
+
self.required_fields = []
|
6
|
+
|
7
|
+
def []=(key, value)
|
8
|
+
return if value.blank? && !required?(key)
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_post_data
|
13
|
+
collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :to_s, :to_post_data
|
17
|
+
|
18
|
+
private
|
19
|
+
def required?(key)
|
20
|
+
required_fields.include?(key)
|
21
|
+
end
|
22
|
+
end
|
@@ -1,9 +1,15 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
|
+
class ConnectionError < ActiveMerchantError
|
3
|
+
end
|
4
|
+
|
2
5
|
module PostsData #:nodoc:
|
3
6
|
|
4
7
|
def self.included(base)
|
5
8
|
base.class_inheritable_accessor :ssl_strict
|
6
9
|
base.ssl_strict = true
|
10
|
+
|
11
|
+
base.class_inheritable_accessor :pem_password
|
12
|
+
base.pem_password = false
|
7
13
|
end
|
8
14
|
|
9
15
|
def ssl_post(url, data, headers = {})
|
@@ -12,19 +18,31 @@ module ActiveMerchant #:nodoc:
|
|
12
18
|
http = Net::HTTP.new(uri.host, uri.port)
|
13
19
|
http.use_ssl = true
|
14
20
|
|
15
|
-
if
|
21
|
+
if ssl_strict
|
16
22
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
17
23
|
http.ca_file = File.dirname(__FILE__) + '/../../certs/cacert.pem'
|
18
24
|
else
|
19
25
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
20
26
|
end
|
21
27
|
|
22
|
-
|
28
|
+
if @options && !@options[:pem].blank?
|
23
29
|
http.cert = OpenSSL::X509::Certificate.new(@options[:pem])
|
24
|
-
|
30
|
+
|
31
|
+
if pem_password
|
32
|
+
raise ArgumentError, "The private key requires a password" if @options[:pem_password].blank?
|
33
|
+
http.key = OpenSSL::PKey::RSA.new(@options[:pem], @options[:pem_password])
|
34
|
+
else
|
35
|
+
http.key = OpenSSL::PKey::RSA.new(@options[:pem])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
http.post(uri.request_uri, data, headers).body
|
41
|
+
rescue EOFError => e
|
42
|
+
raise ConnectionError, "The remote server dropped the connection"
|
43
|
+
rescue Errno::ECONNREFUSED => e
|
44
|
+
raise ConnectionError, "The remote server refused the connection"
|
25
45
|
end
|
26
|
-
|
27
|
-
http.post(uri.path, data, headers).body
|
28
46
|
end
|
29
47
|
end
|
30
48
|
end
|