activemerchant 1.35.1 → 1.36.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 +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
|