activemerchant 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|