activemerchant 1.3.2 → 1.4.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 +58 -0
- data/CONTRIBUTERS +25 -0
- data/MIT-LICENSE +3 -3
- data/README +16 -10
- data/Rakefile +4 -3
- data/lib/active_merchant.rb +7 -1
- data/lib/active_merchant/billing/check.rb +16 -9
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +702 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +233 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +10 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +26 -2
- data/lib/active_merchant/billing/gateways/data_cash.rb +255 -59
- data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +214 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +1 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +2 -2
- data/lib/active_merchant/billing/gateways/payflow_express.rb +3 -11
- data/lib/active_merchant/billing/gateways/payment_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +39 -21
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +3 -12
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
- data/lib/active_merchant/billing/gateways/protx.rb +25 -25
- data/lib/active_merchant/billing/gateways/sage.rb +145 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +110 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +3 -1
- data/lib/active_merchant/billing/gateways/skip_jack.rb +2 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +1 -1
- data/lib/active_merchant/billing/gateways/wirecard.rb +304 -0
- data/lib/active_merchant/billing/integrations.rb +8 -2
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +18 -4
- data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +4 -2
- data/lib/active_merchant/billing/integrations/notification.rb +10 -1
- data/lib/active_merchant/lib/posts_data.rb +12 -3
- data/script/destroy +0 -0
- data/script/generate +0 -0
- data/test/extra/binding_of_caller.rb +0 -0
- data/test/extra/breakpoint.rb +0 -0
- data/test/fixtures.yml +24 -0
- data/test/remote/gateways/remote_authorize_net_cim_test.rb +459 -0
- data/test/remote/gateways/remote_beanstream_interac_test.rb +53 -0
- data/test/remote/gateways/remote_beanstream_test.rb +150 -0
- data/test/remote/gateways/remote_braintree_test.rb +22 -0
- data/test/remote/gateways/remote_cyber_source_test.rb +28 -3
- data/test/remote/gateways/remote_data_cash_test.rb +250 -48
- data/test/remote/gateways/remote_modern_payments_cim_test.rb +58 -0
- data/test/remote/gateways/remote_modern_payments_test.rb +43 -0
- data/test/remote/gateways/remote_sage_bankcard_test.rb +109 -0
- data/test/remote/gateways/remote_sage_test.rb +87 -0
- data/test/remote/gateways/remote_sage_virtual_check_test.rb +62 -0
- data/test/remote/gateways/remote_wirecard_test.rb +76 -0
- data/test/remote/integrations/remote_paypal_integration_test.rb +15 -3
- data/test/test_helper.rb +31 -13
- data/test/unit/check_test.rb +14 -2
- data/test/unit/credit_card_methods_test.rb +18 -0
- data/test/unit/gateways/authorize_net_cim_test.rb +641 -0
- data/test/unit/gateways/beanstream_interac_test.rb +51 -0
- data/test/unit/gateways/beanstream_test.rb +108 -0
- data/test/unit/gateways/braintree_test.rb +2 -5
- data/test/unit/gateways/cyber_source_test.rb +18 -0
- data/test/unit/gateways/data_cash_test.rb +32 -4
- data/test/unit/gateways/gateway_test.rb +8 -1
- data/test/unit/gateways/modern_payments_cim_test.rb +171 -0
- data/test/unit/gateways/net_registry_test.rb +6 -0
- data/test/unit/gateways/payflow_express_test.rb +18 -2
- data/test/unit/gateways/paypal_express_test.rb +154 -0
- data/test/unit/gateways/paypal_test.rb +140 -0
- data/test/unit/gateways/sage_bankcard_test.rb +162 -0
- data/test/unit/gateways/sage_virtual_check_test.rb +71 -0
- data/test/unit/gateways/secure_pay_au_test.rb +58 -1
- data/test/unit/gateways/skip_jack_test.rb +8 -0
- data/test/unit/gateways/verifi_test.rb +0 -1
- data/test/unit/gateways/wirecard_test.rb +232 -0
- data/test/unit/integrations/action_view_helper_test.rb +3 -0
- data/test/unit/integrations/notifications/hi_trust_notification_test.rb +23 -2
- data/test/unit/integrations/notifications/notification_test.rb +13 -0
- data/test/unit/posts_data_test.rb +20 -6
- metadata +40 -5
- metadata.gz.sig +0 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/modern_payments_cim'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class ModernPaymentsGateway < Gateway
|
6
|
+
self.supported_countries = ModernPaymentsCimGateway.supported_countries
|
7
|
+
self.supported_cardtypes = ModernPaymentsCimGateway.supported_cardtypes
|
8
|
+
self.homepage_url = ModernPaymentsCimGateway.homepage_url
|
9
|
+
self.display_name = ModernPaymentsCimGateway.display_name
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
requires!(options, :login, :password)
|
13
|
+
@options = options
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def purchase(money, credit_card, options = {})
|
18
|
+
customer_response = cim.create_customer(options)
|
19
|
+
return customer_response unless customer_response.success?
|
20
|
+
|
21
|
+
customer_id = customer_response.params["create_customer_result"]
|
22
|
+
|
23
|
+
card_response = cim.modify_customer_credit_card(customer_id, credit_card)
|
24
|
+
return card_response unless card_response.success?
|
25
|
+
|
26
|
+
cim.authorize_credit_card_payment(customer_id, money)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def cim
|
31
|
+
@cim ||= ModernPaymentsCimGateway.new(@options)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,214 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class ModernPaymentsCimGateway < Gateway #:nodoc:
|
4
|
+
TEST_URL = "https://secure.modpay.com/netservices/test/ModpayTest.asmx"
|
5
|
+
LIVE_URL = 'https://secure.modpay.com/ws/modpay.asmx'
|
6
|
+
|
7
|
+
LIVE_XMLNS = "http://secure.modpay.com:81/ws/"
|
8
|
+
TEST_XMLNS = "https://secure.modpay.com/netservices/test/"
|
9
|
+
|
10
|
+
self.supported_countries = ['US']
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
12
|
+
self.homepage_url = 'http://www.modpay.com'
|
13
|
+
self.display_name = 'Modern Payments'
|
14
|
+
|
15
|
+
SUCCESS_MESSAGE = "Transaction accepted"
|
16
|
+
FAILURE_MESSAGE = "Transaction failed"
|
17
|
+
ERROR_MESSAGE = "Transaction error"
|
18
|
+
|
19
|
+
PAYMENT_METHOD = {
|
20
|
+
:check => 1,
|
21
|
+
:credit_card => 2
|
22
|
+
}
|
23
|
+
|
24
|
+
def initialize(options = {})
|
25
|
+
requires!(options, :login, :password)
|
26
|
+
@options = options
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_customer(options = {})
|
31
|
+
post = {}
|
32
|
+
add_customer_data(post, options)
|
33
|
+
add_address(post, options)
|
34
|
+
|
35
|
+
commit('CreateCustomer', post)
|
36
|
+
end
|
37
|
+
|
38
|
+
def modify_customer_credit_card(customer_id, credit_card)
|
39
|
+
raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
|
40
|
+
|
41
|
+
post = {}
|
42
|
+
add_customer_id(post, customer_id)
|
43
|
+
add_credit_card(post, credit_card)
|
44
|
+
|
45
|
+
commit('ModifyCustomerCreditCard', post)
|
46
|
+
end
|
47
|
+
|
48
|
+
def authorize_credit_card_payment(customer_id, amount)
|
49
|
+
raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
|
50
|
+
|
51
|
+
post = {}
|
52
|
+
add_customer_id(post, customer_id)
|
53
|
+
add_amount(post, amount)
|
54
|
+
|
55
|
+
commit('AuthorizeCreditCardPayment', post)
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_payment(customer_id, amount, options = {})
|
59
|
+
raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
|
60
|
+
|
61
|
+
post = {}
|
62
|
+
add_customer_id(post, customer_id)
|
63
|
+
add_amount(post, amount)
|
64
|
+
add_payment_details(post, options)
|
65
|
+
|
66
|
+
commit('CreatePayment', post)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def add_payment_details(post, options)
|
71
|
+
post[:pmtDate] = (options[:payment_date] || Time.now.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
72
|
+
post[:pmtType] = PAYMENT_METHOD[options[:payment_method] || :credit_card]
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_amount(post, money)
|
76
|
+
post[:pmtAmount] = amount(money)
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_customer_id(post, customer_id)
|
80
|
+
post[:custId] = customer_id
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_customer_data(post, options)
|
84
|
+
post[:acctNum] = options[:customer]
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_address(post, options)
|
88
|
+
address = options[:billing_address] || options[:address] || {}
|
89
|
+
|
90
|
+
if name = address[:name]
|
91
|
+
segments = name.split(' ')
|
92
|
+
post[:lastName] = segments.pop
|
93
|
+
post[:firstName] = segments.join(' ')
|
94
|
+
else
|
95
|
+
post[:firstName] = address[:first_name]
|
96
|
+
post[:lastName] = address[:last_name]
|
97
|
+
end
|
98
|
+
|
99
|
+
post[:address] = address[:address1]
|
100
|
+
post[:city] = address[:city]
|
101
|
+
post[:state] = address[:state]
|
102
|
+
post[:zip] = address[:zip]
|
103
|
+
post[:phone] = address[:phone]
|
104
|
+
post[:fax] = address[:fax]
|
105
|
+
post[:email] = address[:email]
|
106
|
+
end
|
107
|
+
|
108
|
+
def add_credit_card(post, credit_card)
|
109
|
+
post[:ccName] = credit_card.name
|
110
|
+
post[:ccNum] = credit_card.number
|
111
|
+
post[:expMonth] = credit_card.month
|
112
|
+
post[:expYear] = credit_card.year
|
113
|
+
end
|
114
|
+
|
115
|
+
def build_request(action, params)
|
116
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
117
|
+
xml.instruct!
|
118
|
+
xml.tag! 'env:Envelope',
|
119
|
+
{ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
120
|
+
'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
121
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' } do
|
122
|
+
|
123
|
+
xml.tag! 'env:Body' do
|
124
|
+
xml.tag! action, { "xmlns" => xmlns(action) } do
|
125
|
+
xml.tag! "clientId", @options[:login]
|
126
|
+
xml.tag! "clientCode", @options[:password]
|
127
|
+
params.each {|key, value| xml.tag! key, value }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
xml.target!
|
132
|
+
end
|
133
|
+
|
134
|
+
def xmlns(action)
|
135
|
+
if test? && action == 'AuthorizeCreditCardPayment'
|
136
|
+
TEST_XMLNS
|
137
|
+
else
|
138
|
+
LIVE_XMLNS
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def url(action)
|
143
|
+
if test? && action == 'AuthorizeCreditCardPayment'
|
144
|
+
TEST_URL
|
145
|
+
else
|
146
|
+
LIVE_URL
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def commit(action, params)
|
151
|
+
data = ssl_post(url(action), build_request(action, params),
|
152
|
+
{ 'Content-Type' =>'text/xml; charset=utf-8',
|
153
|
+
'SOAPAction' => "#{xmlns(action)}#{action}" }
|
154
|
+
)
|
155
|
+
|
156
|
+
response = parse(action, data)
|
157
|
+
Response.new(successful?(action, response), message_from(action, response), response,
|
158
|
+
:test => test?,
|
159
|
+
:authorization => authorization_from(action, response),
|
160
|
+
:avs_result => { :code => response[:avs_code] }
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
164
|
+
def authorization_from(action, response)
|
165
|
+
response[result_key(action)]
|
166
|
+
end
|
167
|
+
|
168
|
+
def result_key(action)
|
169
|
+
action == "AuthorizeCreditCardPayment" ? :trans_id : "#{action.underscore}_result".to_sym
|
170
|
+
end
|
171
|
+
|
172
|
+
def successful?(action, response)
|
173
|
+
response[result_key(action)].to_i > 0
|
174
|
+
end
|
175
|
+
|
176
|
+
def message_from(action, response)
|
177
|
+
if response[:faultcode]
|
178
|
+
ERROR_MESSAGE
|
179
|
+
elsif successful?(action, response)
|
180
|
+
SUCCESS_MESSAGE
|
181
|
+
else
|
182
|
+
FAILURE_MESSAGE
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def parse(action, xml)
|
187
|
+
response = {}
|
188
|
+
response[:action] = action
|
189
|
+
|
190
|
+
xml = REXML::Document.new(xml)
|
191
|
+
if root = REXML::XPath.first(xml, "//#{action}Response")
|
192
|
+
root.elements.to_a.each do |node|
|
193
|
+
parse_element(response, node)
|
194
|
+
end
|
195
|
+
elsif root = REXML::XPath.first(xml, "//soap:Fault")
|
196
|
+
root.elements.to_a.each do |node|
|
197
|
+
response[node.name.underscore.to_sym] = node.text
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
response
|
202
|
+
end
|
203
|
+
|
204
|
+
def parse_element(response, node)
|
205
|
+
if node.has_elements?
|
206
|
+
node.elements.each{|e| parse_element(response, e) }
|
207
|
+
else
|
208
|
+
response[node.name.underscore.to_sym] = node.text
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
@@ -72,6 +72,7 @@ module ActiveMerchant
|
|
72
72
|
# described in "Programming for NetRegistry's E-commerce
|
73
73
|
# Gateway." [http://rubyurl.com/hNG]
|
74
74
|
def capture(money, authorization, options = {})
|
75
|
+
requires!(options, :credit_card)
|
75
76
|
credit_card = options[:credit_card]
|
76
77
|
|
77
78
|
params = {
|
@@ -28,8 +28,8 @@ module ActiveMerchant #:nodoc:
|
|
28
28
|
end
|
29
29
|
|
30
30
|
XMLNS = 'http://www.paypal.com/XMLPay'
|
31
|
-
TEST_URL = 'https://pilot-payflowpro.
|
32
|
-
LIVE_URL = 'https://payflowpro.
|
31
|
+
TEST_URL = 'https://pilot-payflowpro.paypal.com'
|
32
|
+
LIVE_URL = 'https://payflowpro.paypal.com'
|
33
33
|
|
34
34
|
CARD_MAPPING = {
|
35
35
|
:visa => 'Visa',
|
@@ -1,25 +1,17 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/payflow/payflow_common_api'
|
2
2
|
require File.dirname(__FILE__) + '/payflow/payflow_express_response'
|
3
|
+
require File.dirname(__FILE__) + '/paypal_express_common'
|
3
4
|
|
4
5
|
module ActiveMerchant #:nodoc:
|
5
6
|
module Billing #:nodoc:
|
6
7
|
class PayflowExpressGateway < Gateway
|
7
8
|
include PayflowCommonAPI
|
9
|
+
include PaypalExpressCommon
|
8
10
|
|
9
|
-
|
10
|
-
TEST_REDIRECT_URL = 'https://test-expresscheckout.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='
|
11
|
-
|
11
|
+
self.test_redirect_url = 'https://test-expresscheckout.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='
|
12
12
|
self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
|
13
13
|
self.display_name = 'PayPal Express Checkout'
|
14
14
|
|
15
|
-
def redirect_url
|
16
|
-
test? ? TEST_REDIRECT_URL : LIVE_REDIRECT_URL
|
17
|
-
end
|
18
|
-
|
19
|
-
def redirect_url_for(token)
|
20
|
-
"#{redirect_url}#{token}"
|
21
|
-
end
|
22
|
-
|
23
15
|
def authorize(money, options = {})
|
24
16
|
requires!(options, :token, :payer_id)
|
25
17
|
request = build_sale_or_authorization_request('Authorization', money, options)
|
@@ -21,7 +21,7 @@ module ActiveMerchant #:nodoc:
|
|
21
21
|
self.homepage_url = 'http://www.paymentexpress.com/'
|
22
22
|
self.display_name = 'PaymentExpress'
|
23
23
|
|
24
|
-
|
24
|
+
URL = 'https://www.paymentexpress.com/pxpost.aspx'
|
25
25
|
|
26
26
|
APPROVED = '1'
|
27
27
|
|
@@ -196,7 +196,7 @@ module ActiveMerchant #:nodoc:
|
|
196
196
|
add_transaction_type(request, action)
|
197
197
|
|
198
198
|
# Parse the XML response
|
199
|
-
response = parse( ssl_post(
|
199
|
+
response = parse( ssl_post(URL, request.to_s) )
|
200
200
|
|
201
201
|
# Return a response
|
202
202
|
PaymentExpressResponse.new(response[:success] == APPROVED, response[:response_text], response,
|
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
base.cattr_accessor :signature
|
9
9
|
end
|
10
10
|
|
11
|
-
API_VERSION = '
|
11
|
+
API_VERSION = '52.0'
|
12
12
|
|
13
13
|
URLS = {
|
14
14
|
:test => { :certificate => 'https://api.sandbox.paypal.com/2.0/',
|
@@ -42,6 +42,8 @@ module ActiveMerchant #:nodoc:
|
|
42
42
|
|
43
43
|
SUCCESS_CODES = [ 'Success', 'SuccessWithWarning' ]
|
44
44
|
|
45
|
+
FRAUD_REVIEW_CODE = "11610"
|
46
|
+
|
45
47
|
# The gateway must be configured with either your PayPal PEM file
|
46
48
|
# or your PayPal API Signature. Only one is required.
|
47
49
|
#
|
@@ -109,7 +111,7 @@ module ActiveMerchant #:nodoc:
|
|
109
111
|
|
110
112
|
private
|
111
113
|
def build_reauthorize_request(money, authorization, options)
|
112
|
-
xml = Builder::XmlMarkup.new
|
114
|
+
xml = Builder::XmlMarkup.new
|
113
115
|
|
114
116
|
xml.tag! 'DoReauthorizationReq', 'xmlns' => PAYPAL_NAMESPACE do
|
115
117
|
xml.tag! 'DoReauthorizationRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
@@ -123,7 +125,7 @@ module ActiveMerchant #:nodoc:
|
|
123
125
|
end
|
124
126
|
|
125
127
|
def build_capture_request(money, authorization, options)
|
126
|
-
xml = Builder::XmlMarkup.new
|
128
|
+
xml = Builder::XmlMarkup.new
|
127
129
|
|
128
130
|
xml.tag! 'DoCaptureReq', 'xmlns' => PAYPAL_NAMESPACE do
|
129
131
|
xml.tag! 'DoCaptureRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
@@ -139,7 +141,7 @@ module ActiveMerchant #:nodoc:
|
|
139
141
|
end
|
140
142
|
|
141
143
|
def build_credit_request(money, identification, options)
|
142
|
-
xml = Builder::XmlMarkup.new
|
144
|
+
xml = Builder::XmlMarkup.new
|
143
145
|
|
144
146
|
xml.tag! 'RefundTransactionReq', 'xmlns' => PAYPAL_NAMESPACE do
|
145
147
|
xml.tag! 'RefundTransactionRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
@@ -155,7 +157,7 @@ module ActiveMerchant #:nodoc:
|
|
155
157
|
end
|
156
158
|
|
157
159
|
def build_void_request(authorization, options)
|
158
|
-
xml = Builder::XmlMarkup.new
|
160
|
+
xml = Builder::XmlMarkup.new
|
159
161
|
|
160
162
|
xml.tag! 'DoVoidReq', 'xmlns' => PAYPAL_NAMESPACE do
|
161
163
|
xml.tag! 'DoVoidRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
@@ -172,7 +174,7 @@ module ActiveMerchant #:nodoc:
|
|
172
174
|
default_options = args.last.is_a?(Hash) ? args.pop : {}
|
173
175
|
recipients = args.first.is_a?(Array) ? args : [args]
|
174
176
|
|
175
|
-
xml = Builder::XmlMarkup.new
|
177
|
+
xml = Builder::XmlMarkup.new
|
176
178
|
|
177
179
|
xml.tag! 'MassPayReq', 'xmlns' => PAYPAL_NAMESPACE do
|
178
180
|
xml.tag! 'MassPayRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
@@ -192,19 +194,41 @@ module ActiveMerchant #:nodoc:
|
|
192
194
|
|
193
195
|
xml.target!
|
194
196
|
end
|
195
|
-
|
197
|
+
|
196
198
|
def parse(action, xml)
|
197
199
|
response = {}
|
200
|
+
|
201
|
+
error_messages = []
|
202
|
+
error_codes = []
|
203
|
+
|
198
204
|
xml = REXML::Document.new(xml)
|
199
205
|
if root = REXML::XPath.first(xml, "//#{action}Response")
|
200
|
-
root.elements.
|
206
|
+
root.elements.each do |node|
|
201
207
|
case node.name
|
202
208
|
when 'Errors'
|
203
|
-
|
209
|
+
short_message = nil
|
210
|
+
long_message = nil
|
211
|
+
|
212
|
+
node.elements.each do |child|
|
213
|
+
case child.name
|
214
|
+
when "LongMessage"
|
215
|
+
long_message = child.text unless child.text.blank?
|
216
|
+
when "ShortMessage"
|
217
|
+
short_message = child.text unless child.text.blank?
|
218
|
+
when "ErrorCode"
|
219
|
+
error_codes << child.text unless child.text.blank?
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
if message = long_message || short_message
|
224
|
+
error_messages << message
|
225
|
+
end
|
204
226
|
else
|
205
227
|
parse_element(response, node)
|
206
228
|
end
|
207
229
|
end
|
230
|
+
response[:message] = error_messages.uniq.join(". ") unless error_messages.empty?
|
231
|
+
response[:error_codes] = error_codes.uniq.join(",") unless error_codes.empty?
|
208
232
|
elsif root = REXML::XPath.first(xml, "//SOAP-ENV:Fault")
|
209
233
|
parse_element(response, root)
|
210
234
|
response[:message] = "#{response[:faultcode]}: #{response[:faultstring]} - #{response[:detail]}"
|
@@ -224,19 +248,8 @@ module ActiveMerchant #:nodoc:
|
|
224
248
|
end
|
225
249
|
end
|
226
250
|
|
227
|
-
def response_type_for(action)
|
228
|
-
case action
|
229
|
-
when 'Authorization', 'Purchase'
|
230
|
-
'DoDirectPaymentResponse'
|
231
|
-
when 'Void'
|
232
|
-
'DoVoidResponse'
|
233
|
-
when 'Capture'
|
234
|
-
'DoCaptureResponse'
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
251
|
def build_request(body)
|
239
|
-
xml = Builder::XmlMarkup.new
|
252
|
+
xml = Builder::XmlMarkup.new
|
240
253
|
|
241
254
|
xml.instruct!
|
242
255
|
xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
|
@@ -286,11 +299,16 @@ module ActiveMerchant #:nodoc:
|
|
286
299
|
build_response(successful?(response), message_from(response), response,
|
287
300
|
:test => test?,
|
288
301
|
:authorization => authorization_from(response),
|
302
|
+
:fraud_review => fraud_review?(response),
|
289
303
|
:avs_result => { :code => response[:avs_code] },
|
290
304
|
:cvv_result => response[:cvv2_code]
|
291
305
|
)
|
292
306
|
end
|
293
307
|
|
308
|
+
def fraud_review?(response)
|
309
|
+
response[:error_codes] == FRAUD_REVIEW_CODE
|
310
|
+
end
|
311
|
+
|
294
312
|
def authorization_from(response)
|
295
313
|
response[:transaction_id] || response[:authorization_id] # latter one is from reauthorization
|
296
314
|
end
|