activemerchant 1.64.0 → 1.65.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.
- checksums.yaml +4 -4
- data/CHANGELOG +27 -0
- data/README.md +0 -1
- data/lib/active_merchant/billing/gateways/adyen.rb +228 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +68 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +10 -2
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +2 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +2 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +17 -5
- data/lib/active_merchant/billing/gateways/jetpay.rb +12 -9
- data/lib/active_merchant/billing/gateways/openpay.rb +1 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +5 -3
- data/lib/active_merchant/billing/gateways/payeezy.rb +7 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +1 -1
- data/lib/active_merchant/billing/gateways/pin.rb +5 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +3 -3
- data/lib/active_merchant/billing/gateways/qvalent.rb +44 -1
- data/lib/active_merchant/billing/gateways/safe_charge.rb +211 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +8 -5
- data/lib/active_merchant/billing/gateways/stripe.rb +6 -1
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +45 -11
- data/lib/active_merchant/billing/gateways/wepay.rb +1 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +8 -3
- data/lib/active_merchant/posts_data.rb +1 -1
- data/lib/active_merchant/version.rb +1 -1
- metadata +4 -3
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
@@ -20,7 +20,8 @@ module ActiveMerchant #:nodoc:
|
|
20
20
|
:void => 'VOID',
|
21
21
|
:abort => 'ABORT',
|
22
22
|
:store => 'TOKEN',
|
23
|
-
:unstore => 'REMOVETOKEN'
|
23
|
+
:unstore => 'REMOVETOKEN',
|
24
|
+
:repeat => 'REPEAT'
|
24
25
|
}
|
25
26
|
|
26
27
|
CREDIT_CARDS = {
|
@@ -87,7 +88,7 @@ module ActiveMerchant #:nodoc:
|
|
87
88
|
add_customer_data(post, options)
|
88
89
|
add_optional_data(post, options)
|
89
90
|
|
90
|
-
commit(:purchase, post)
|
91
|
+
commit((options[:repeat] ? :repeat : :purchase), post)
|
91
92
|
end
|
92
93
|
|
93
94
|
def authorize(money, payment_method, options = {})
|
@@ -130,7 +131,7 @@ module ActiveMerchant #:nodoc:
|
|
130
131
|
|
131
132
|
post = {}
|
132
133
|
|
133
|
-
|
134
|
+
add_related_reference(post, identification)
|
134
135
|
add_amount(post, money, options)
|
135
136
|
add_invoice(post, options)
|
136
137
|
|
@@ -195,7 +196,7 @@ module ActiveMerchant #:nodoc:
|
|
195
196
|
add_pair(post, :SecurityKey, security_key)
|
196
197
|
end
|
197
198
|
|
198
|
-
def
|
199
|
+
def add_related_reference(post, identification)
|
199
200
|
order_id, transaction_id, authorization, security_key = identification.split(';')
|
200
201
|
|
201
202
|
add_pair(post, :RelatedVendorTxCode, order_id)
|
@@ -267,7 +268,9 @@ module ActiveMerchant #:nodoc:
|
|
267
268
|
end
|
268
269
|
|
269
270
|
def add_payment_method(post, payment_method, options)
|
270
|
-
if
|
271
|
+
if options[:repeat]
|
272
|
+
add_related_reference(post, payment_method)
|
273
|
+
elsif payment_method.respond_to?(:number)
|
271
274
|
add_credit_card(post, payment_method)
|
272
275
|
else
|
273
276
|
add_token_details(post, payment_method, options)
|
@@ -475,7 +475,7 @@ module ActiveMerchant #:nodoc:
|
|
475
475
|
"Authorization" => "Basic " + Base64.encode64(key.to_s + ":").strip,
|
476
476
|
"User-Agent" => "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
|
477
477
|
"Stripe-Version" => api_version(options),
|
478
|
-
"X-Stripe-Client-User-Agent" =>
|
478
|
+
"X-Stripe-Client-User-Agent" => stripe_client_user_agent(options),
|
479
479
|
"X-Stripe-Client-User-Metadata" => {:ip => options[:ip]}.to_json
|
480
480
|
}
|
481
481
|
headers.merge!("Idempotency-Key" => idempotency_key) if idempotency_key
|
@@ -483,6 +483,11 @@ module ActiveMerchant #:nodoc:
|
|
483
483
|
headers
|
484
484
|
end
|
485
485
|
|
486
|
+
def stripe_client_user_agent(options)
|
487
|
+
return user_agent unless options[:application]
|
488
|
+
JSON.dump(JSON.parse(user_agent).merge!({application: options[:application]}))
|
489
|
+
end
|
490
|
+
|
486
491
|
def api_version(options)
|
487
492
|
options[:version] || @options[:version] || "2015-04-07"
|
488
493
|
end
|
@@ -175,6 +175,10 @@ module ActiveMerchant #:nodoc:
|
|
175
175
|
|
176
176
|
verify: 9,
|
177
177
|
|
178
|
+
purchase_echeck: 11,
|
179
|
+
refund_echeck: 16,
|
180
|
+
void_echeck: 16,
|
181
|
+
|
178
182
|
wallet_sale: 14,
|
179
183
|
}
|
180
184
|
|
@@ -187,7 +191,15 @@ module ActiveMerchant #:nodoc:
|
|
187
191
|
if credit_card?(payment_method)
|
188
192
|
action = :purchase
|
189
193
|
request = build_xml_transaction_request do |doc|
|
190
|
-
|
194
|
+
add_credit_card(doc, payment_method)
|
195
|
+
add_contact(doc, payment_method.name, options)
|
196
|
+
add_amount(doc, amount)
|
197
|
+
add_order_number(doc, options)
|
198
|
+
end
|
199
|
+
elsif echeck?(payment_method)
|
200
|
+
action = :purchase_echeck
|
201
|
+
request = build_xml_transaction_request do |doc|
|
202
|
+
add_echeck(doc, payment_method)
|
191
203
|
add_contact(doc, payment_method.name, options)
|
192
204
|
add_amount(doc, amount)
|
193
205
|
add_order_number(doc, options)
|
@@ -207,7 +219,7 @@ module ActiveMerchant #:nodoc:
|
|
207
219
|
def authorize(amount, payment_method, options={})
|
208
220
|
if credit_card?(payment_method)
|
209
221
|
request = build_xml_transaction_request do |doc|
|
210
|
-
|
222
|
+
add_credit_card(doc, payment_method)
|
211
223
|
add_contact(doc, payment_method.name, options)
|
212
224
|
add_amount(doc, amount)
|
213
225
|
end
|
@@ -243,14 +255,14 @@ module ActiveMerchant #:nodoc:
|
|
243
255
|
end
|
244
256
|
|
245
257
|
def refund(amount, authorization, options={})
|
246
|
-
transaction_id = split_authorization(authorization)
|
258
|
+
action, transaction_id = split_authorization(authorization)
|
247
259
|
|
248
260
|
request = build_xml_transaction_request do |doc|
|
249
|
-
add_amount(doc, amount)
|
261
|
+
add_amount(doc, amount) unless action == 'purchase_echeck'
|
250
262
|
add_original_transaction_data(doc, transaction_id)
|
251
263
|
end
|
252
264
|
|
253
|
-
commit(
|
265
|
+
commit(refund_type(action), request)
|
254
266
|
end
|
255
267
|
|
256
268
|
def credit(amount, payment_method, options={})
|
@@ -264,7 +276,7 @@ module ActiveMerchant #:nodoc:
|
|
264
276
|
|
265
277
|
def verify(credit_card, options={})
|
266
278
|
request = build_xml_transaction_request do |doc|
|
267
|
-
|
279
|
+
add_credit_card(doc, credit_card)
|
268
280
|
add_contact(doc, credit_card.name, options)
|
269
281
|
end
|
270
282
|
|
@@ -286,7 +298,7 @@ module ActiveMerchant #:nodoc:
|
|
286
298
|
add_customer_id(doc, customer_id)
|
287
299
|
doc["v1"].pmt do
|
288
300
|
doc["v1"].type 0 # add
|
289
|
-
|
301
|
+
add_credit_card(doc, payment_method)
|
290
302
|
end
|
291
303
|
end
|
292
304
|
end
|
@@ -383,8 +395,9 @@ module ActiveMerchant #:nodoc:
|
|
383
395
|
|
384
396
|
message = RESPONSE_MESSAGES[code]
|
385
397
|
extended = EXTENDED_RESPONSE_MESSAGES[extended_code]
|
398
|
+
ach_response = response["achResponse"]
|
386
399
|
|
387
|
-
[message, extended].compact.join('. ')
|
400
|
+
[message, extended, ach_response].compact.join('. ')
|
388
401
|
else
|
389
402
|
response["faultstring"]
|
390
403
|
end
|
@@ -401,7 +414,11 @@ module ActiveMerchant #:nodoc:
|
|
401
414
|
|
402
415
|
# -- helper methods ----------------------------------------------------
|
403
416
|
def credit_card?(payment_method)
|
404
|
-
payment_method.respond_to?(:
|
417
|
+
payment_method.respond_to?(:verification_value)
|
418
|
+
end
|
419
|
+
|
420
|
+
def echeck?(payment_method)
|
421
|
+
payment_method.respond_to?(:routing_number)
|
405
422
|
end
|
406
423
|
|
407
424
|
def split_authorization(authorization)
|
@@ -409,7 +426,11 @@ module ActiveMerchant #:nodoc:
|
|
409
426
|
end
|
410
427
|
|
411
428
|
def void_type(action)
|
412
|
-
:"void_#{action}"
|
429
|
+
action == 'purchase_echeck' ? :void_echeck : :"void_#{action}"
|
430
|
+
end
|
431
|
+
|
432
|
+
def refund_type(action)
|
433
|
+
action == 'purchase_echeck' ? :refund_echeck : :refund
|
413
434
|
end
|
414
435
|
|
415
436
|
# -- request methods ---------------------------------------------------
|
@@ -482,7 +503,7 @@ module ActiveMerchant #:nodoc:
|
|
482
503
|
}
|
483
504
|
end
|
484
505
|
|
485
|
-
def
|
506
|
+
def add_credit_card(doc, payment_method)
|
486
507
|
doc["v1"].card {
|
487
508
|
doc["v1"].pan payment_method.number
|
488
509
|
doc["v1"].sec payment_method.verification_value if payment_method.verification_value?
|
@@ -490,6 +511,13 @@ module ActiveMerchant #:nodoc:
|
|
490
511
|
}
|
491
512
|
end
|
492
513
|
|
514
|
+
def add_echeck(doc, payment_method)
|
515
|
+
doc["v1"].achEcheck {
|
516
|
+
doc["v1"].bankRtNr payment_method.routing_number
|
517
|
+
doc["v1"].acctNr payment_method.account_number
|
518
|
+
}
|
519
|
+
end
|
520
|
+
|
493
521
|
def expiration_date(payment_method)
|
494
522
|
yy = format(payment_method.year, :two_digits)
|
495
523
|
mm = format(payment_method.month, :two_digits)
|
@@ -540,6 +568,12 @@ module ActiveMerchant #:nodoc:
|
|
540
568
|
end
|
541
569
|
end
|
542
570
|
|
571
|
+
def add_name(doc, payment_method)
|
572
|
+
doc["v1"].contact do
|
573
|
+
doc["v1"].fullName payment_method.name
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
543
577
|
def add_original_transaction_data(doc, authorization)
|
544
578
|
doc["v1"].origTranData do
|
545
579
|
doc["v1"].tranNr authorization
|
@@ -126,6 +126,7 @@ module ActiveMerchant #:nodoc:
|
|
126
126
|
post[:payer_email_message] = options[:payer_email_message] if options[:payer_email_message]
|
127
127
|
post[:payee_email_message] = options[:payee_email_message] if options[:payee_email_message]
|
128
128
|
post[:reference_id] = options[:order_id] if options[:order_id]
|
129
|
+
post[:unique_id] = options[:unique_id] if options[:unique_id]
|
129
130
|
post[:redirect_uri] = options[:redirect_uri] if options[:redirect_uri]
|
130
131
|
post[:callback_uri] = options[:callback_uri] if options[:callback_uri]
|
131
132
|
post[:fallback_uri] = options[:fallback_uri] if options[:fallback_uri]
|
@@ -60,10 +60,15 @@ module ActiveMerchant #:nodoc:
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def refund(money, authorization, options = {})
|
63
|
-
MultiResponse.run do |r|
|
64
|
-
r.process{inquire_request(authorization, options, "CAPTURED", "SETTLED", "SETTLED_BY_MERCHANT")}
|
65
|
-
r.process{refund_request(money, authorization, options)}
|
63
|
+
response = MultiResponse.run do |r|
|
64
|
+
r.process { inquire_request(authorization, options, "CAPTURED", "SETTLED", "SETTLED_BY_MERCHANT") }
|
65
|
+
r.process { refund_request(money, authorization, options) }
|
66
66
|
end
|
67
|
+
|
68
|
+
return response if response.success?
|
69
|
+
return response unless options[:force_full_refund_if_unsettled]
|
70
|
+
|
71
|
+
void(authorization, options ) if response.params["last_event"] == "AUTHORISED"
|
67
72
|
end
|
68
73
|
|
69
74
|
def verify(credit_card, options={})
|
@@ -41,7 +41,7 @@ module ActiveMerchant #:nodoc:
|
|
41
41
|
|
42
42
|
def raw_ssl_request(method, endpoint, data, headers = {})
|
43
43
|
logger.warn "#{self.class} using ssl_strict=false, which is insecure" if logger unless ssl_strict
|
44
|
-
logger.warn "#{self.class} posting to plaintext endpoint, which is insecure" if logger unless endpoint =~ /^https:/
|
44
|
+
logger.warn "#{self.class} posting to plaintext endpoint, which is insecure" if logger unless endpoint.to_s =~ /^https:/
|
45
45
|
|
46
46
|
connection = new_connection(endpoint)
|
47
47
|
connection.open_timeout = open_timeout
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.65.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -161,6 +161,7 @@ files:
|
|
161
161
|
- lib/active_merchant/billing/cvv_result.rb
|
162
162
|
- lib/active_merchant/billing/gateway.rb
|
163
163
|
- lib/active_merchant/billing/gateways.rb
|
164
|
+
- lib/active_merchant/billing/gateways/adyen.rb
|
164
165
|
- lib/active_merchant/billing/gateways/allied_wallet.rb
|
165
166
|
- lib/active_merchant/billing/gateways/authorize_net.rb
|
166
167
|
- lib/active_merchant/billing/gateways/authorize_net_arb.rb
|
@@ -170,7 +171,6 @@ files:
|
|
170
171
|
- lib/active_merchant/billing/gateways/bank_frick.rb
|
171
172
|
- lib/active_merchant/billing/gateways/banwire.rb
|
172
173
|
- lib/active_merchant/billing/gateways/barclaycard_smartpay.rb
|
173
|
-
- lib/active_merchant/billing/gateways/barclays_epdq.rb
|
174
174
|
- lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb
|
175
175
|
- lib/active_merchant/billing/gateways/be2bill.rb
|
176
176
|
- lib/active_merchant/billing/gateways/beanstream.rb
|
@@ -332,6 +332,7 @@ files:
|
|
332
332
|
- lib/active_merchant/billing/gateways/realex.rb
|
333
333
|
- lib/active_merchant/billing/gateways/redsys.rb
|
334
334
|
- lib/active_merchant/billing/gateways/s5.rb
|
335
|
+
- lib/active_merchant/billing/gateways/safe_charge.rb
|
335
336
|
- lib/active_merchant/billing/gateways/sage.rb
|
336
337
|
- lib/active_merchant/billing/gateways/sage_pay.rb
|
337
338
|
- lib/active_merchant/billing/gateways/sallie_mae.rb
|
@@ -1,314 +0,0 @@
|
|
1
|
-
module ActiveMerchant #:nodoc:
|
2
|
-
module Billing #:nodoc:
|
3
|
-
class BarclaysEpdqGateway < Gateway
|
4
|
-
self.test_url = 'https://secure2.mde.epdq.co.uk:11500'
|
5
|
-
self.live_url = 'https://secure2.epdq.co.uk:11500'
|
6
|
-
|
7
|
-
self.supported_countries = ['GB']
|
8
|
-
self.default_currency = 'GBP'
|
9
|
-
self.supported_cardtypes = [:visa, :master, :american_express, :maestro, :switch ]
|
10
|
-
self.money_format = :cents
|
11
|
-
self.homepage_url = 'http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/'
|
12
|
-
self.display_name = 'Barclays ePDQ MPI'
|
13
|
-
|
14
|
-
def initialize(options = {})
|
15
|
-
requires!(options, :login, :password, :client_id)
|
16
|
-
super
|
17
|
-
end
|
18
|
-
|
19
|
-
def authorize(money, creditcard, options = {})
|
20
|
-
document = Document.new(self, @options) do
|
21
|
-
add_order_form(options[:order_id]) do
|
22
|
-
add_consumer(options) do
|
23
|
-
add_creditcard(creditcard)
|
24
|
-
end
|
25
|
-
add_transaction(:PreAuth, money)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
commit(document)
|
30
|
-
end
|
31
|
-
|
32
|
-
def purchase(money, creditcard, options = {})
|
33
|
-
# disable fraud checks if this is a repeat order:
|
34
|
-
if options[:payment_number] && (options[:payment_number] > 1)
|
35
|
-
no_fraud = true
|
36
|
-
else
|
37
|
-
no_fraud = options[:no_fraud]
|
38
|
-
end
|
39
|
-
document = Document.new(self, @options, :no_fraud => no_fraud) do
|
40
|
-
add_order_form(options[:order_id], options[:group_id]) do
|
41
|
-
add_consumer(options) do
|
42
|
-
add_creditcard(creditcard)
|
43
|
-
end
|
44
|
-
add_transaction(:Auth, money, options)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
commit(document)
|
48
|
-
end
|
49
|
-
|
50
|
-
# authorization is your unique order ID, not the authorization
|
51
|
-
# code returned by ePDQ
|
52
|
-
def capture(money, authorization, options = {})
|
53
|
-
document = Document.new(self, @options) do
|
54
|
-
add_order_form(authorization) do
|
55
|
-
add_transaction(:PostAuth, money)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
commit(document)
|
60
|
-
end
|
61
|
-
|
62
|
-
# authorization is your unique order ID, not the authorization
|
63
|
-
# code returned by ePDQ
|
64
|
-
def credit(money, creditcard_or_authorization, options = {})
|
65
|
-
if creditcard_or_authorization.is_a?(String)
|
66
|
-
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
67
|
-
refund(money, creditcard_or_authorization, options)
|
68
|
-
else
|
69
|
-
credit_new_order(money, creditcard_or_authorization, options)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def refund(money, authorization, options = {})
|
74
|
-
credit_existing_order(money, authorization, options)
|
75
|
-
end
|
76
|
-
|
77
|
-
def void(authorization, options = {})
|
78
|
-
document = Document.new(self, @options) do
|
79
|
-
add_order_form(authorization) do
|
80
|
-
add_transaction(:Void)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
commit(document)
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
def credit_new_order(money, creditcard, options)
|
89
|
-
document = Document.new(self, @options) do
|
90
|
-
add_order_form do
|
91
|
-
add_consumer(options) do
|
92
|
-
add_creditcard(creditcard)
|
93
|
-
end
|
94
|
-
add_transaction(:Credit, money)
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
commit(document)
|
99
|
-
end
|
100
|
-
|
101
|
-
def credit_existing_order(money, authorization, options)
|
102
|
-
order_id, _ = authorization.split(":")
|
103
|
-
document = Document.new(self, @options) do
|
104
|
-
add_order_form(order_id) do
|
105
|
-
add_transaction(:Credit, money)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
commit(document)
|
110
|
-
end
|
111
|
-
|
112
|
-
def parse(body)
|
113
|
-
parser = Parser.new(body)
|
114
|
-
response = parser.parse
|
115
|
-
Response.new(response[:success], response[:message], response,
|
116
|
-
:test => test?,
|
117
|
-
:authorization => response[:authorization],
|
118
|
-
:avs_result => response[:avsresponse],
|
119
|
-
:cvv_result => response[:cvv_result],
|
120
|
-
:order_id => response[:order_id],
|
121
|
-
:raw_response => response[:raw_response]
|
122
|
-
)
|
123
|
-
end
|
124
|
-
|
125
|
-
def commit(document)
|
126
|
-
url = (test? ? self.test_url : self.live_url)
|
127
|
-
data = ssl_post(url, document.to_xml)
|
128
|
-
parse(data)
|
129
|
-
end
|
130
|
-
|
131
|
-
class Parser
|
132
|
-
def initialize(response)
|
133
|
-
@response = response
|
134
|
-
end
|
135
|
-
|
136
|
-
def parse
|
137
|
-
require 'iconv' unless String.method_defined?(:encode)
|
138
|
-
if String.method_defined?(:encode)
|
139
|
-
doc = REXML::Document.new(@response.encode("UTF-8", "ISO-8859-1"))
|
140
|
-
else
|
141
|
-
ic = Iconv.new('UTF-8', 'ISO-8859-1')
|
142
|
-
doc = REXML::Document.new(ic.iconv(@response))
|
143
|
-
end
|
144
|
-
|
145
|
-
auth_type = find(doc, "//Transaction/Type").to_s
|
146
|
-
|
147
|
-
message = find(doc, "//Message/Text")
|
148
|
-
if message.blank?
|
149
|
-
message = find(doc, "//Transaction/CardProcResp/CcReturnMsg")
|
150
|
-
end
|
151
|
-
|
152
|
-
case auth_type
|
153
|
-
when 'Credit', 'Void'
|
154
|
-
success = find(doc, "//CcReturnMsg") == "Approved."
|
155
|
-
else
|
156
|
-
success = find(doc, "//Transaction/AuthCode").present?
|
157
|
-
end
|
158
|
-
|
159
|
-
{
|
160
|
-
:success => success,
|
161
|
-
:message => message,
|
162
|
-
:transaction_id => find(doc, "//Transaction/Id"),
|
163
|
-
:avs_result => find(doc, "//Transaction/AvsRespCode"),
|
164
|
-
:cvv_result => find(doc, "//Transaction/Cvv2Resp"),
|
165
|
-
:authorization => find(doc, "//OrderFormDoc/Id"),
|
166
|
-
:raw_response => @response
|
167
|
-
}
|
168
|
-
end
|
169
|
-
|
170
|
-
def find(doc, xpath)
|
171
|
-
REXML::XPath.first(doc, xpath).try(:text)
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
class Document
|
176
|
-
attr_reader :type, :xml
|
177
|
-
|
178
|
-
PAYMENT_INTERVALS = {
|
179
|
-
:days => 'D',
|
180
|
-
:months => 'M'
|
181
|
-
}
|
182
|
-
|
183
|
-
EPDQ_CARD_TYPES = {
|
184
|
-
:visa => 1,
|
185
|
-
:master => 2,
|
186
|
-
:switch => 9,
|
187
|
-
:maestro => 10,
|
188
|
-
}
|
189
|
-
|
190
|
-
def initialize(gateway, options = {}, document_options = {}, &block)
|
191
|
-
@gateway = gateway
|
192
|
-
@options = options
|
193
|
-
@document_options = document_options
|
194
|
-
@xml = Builder::XmlMarkup.new(:indent => 2)
|
195
|
-
build(&block)
|
196
|
-
end
|
197
|
-
|
198
|
-
def to_xml
|
199
|
-
@xml.target!
|
200
|
-
end
|
201
|
-
|
202
|
-
def build(&block)
|
203
|
-
xml.instruct!(:xml, :version => '1.0')
|
204
|
-
xml.EngineDocList do
|
205
|
-
xml.DocVersion "1.0"
|
206
|
-
xml.EngineDoc do
|
207
|
-
xml.ContentType "OrderFormDoc"
|
208
|
-
xml.User do
|
209
|
-
xml.Name(@options[:login])
|
210
|
-
xml.Password(@options[:password])
|
211
|
-
xml.ClientId({ :DataType => "S32" }, @options[:client_id])
|
212
|
-
end
|
213
|
-
xml.Instructions do
|
214
|
-
if @document_options[:no_fraud]
|
215
|
-
xml.Pipeline "PaymentNoFraud"
|
216
|
-
else
|
217
|
-
xml.Pipeline "Payment"
|
218
|
-
end
|
219
|
-
end
|
220
|
-
instance_eval(&block)
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
def add_order_form(order_id=nil, group_id=nil, &block)
|
226
|
-
xml.OrderFormDoc do
|
227
|
-
xml.Mode 'P'
|
228
|
-
xml.Id(order_id) if order_id
|
229
|
-
xml.GroupId(group_id) if group_id
|
230
|
-
instance_eval(&block)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
def add_consumer(options=nil, &block)
|
235
|
-
xml.Consumer do
|
236
|
-
if options
|
237
|
-
xml.Email(options[:email]) if options[:email]
|
238
|
-
billing_address = options[:billing_address] || options[:address]
|
239
|
-
if billing_address
|
240
|
-
xml.BillTo do
|
241
|
-
xml.Location do
|
242
|
-
xml.Address do
|
243
|
-
xml.Street1 billing_address[:address1]
|
244
|
-
xml.Street2 billing_address[:address2]
|
245
|
-
xml.City billing_address[:city]
|
246
|
-
xml.StateProv billing_address[:state]
|
247
|
-
xml.PostalCode billing_address[:zip]
|
248
|
-
xml.Country billing_address[:country_code]
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
instance_eval(&block)
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
def add_creditcard(creditcard)
|
259
|
-
xml.PaymentMech do
|
260
|
-
xml.CreditCard do
|
261
|
-
xml.Type({ :DataType => 'S32' }, EPDQ_CARD_TYPES[creditcard.brand.to_sym])
|
262
|
-
xml.Number creditcard.number
|
263
|
-
xml.Expires({ :DataType => 'ExpirationDate', :Locale => 826 }, format_expiry_date(creditcard))
|
264
|
-
if creditcard.verification_value.present?
|
265
|
-
xml.Cvv2Indicator 1
|
266
|
-
xml.Cvv2Val creditcard.verification_value
|
267
|
-
else
|
268
|
-
xml.Cvv2Indicator 5
|
269
|
-
end
|
270
|
-
xml.IssueNum(creditcard.issue_number) if creditcard.issue_number.present?
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
def add_transaction(auth_type, amount = nil, options = {})
|
276
|
-
@auth_type = auth_type
|
277
|
-
xml.Transaction do
|
278
|
-
xml.Type @auth_type.to_s
|
279
|
-
if options[:payment_number] && options[:payment_number] > 1
|
280
|
-
xml.CardholderPresentCode({ :DataType => 'S32' }, 8)
|
281
|
-
else
|
282
|
-
xml.CardholderPresentCode({ :DataType => 'S32' }, 7)
|
283
|
-
end
|
284
|
-
if options[:payment_number]
|
285
|
-
xml.PaymentNumber({ :DataType => 'S32' }, options[:payment_number])
|
286
|
-
end
|
287
|
-
if options[:total_payments]
|
288
|
-
xml.TotalNumberPayments({ :DataType => 'S32' }, options[:total_payments])
|
289
|
-
end
|
290
|
-
if amount
|
291
|
-
xml.CurrentTotals do
|
292
|
-
xml.Totals do
|
293
|
-
xml.Total({ :DataType => 'Money', :Currency => 826 }, amount)
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
# date must be formatted MM/YY
|
301
|
-
def format_expiry_date(creditcard)
|
302
|
-
month_str = "%02d" % creditcard.month
|
303
|
-
if match = creditcard.year.to_s.match(/^\d{2}(\d{2})$/)
|
304
|
-
year_str = "%02d" % match[1].to_i
|
305
|
-
else
|
306
|
-
year_str = "%02d" % creditcard.year
|
307
|
-
end
|
308
|
-
"#{month_str}/#{year_str}"
|
309
|
-
end
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
314
|
-
|