activemerchant 1.35.1 → 1.36.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 +11 -0
- data/CONTRIBUTORS +4 -0
- data/README.md +1 -0
- data/lib/active_merchant/billing/gateway.rb +5 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -1
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +52 -31
- data/lib/active_merchant/billing/gateways/litle.rb +19 -5
- data/lib/active_merchant/billing/gateways/mercury.rb +17 -7
- data/lib/active_merchant/billing/gateways/payment_express.rb +15 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +9 -1
- data/lib/active_merchant/billing/gateways/secure_net.rb +66 -134
- data/lib/active_merchant/billing/gateways/stripe.rb +47 -21
- data/lib/active_merchant/billing/gateways/webpay.rb +6 -2
- data/lib/active_merchant/billing/integrations/platron.rb +28 -0
- data/lib/active_merchant/billing/integrations/platron/helper.rb +32 -0
- data/lib/active_merchant/billing/integrations/platron/notification.rb +113 -0
- data/lib/active_merchant/billing/integrations/webmoney/helper.rb +1 -0
- data/lib/active_merchant/billing/integrations/webmoney/notification.rb +4 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +62 -59
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.36.0 (August 2, 2013)
|
4
|
+
|
5
|
+
* Fat Zebra: More consistent handling of tokens [adrianmacneil]
|
6
|
+
* Add Platron integration [alexwl]
|
7
|
+
* Litle: Support wiredump_device [pierre]
|
8
|
+
* Litle: support paypage registrations [pierre]
|
9
|
+
* SecureNet: Cleanup and refactoring [duff]
|
10
|
+
* Mercury: Proper refund and void support [opendining]
|
11
|
+
* PaymentExpress: Return token in authorization [ntalbott]
|
12
|
+
* Stripe: Support for partial application fee refunds [melari, odorcicd]
|
13
|
+
|
3
14
|
== Version 1.35.1 (July 22, 2013)
|
4
15
|
|
5
16
|
* Stripe: Allow application_fees to be refunded via the refund_application_fee flag [melari]
|
data/CONTRIBUTORS
CHANGED
data/README.md
CHANGED
@@ -197,6 +197,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
197
197
|
* [Paxum](https://www.paxum.com/)
|
198
198
|
* [PayPal Website Payments Standard](https://www.paypal.com/cgi-bin/webscr?cmd#_wp-standard-overview-outside)
|
199
199
|
* [Paysbuy](https://www.paysbuy.com/) - TH
|
200
|
+
* [Platron](https://www.platron.ru/) - RU
|
200
201
|
* [RBK Money](https://rbkmoney.ru/) - RU
|
201
202
|
* [Robokassa](http://robokassa.ru/) - RU
|
202
203
|
* [SagePay Form](http://www.sagepay.com/products_services/sage_pay_go/integration/form)
|
@@ -161,7 +161,11 @@ module ActiveMerchant #:nodoc:
|
|
161
161
|
|
162
162
|
def localized_amount(money, currency)
|
163
163
|
amount = amount(money)
|
164
|
-
|
164
|
+
non_fractional_currency?(currency) ? amount.split('.').first : amount
|
165
|
+
end
|
166
|
+
|
167
|
+
def non_fractional_currency?(currency)
|
168
|
+
CURRENCIES_WITHOUT_FRACTIONS.include?(currency.to_s)
|
165
169
|
end
|
166
170
|
|
167
171
|
def currency(money)
|
@@ -858,7 +858,7 @@ module ActiveMerchant #:nodoc:
|
|
858
858
|
end
|
859
859
|
|
860
860
|
def format_extra_options(options)
|
861
|
-
options.map{ |k, v| "#{k}=#{v}" }.join('
|
861
|
+
options.map{ |k, v| "#{k}=#{v}" }.join('&') unless options.nil?
|
862
862
|
end
|
863
863
|
|
864
864
|
def parse_direct_response(params)
|
@@ -13,15 +13,14 @@ module ActiveMerchant #:nodoc:
|
|
13
13
|
|
14
14
|
self.homepage_url = 'https://www.fatzebra.com.au/'
|
15
15
|
self.display_name = 'Fat Zebra'
|
16
|
-
|
16
|
+
|
17
17
|
# Setup a new instance of the gateway.
|
18
18
|
#
|
19
19
|
# The options hash should include :username and :token
|
20
20
|
# You can find your username and token at https://dashboard.fatzebra.com.au
|
21
21
|
# Under the Your Account section
|
22
22
|
def initialize(options = {})
|
23
|
-
requires!(options, :username)
|
24
|
-
requires!(options, :token)
|
23
|
+
requires!(options, :username, :token)
|
25
24
|
@username = options[:username]
|
26
25
|
@token = options[:token]
|
27
26
|
super
|
@@ -29,11 +28,11 @@ module ActiveMerchant #:nodoc:
|
|
29
28
|
|
30
29
|
# To create a purchase on a credit card use:
|
31
30
|
#
|
32
|
-
# purchase(money, creditcard
|
31
|
+
# purchase(money, creditcard)
|
33
32
|
#
|
34
33
|
# To charge a tokenized card
|
35
34
|
#
|
36
|
-
# purchase(money,
|
35
|
+
# purchase(money, "abzy87u", :cvv => "123")
|
37
36
|
def purchase(money, creditcard, options = {})
|
38
37
|
post = {}
|
39
38
|
|
@@ -61,6 +60,8 @@ module ActiveMerchant #:nodoc:
|
|
61
60
|
end
|
62
61
|
|
63
62
|
# Tokenize a credit card
|
63
|
+
#
|
64
|
+
# The token is returned in the Response#authorization
|
64
65
|
def store(creditcard)
|
65
66
|
post = {}
|
66
67
|
add_creditcard(post, creditcard)
|
@@ -69,6 +70,7 @@ module ActiveMerchant #:nodoc:
|
|
69
70
|
end
|
70
71
|
|
71
72
|
private
|
73
|
+
|
72
74
|
# Add the money details to the request
|
73
75
|
def add_amount(post, money, options)
|
74
76
|
post[:amount] = money
|
@@ -81,42 +83,61 @@ module ActiveMerchant #:nodoc:
|
|
81
83
|
post[:card_expiry] = "#{creditcard.month}/#{creditcard.year}"
|
82
84
|
post[:cvv] = creditcard.verification_value if creditcard.verification_value?
|
83
85
|
post[:card_holder] = creditcard.name if creditcard.name
|
86
|
+
elsif creditcard.is_a?(String)
|
87
|
+
post[:card_token] = creditcard
|
88
|
+
post[:cvv] = options[:cvv]
|
89
|
+
elsif creditcard.is_a?(Hash)
|
90
|
+
deprecated "Passing the credit card as a Hash is deprecated. Use a String and put the (optional) CVV in the options hash instead."
|
91
|
+
post[:card_token] = creditcard[:token]
|
92
|
+
post[:cvv] = creditcard[:cvv]
|
84
93
|
else
|
85
|
-
|
86
|
-
post[:cvv] = creditcard[:cvv]
|
94
|
+
raise ArgumentError.new("Unknown credit card format #{creditcard.inspect}")
|
87
95
|
end
|
88
96
|
end
|
89
97
|
|
90
98
|
# Post the data to the gateway
|
91
99
|
def commit(method, uri, parameters=nil)
|
92
|
-
|
93
|
-
|
94
|
-
begin
|
95
|
-
raw_response = ssl_request(method, get_url(uri), parameters.to_json, headers)
|
96
|
-
response = parse(raw_response)
|
97
|
-
success = response["successful"] && (response["response"]["successful"] || response["response"]["token"])
|
100
|
+
response = begin
|
101
|
+
parse(ssl_request(method, get_url(uri), parameters.to_json, headers))
|
98
102
|
rescue ResponseError => e
|
99
|
-
if
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
raw_response = e.response.body
|
104
|
-
response = parse(raw_response)
|
105
|
-
rescue JSON::ParserError
|
106
|
-
response = json_error(raw_response)
|
103
|
+
return Response.new(false, "Invalid Login") if(e.response.code == "401")
|
104
|
+
parse(e.response.body)
|
107
105
|
end
|
108
106
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
107
|
+
success = success_from(response)
|
108
|
+
Response.new(
|
109
|
+
success,
|
110
|
+
message_from(response),
|
111
|
+
response,
|
112
|
+
:test => response["test"],
|
113
|
+
:authorization => authorization_from(response, success)
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
def success_from(response)
|
118
|
+
(
|
119
|
+
response["successful"] &&
|
120
|
+
response["response"] &&
|
121
|
+
(response["response"]["successful"] || response["response"]["token"])
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def authorization_from(response, success)
|
126
|
+
if success
|
127
|
+
(response["response"]["id"] || response["response"]["token"])
|
128
|
+
else
|
129
|
+
nil
|
113
130
|
end
|
131
|
+
end
|
114
132
|
|
115
|
-
|
116
|
-
|
117
|
-
response,
|
118
|
-
|
119
|
-
|
133
|
+
def message_from(response)
|
134
|
+
if !response["errors"].empty?
|
135
|
+
response["errors"].join(", ")
|
136
|
+
elsif response["response"]["message"]
|
137
|
+
response["response"]["message"]
|
138
|
+
else
|
139
|
+
"Unknown Error"
|
140
|
+
end
|
120
141
|
end
|
121
142
|
|
122
143
|
# Parse the returned JSON, if parse errors are raised then return a detailed error.
|
@@ -146,7 +167,7 @@ module ActiveMerchant #:nodoc:
|
|
146
167
|
"Authorization" => "Basic " + Base64.strict_encode64(@username.to_s + ":" + @token.to_s).strip,
|
147
168
|
"User-Agent" => "Fat Zebra v1.0/ActiveMerchant #{ActiveMerchant::VERSION}"
|
148
169
|
}
|
149
|
-
end
|
170
|
+
end
|
150
171
|
end
|
151
172
|
end
|
152
173
|
end
|
@@ -57,7 +57,15 @@ module ActiveMerchant #:nodoc:
|
|
57
57
|
begin
|
58
58
|
require 'LitleOnline'
|
59
59
|
rescue LoadError
|
60
|
-
raise "Could not load the LitleOnline gem (
|
60
|
+
raise "Could not load the LitleOnline gem (> 08.15.0). Use `gem install LitleOnline` to install it."
|
61
|
+
end
|
62
|
+
|
63
|
+
if wiredump_device
|
64
|
+
LitleOnline::Configuration.logger = ((Logger === wiredump_device) ? wiredump_device : Logger.new(wiredump_device))
|
65
|
+
LitleOnline::Configuration.logger.level = Logger::DEBUG
|
66
|
+
else
|
67
|
+
LitleOnline::Configuration.logger = Logger.new(STDOUT)
|
68
|
+
LitleOnline::Configuration.logger.level = Logger::WARN
|
61
69
|
end
|
62
70
|
|
63
71
|
@litle = LitleOnline::LitleOnlineRequest.new
|
@@ -109,8 +117,8 @@ module ActiveMerchant #:nodoc:
|
|
109
117
|
build_response(:credit, @litle.credit(to_pass))
|
110
118
|
end
|
111
119
|
|
112
|
-
def store(
|
113
|
-
to_pass = create_token_hash(
|
120
|
+
def store(creditcard_or_paypage_registration_id, options = {})
|
121
|
+
to_pass = create_token_hash(creditcard_or_paypage_registration_id, options)
|
114
122
|
build_response(:registerToken, @litle.register_token_request(to_pass), %w(000 801 802))
|
115
123
|
end
|
116
124
|
|
@@ -286,9 +294,15 @@ module ActiveMerchant #:nodoc:
|
|
286
294
|
hash
|
287
295
|
end
|
288
296
|
|
289
|
-
def create_token_hash(
|
297
|
+
def create_token_hash(creditcard_or_paypage_registration_id, options)
|
290
298
|
hash = create_hash(0, options)
|
291
|
-
|
299
|
+
|
300
|
+
if creditcard_or_paypage_registration_id.is_a?(String)
|
301
|
+
hash['paypageRegistrationId'] = creditcard_or_paypage_registration_id
|
302
|
+
else
|
303
|
+
hash['accountNumber'] = creditcard_or_paypage_registration_id.number
|
304
|
+
end
|
305
|
+
|
292
306
|
hash
|
293
307
|
end
|
294
308
|
|
@@ -59,12 +59,22 @@ module ActiveMerchant #:nodoc:
|
|
59
59
|
def refund(money, authorization, options = {})
|
60
60
|
requires!(options, :credit_card) unless @use_tokenization
|
61
61
|
|
62
|
-
request = build_authorized_request('
|
63
|
-
commit(
|
62
|
+
request = build_authorized_request('Return', money, authorization, options[:credit_card], options)
|
63
|
+
commit('Return', request)
|
64
64
|
end
|
65
65
|
|
66
66
|
def void(authorization, options={})
|
67
|
-
|
67
|
+
requires!(options, :credit_card) unless @use_tokenization
|
68
|
+
|
69
|
+
if options[:try_reversal]
|
70
|
+
request = build_authorized_request('VoidSale', nil, authorization, options[:credit_card], options.merge(:reversal => true))
|
71
|
+
response = commit('VoidSale', request)
|
72
|
+
|
73
|
+
return response if response.success?
|
74
|
+
end
|
75
|
+
|
76
|
+
request = build_authorized_request('VoidSale', nil, authorization, options[:credit_card], options)
|
77
|
+
commit('VoidSale', request)
|
68
78
|
end
|
69
79
|
|
70
80
|
private
|
@@ -94,7 +104,7 @@ module ActiveMerchant #:nodoc:
|
|
94
104
|
xml = Builder::XmlMarkup.new
|
95
105
|
|
96
106
|
invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = split_authorization(authorization)
|
97
|
-
ref_no = invoice_no if options[:
|
107
|
+
ref_no = invoice_no if options[:reversal]
|
98
108
|
|
99
109
|
xml.tag! "TStream" do
|
100
110
|
xml.tag! "Transaction" do
|
@@ -111,8 +121,8 @@ module ActiveMerchant #:nodoc:
|
|
111
121
|
add_address(xml, options)
|
112
122
|
xml.tag! 'TranInfo' do
|
113
123
|
xml.tag! "AuthCode", auth_code
|
114
|
-
xml.tag! "AcqRefData", acq_ref_data
|
115
|
-
xml.tag! "ProcessData", process_data
|
124
|
+
xml.tag! "AcqRefData", acq_ref_data if options[:reversal]
|
125
|
+
xml.tag! "ProcessData", process_data if options[:reversal]
|
116
126
|
end
|
117
127
|
end
|
118
128
|
end
|
@@ -121,7 +131,7 @@ module ActiveMerchant #:nodoc:
|
|
121
131
|
|
122
132
|
def add_invoice(xml, invoice_no, ref_no, options)
|
123
133
|
if /^\d+$/ !~ invoice_no.to_s
|
124
|
-
raise ArgumentError.new("#{invoice_no} is not numeric as required by Mercury")
|
134
|
+
raise ArgumentError.new("order_id '#{invoice_no}' is not numeric as required by Mercury")
|
125
135
|
end
|
126
136
|
|
127
137
|
xml.tag! 'InvoiceNo', invoice_no
|
@@ -285,9 +285,9 @@ module ActiveMerchant #:nodoc:
|
|
285
285
|
response = parse( ssl_post(self.live_url, request.to_s) )
|
286
286
|
|
287
287
|
# Return a response
|
288
|
-
PaymentExpressResponse.new(response[:success] == APPROVED, response
|
288
|
+
PaymentExpressResponse.new(response[:success] == APPROVED, message_from(response), response,
|
289
289
|
:test => response[:test_mode] == '1',
|
290
|
-
:authorization => response
|
290
|
+
:authorization => authorization_from(action, response)
|
291
291
|
)
|
292
292
|
end
|
293
293
|
|
@@ -312,6 +312,19 @@ module ActiveMerchant #:nodoc:
|
|
312
312
|
response
|
313
313
|
end
|
314
314
|
|
315
|
+
def message_from(response)
|
316
|
+
(response[:card_holder_help_text] || response[:response_text])
|
317
|
+
end
|
318
|
+
|
319
|
+
def authorization_from(action, response)
|
320
|
+
case action
|
321
|
+
when :validate
|
322
|
+
(response[:billing_id] || response[:dps_billing_id])
|
323
|
+
else
|
324
|
+
response[:dps_txn_ref]
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
315
328
|
def format_date(month, year)
|
316
329
|
"#{format(month, :two_digits)}#{format(year, :two_digits)}"
|
317
330
|
end
|
@@ -542,7 +542,7 @@ module ActiveMerchant #:nodoc:
|
|
542
542
|
xml.tag! 'n2:Number', item[:number]
|
543
543
|
xml.tag! 'n2:Quantity', item[:quantity]
|
544
544
|
if item[:amount]
|
545
|
-
xml.tag! 'n2:Amount',
|
545
|
+
xml.tag! 'n2:Amount', item_amount(item[:amount], currency_code), 'currencyID' => currency_code
|
546
546
|
end
|
547
547
|
xml.tag! 'n2:Description', item[:description]
|
548
548
|
xml.tag! 'n2:ItemURL', item[:url]
|
@@ -657,6 +657,14 @@ module ActiveMerchant #:nodoc:
|
|
657
657
|
def date_to_iso(date)
|
658
658
|
(date.is_a?(Date) ? date.to_time : date).utc.iso8601
|
659
659
|
end
|
660
|
+
|
661
|
+
def item_amount(amount, currency_code)
|
662
|
+
if amount.to_i < 0 && non_fractional_currency?(currency_code)
|
663
|
+
amount(amount).to_f.floor
|
664
|
+
else
|
665
|
+
localized_amount(amount, currency_code)
|
666
|
+
end
|
667
|
+
end
|
660
668
|
end
|
661
669
|
end
|
662
670
|
end
|
@@ -5,53 +5,28 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
API_VERSION = "4.0"
|
6
6
|
|
7
7
|
TRANSACTIONS = {
|
8
|
-
:auth_only => "0000",
|
9
|
-
:
|
10
|
-
:auth_capture => "0100", #
|
11
|
-
:partial_auth_capture => "0101",
|
8
|
+
:auth_only => "0000",
|
9
|
+
:auth_capture => "0100",
|
12
10
|
:prior_auth_capture => "0200",
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:partial_void => "0401",
|
16
|
-
:credit => "0500", #
|
17
|
-
:credit_authonly => "0501",
|
18
|
-
:credit_priorauthcapture => "0502",
|
19
|
-
:force_credit => "0600",
|
20
|
-
:force_credit_authonly => "0601",
|
21
|
-
:force_credit_priorauthcapture => "0602",
|
22
|
-
:verification => "0700",
|
23
|
-
:auth_increment => "0800",
|
24
|
-
:issue => "0900",
|
25
|
-
:activate => "0901",
|
26
|
-
:redeem => "0902",
|
27
|
-
:redeem_partial => "0903",
|
28
|
-
:deactivate => "0904",
|
29
|
-
:reactivate => "0905",
|
30
|
-
:inquiry_balance => "0906"
|
11
|
+
:void => "0400",
|
12
|
+
:credit => "0500"
|
31
13
|
}
|
32
14
|
|
33
|
-
XML_ATTRIBUTES = {
|
34
|
-
|
15
|
+
XML_ATTRIBUTES = {
|
16
|
+
'xmlns' => "http://gateway.securenet.com/API/Contracts",
|
17
|
+
'xmlns:i' => "http://www.w3.org/2001/XMLSchema-instance"
|
35
18
|
}
|
36
19
|
NIL_ATTRIBUTE = { 'i:nil' => "true" }
|
37
20
|
|
38
|
-
# SUCCESS = "true"
|
39
|
-
# SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ]
|
40
|
-
|
41
21
|
self.supported_countries = ['US']
|
42
22
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
43
23
|
self.homepage_url = 'http://www.securenet.com/'
|
44
24
|
self.display_name = 'SecureNet'
|
45
|
-
# self.wiredump_device = STDOUT
|
46
25
|
|
47
|
-
# self.test_url = 'https://certify.securenet.com/api/Gateway.svc'
|
48
26
|
self.test_url = 'https://certify.securenet.com/API/gateway.svc/webHttp/ProcessTransaction'
|
49
27
|
self.live_url = 'https://gateway.securenet.com/api/Gateway.svc'
|
50
28
|
|
51
|
-
APPROVED, DECLINED
|
52
|
-
|
53
|
-
RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
|
54
|
-
AVS_RESULT_CODE, CARD_CODE_RESPONSE_CODE, TRANSACTION_ID = 5, 6, 8
|
29
|
+
APPROVED, DECLINED = 1, 2
|
55
30
|
|
56
31
|
CARD_CODE_ERRORS = %w( N S )
|
57
32
|
AVS_ERRORS = %w( A E N R W Z )
|
@@ -62,150 +37,87 @@ module ActiveMerchant #:nodoc:
|
|
62
37
|
end
|
63
38
|
|
64
39
|
def authorize(money, creditcard, options = {})
|
65
|
-
commit(
|
40
|
+
commit(build_sale_or_authorization(creditcard, options, :auth_only, money))
|
66
41
|
end
|
67
42
|
|
68
43
|
def purchase(money, creditcard, options = {})
|
69
|
-
commit(
|
44
|
+
commit(build_sale_or_authorization(creditcard, options, :auth_capture, money))
|
45
|
+
end
|
46
|
+
|
47
|
+
def capture(money, authorization, options = {})
|
48
|
+
commit(build_capture_refund_void(authorization, options, :prior_auth_capture, money))
|
70
49
|
end
|
71
50
|
|
72
|
-
def
|
73
|
-
commit(
|
51
|
+
def void(authorization, options = {})
|
52
|
+
commit(build_capture_refund_void(authorization, options, :void))
|
74
53
|
end
|
75
54
|
|
76
|
-
def
|
77
|
-
commit(
|
55
|
+
def refund(money, authorization, options = {})
|
56
|
+
commit(build_capture_refund_void(authorization, options, :credit, money))
|
78
57
|
end
|
79
58
|
|
80
|
-
def credit(money,
|
81
|
-
|
59
|
+
def credit(money, authorization, options = {})
|
60
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
61
|
+
refund(money, authorization, options)
|
82
62
|
end
|
83
63
|
|
64
|
+
|
84
65
|
private
|
85
|
-
def commit(request
|
86
|
-
xml = build_request(request
|
66
|
+
def commit(request)
|
67
|
+
xml = build_request(request)
|
87
68
|
data = ssl_post(self.test_url, xml, "Content-Type" => "text/xml")
|
88
69
|
response = parse(data)
|
89
70
|
|
90
71
|
test_mode = test?
|
91
72
|
Response.new(success?(response), message_from(response), response,
|
92
73
|
:test => test_mode,
|
93
|
-
:authorization => response
|
74
|
+
:authorization => build_authorization(response),
|
94
75
|
:avs_result => { :code => response[:avs_result_code] },
|
95
76
|
:cvv_result => response[:card_code_response_code]
|
96
77
|
)
|
97
78
|
end
|
98
79
|
|
99
|
-
def build_request(request
|
80
|
+
def build_request(request)
|
100
81
|
xml = Builder::XmlMarkup.new
|
101
82
|
|
102
83
|
xml.instruct!
|
103
84
|
xml.tag!("TRANSACTION", XML_ATTRIBUTES) do
|
104
|
-
xml.tag! 'AMOUNT', amount(money)
|
105
85
|
xml << request
|
106
86
|
end
|
107
87
|
|
108
88
|
xml.target!
|
109
89
|
end
|
110
90
|
|
111
|
-
def
|
91
|
+
def build_sale_or_authorization(creditcard, options, action, money)
|
112
92
|
xml = Builder::XmlMarkup.new
|
113
93
|
|
94
|
+
xml.tag! 'AMOUNT', amount(money)
|
114
95
|
add_credit_card(xml, creditcard)
|
115
|
-
xml
|
116
|
-
add_customer_data(xml, options)
|
96
|
+
add_required_params(xml, action, options)
|
117
97
|
add_address(xml, creditcard, options)
|
118
|
-
xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID
|
119
|
-
xml.tag! 'INSTALLMENT_SEQUENCENUM', 1
|
120
98
|
add_invoice(xml, options)
|
121
|
-
|
122
|
-
xml.tag! 'METHOD', 'CC'
|
123
|
-
xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id]
|
124
|
-
xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it
|
125
|
-
xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!?
|
126
|
-
xml.tag! 'TEST', 'TRUE'
|
127
|
-
xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0
|
128
|
-
xml.tag! 'TRANSACTION_SERVICE', 0
|
129
|
-
|
130
|
-
xml.target!
|
131
|
-
end
|
132
|
-
|
133
|
-
def build_capture_or_credit_request(identification, options)
|
134
|
-
xml = Builder::XmlMarkup.new
|
135
|
-
|
136
|
-
add_identification(xml, identification)
|
137
|
-
add_customer_data(xml, options)
|
99
|
+
add_more_required_params(xml, options)
|
138
100
|
|
139
101
|
xml.target!
|
140
102
|
end
|
141
103
|
|
142
|
-
def
|
104
|
+
def build_capture_refund_void(authorization, options, action, money = nil)
|
143
105
|
xml = Builder::XmlMarkup.new
|
144
106
|
|
145
|
-
|
146
|
-
xml.tag! 'CODE', TRANSACTIONS[action]
|
147
|
-
add_customer_data(xml, options)
|
148
|
-
xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID
|
149
|
-
xml.tag! 'INSTALLMENT_SEQUENCENUM', 1
|
150
|
-
add_merchant_key(xml, options)
|
151
|
-
xml.tag! 'METHOD', 'CC'
|
152
|
-
xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id]
|
153
|
-
xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it
|
154
|
-
xml.tag! 'REF_TRANSID', authorization
|
155
|
-
xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!?
|
156
|
-
xml.tag! 'TEST', 'TRUE'
|
157
|
-
xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0
|
158
|
-
xml.tag! 'TRANSACTION_SERVICE', 0
|
159
|
-
|
160
|
-
xml.target!
|
161
|
-
end
|
162
|
-
|
163
|
-
def build_credit_request(authorization, creditcard, options, action)
|
164
|
-
# requires!(options, :card_number)
|
165
|
-
xml = Builder::XmlMarkup.new
|
166
|
-
|
167
|
-
add_credit_card(xml, creditcard)
|
168
|
-
xml.tag! 'CODE', TRANSACTIONS[action]
|
169
|
-
add_customer_data(xml, options)
|
170
|
-
xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID
|
171
|
-
xml.tag! 'INSTALLMENT_SEQUENCENUM', 1
|
172
|
-
add_merchant_key(xml, options)
|
173
|
-
xml.tag! 'METHOD', 'CC'
|
174
|
-
xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id]
|
175
|
-
xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it
|
176
|
-
xml.tag! 'REF_TRANSID', authorization
|
177
|
-
xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!?
|
178
|
-
xml.tag! 'TEST', 'TRUE'
|
179
|
-
xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0
|
180
|
-
xml.tag! 'TRANSACTION_SERVICE', 0
|
181
|
-
|
182
|
-
xml.target!
|
183
|
-
end
|
107
|
+
transaction_id, amount_in_ref, last_four = split_authorization(authorization)
|
184
108
|
|
185
|
-
|
186
|
-
xml
|
109
|
+
xml.tag! 'AMOUNT', amount(money) || amount_in_ref
|
110
|
+
xml.tag!("CARD") do
|
111
|
+
xml.tag! 'CARDNUMBER', last_four
|
112
|
+
end
|
187
113
|
|
188
|
-
|
189
|
-
xml.tag! '
|
190
|
-
|
191
|
-
xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID
|
192
|
-
xml.tag! 'INSTALLMENT_SEQUENCENUM', 1
|
193
|
-
add_merchant_key(xml, options)
|
194
|
-
xml.tag! 'METHOD', 'CC'
|
195
|
-
xml.tag! 'ORDERID', options[:order_id]#'30'.to_i.to_s#'22'# @options[:order_id]
|
196
|
-
xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it
|
197
|
-
xml.tag! 'REF_TRANSID', authorization
|
198
|
-
xml.tag! 'RETAIL_LANENUM', '0' # Docs say string, but it's an integer!?
|
199
|
-
xml.tag! 'TEST', 'TRUE'
|
200
|
-
xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0
|
201
|
-
xml.tag! 'TRANSACTION_SERVICE', 0
|
114
|
+
add_required_params(xml, action, options)
|
115
|
+
xml.tag! 'REF_TRANSID', transaction_id
|
116
|
+
add_more_required_params(xml, options)
|
202
117
|
|
203
118
|
xml.target!
|
204
119
|
end
|
205
120
|
|
206
|
-
#########################################################################
|
207
|
-
# FUNCTIONS RELATED TO BUILDING THE XML
|
208
|
-
#########################################################################
|
209
121
|
def add_credit_card(xml, creditcard)
|
210
122
|
xml.tag!("CARD") do
|
211
123
|
xml.tag! 'CARDCODE', creditcard.verification_value if creditcard.verification_value?
|
@@ -241,7 +153,6 @@ module ActiveMerchant #:nodoc:
|
|
241
153
|
xml.tag! 'COUNTRY', address[:country].to_s
|
242
154
|
if options.has_key? :email
|
243
155
|
xml.tag! 'EMAIL', options[:email]
|
244
|
-
# xml.tag! 'EMAIL', 'myemail@yahoo.com'
|
245
156
|
xml.tag! 'EMAILRECEIPT', 'FALSE'
|
246
157
|
end
|
247
158
|
xml.tag! 'FIRSTNAME', creditcard.first_name
|
@@ -283,9 +194,24 @@ module ActiveMerchant #:nodoc:
|
|
283
194
|
end
|
284
195
|
end
|
285
196
|
|
286
|
-
|
287
|
-
|
288
|
-
|
197
|
+
def add_required_params(xml, action, options)
|
198
|
+
xml.tag! 'CODE', TRANSACTIONS[action]
|
199
|
+
add_customer_data(xml, options)
|
200
|
+
xml.tag! 'DCI', 0 # No duplicate checking will be done, except for ORDERID
|
201
|
+
xml.tag! 'INSTALLMENT_SEQUENCENUM', 1
|
202
|
+
add_merchant_key(xml, options)
|
203
|
+
xml.tag! 'METHOD', 'CC'
|
204
|
+
xml.tag! 'ORDERID', options[:order_id]
|
205
|
+
xml.tag! 'OVERRIDE_FROM', 0 # Docs say not required, but doesn't work without it
|
206
|
+
end
|
207
|
+
|
208
|
+
def add_more_required_params(xml, options)
|
209
|
+
xml.tag! 'RETAIL_LANENUM', '0'
|
210
|
+
xml.tag! 'TEST', 'TRUE'
|
211
|
+
xml.tag! 'TOTAL_INSTALLMENTCOUNT', 0
|
212
|
+
xml.tag! 'TRANSACTION_SERVICE', 0
|
213
|
+
end
|
214
|
+
|
289
215
|
def success?(response)
|
290
216
|
response[:response_code].to_i == APPROVED
|
291
217
|
end
|
@@ -302,9 +228,7 @@ module ActiveMerchant #:nodoc:
|
|
302
228
|
def parse(xml)
|
303
229
|
response = {}
|
304
230
|
xml = REXML::Document.new(xml)
|
305
|
-
root = REXML::XPath.first(xml, "//GATEWAYRESPONSE")
|
306
|
-
# root = REXML::XPath.first(xml, "//ProcessTransactionResponse")# ||
|
307
|
-
# REXML::XPath.first(xml, "//ErrorResponse")
|
231
|
+
root = REXML::XPath.first(xml, "//GATEWAYRESPONSE")
|
308
232
|
if root
|
309
233
|
root.elements.to_a.each do |node|
|
310
234
|
recurring_parse_element(response, node)
|
@@ -322,6 +246,14 @@ module ActiveMerchant #:nodoc:
|
|
322
246
|
end
|
323
247
|
end
|
324
248
|
|
249
|
+
def split_authorization(authorization)
|
250
|
+
transaction_id, amount, last_four = authorization.split("|")
|
251
|
+
[transaction_id, amount, last_four]
|
252
|
+
end
|
253
|
+
|
254
|
+
def build_authorization(response)
|
255
|
+
[response[:transactionid], response[:transactionamount], response[:last4_digits]].join("|")
|
256
|
+
end
|
325
257
|
|
326
258
|
end
|
327
259
|
end
|