activemerchant 1.34.1 → 1.35.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 +16 -0
- data/CONTRIBUTORS +8 -0
- data/README.md +4 -5
- data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +1 -1
- data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +28 -3
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +22 -2
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +0 -1
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +275 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +44 -14
- data/lib/active_merchant/billing/gateways/nab_transact.rb +8 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +7 -10
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +10 -2
- data/lib/active_merchant/billing/gateways/skip_jack.rb +2 -2
- data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +30 -29
- data/lib/active_merchant/billing/integrations/first_data/helper.rb +0 -2
- data/lib/active_merchant/billing/integrations/hi_trust.rb +2 -2
- data/lib/active_merchant/billing/integrations/pxpay/helper.rb +3 -2
- data/lib/active_merchant/billing/integrations/verkkomaksut/helper.rb +13 -12
- data/lib/active_merchant/version.rb +1 -1
- metadata +4 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.35.0 (July 17, 2013)
|
4
|
+
|
5
|
+
* Add Barclays ePDQ Extra Plus gateway [ntalbott]
|
6
|
+
* PayPal: Add MassPay payment to recipients by UserID [damonmorgan]
|
7
|
+
* Authorize.Net: Add authorization_code to response params [noahlh]
|
8
|
+
* Make Rails 4 a supported version [sanemat]
|
9
|
+
* CyberSource: Add pinless debit card support [JoshMcKin]
|
10
|
+
* Verkkomaksut: Add item title field [kaapa]
|
11
|
+
* Add MerchantWare V4 gateway [hron]
|
12
|
+
* Eway Rapid: Add #store method [adrianmacneil]
|
13
|
+
* Barclays ePDQ Extra Plus: Use correct PROD url [ntalbott]
|
14
|
+
* Hitrust: update test & live urls [melari]
|
15
|
+
* NAB Transact: Add auth & capture support [nagash]
|
16
|
+
* Mercury: Support card-less capture and refund [ntalbott]
|
17
|
+
* Mercury: Support void [ntalbott]
|
18
|
+
|
3
19
|
== Version 1.34.1 (June 28, 2013)
|
4
20
|
|
5
21
|
* WorldPay: Add dynamic return URL [jordanwheeler]
|
data/CONTRIBUTORS
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# Active Merchant
|
2
|
+
[](http://travis-ci.org/Shopify/active_merchant)
|
3
|
+
[](https://codeclimate.com/github/Shopify/active_merchant)
|
2
4
|
|
3
5
|
Active Merchant is an extraction from the e-commerce system [Shopify](http://www.shopify.com).
|
4
6
|
Shopify's requirements for a simple and unified API to access dozens of different payment
|
@@ -83,7 +85,8 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
|
|
83
85
|
* [Authorize.Net CIM](http://www.authorize.net/) - US
|
84
86
|
* [Balanced](https://www.balancedpayments.com/) - US
|
85
87
|
* [Banwire](https://www.banwire.com/) - MX
|
86
|
-
* [Barclays ePDQ](http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/) - UK
|
88
|
+
* [Barclays ePDQ MPI](http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/) - UK
|
89
|
+
* [Barclays ePDQ Extra Plus](http://www.barclaycard.co.uk/business/accepting-payments/epdq-ecomm/) - UK
|
87
90
|
* [Beanstream.com](http://www.beanstream.com/) - CA
|
88
91
|
* [BluePay](http://www.bluepay.com/) - US
|
89
92
|
* [Braintree](http://www.braintreepaymentsolutions.com) - US
|
@@ -215,7 +218,3 @@ information on adding a new gateway to ActiveMerchant.
|
|
215
218
|
|
216
219
|
Please don't touch the CHANGELOG in your pull requests, we'll add the appropriate CHANGELOG entries
|
217
220
|
at release time.
|
218
|
-
|
219
|
-
[](http://travis-ci.org/Shopify/active_merchant)
|
220
|
-
|
221
|
-
[](https://codeclimate.com/github/Shopify/active_merchant)
|
@@ -38,7 +38,7 @@ module ActiveMerchant #:nodoc:
|
|
38
38
|
|
39
39
|
APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
|
40
40
|
|
41
|
-
RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
|
41
|
+
RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT, AUTHORIZATION_CODE = 0, 2, 3, 4
|
42
42
|
AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38
|
43
43
|
|
44
44
|
self.default_currency = 'USD'
|
@@ -310,7 +310,8 @@ module ActiveMerchant #:nodoc:
|
|
310
310
|
:response_reason_text => fields[RESPONSE_REASON_TEXT],
|
311
311
|
:avs_result_code => fields[AVS_RESULT_CODE],
|
312
312
|
:transaction_id => fields[TRANSACTION_ID],
|
313
|
-
:card_code => fields[CARD_CODE_RESPONSE_CODE]
|
313
|
+
:card_code => fields[CARD_CODE_RESPONSE_CODE],
|
314
|
+
:authorization_code => fields[AUTHORIZATION_CODE]
|
314
315
|
}
|
315
316
|
results
|
316
317
|
end
|
@@ -9,7 +9,7 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
self.supported_cardtypes = [:visa, :master, :american_express, :maestro, :switch ]
|
10
10
|
self.money_format = :cents
|
11
11
|
self.homepage_url = 'http://www.barclaycard.co.uk/business/accepting-payments/epdq-mpi/'
|
12
|
-
self.display_name = 'Barclays ePDQ'
|
12
|
+
self.display_name = 'Barclays ePDQ MPI'
|
13
13
|
|
14
14
|
def initialize(options = {})
|
15
15
|
requires!(options, :login, :password, :client_id)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class BarclaysEpdqExtraPlusGateway < OgoneGateway
|
4
|
+
self.test_url = "https://mdepayments.epdq.co.uk/ncol/test/"
|
5
|
+
self.live_url = "https://payments.epdq.co.uk/ncol/prod/"
|
6
|
+
|
7
|
+
self.display_name = "Barclays ePDQ Extra Plus"
|
8
|
+
self.homepage_url = "http://www.barclaycard.co.uk/business/accepting-payments/epdq-ecomm/"
|
9
|
+
|
10
|
+
self.supported_countries = ["GB"]
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro]
|
12
|
+
self.default_currency = "GBP"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -24,6 +24,9 @@ module ActiveMerchant #:nodoc:
|
|
24
24
|
# CyberSource what kind of item you are selling. It is used when
|
25
25
|
# calculating tax/VAT.
|
26
26
|
# * All transactions use dollar values.
|
27
|
+
# * To process pinless debit cards throught the pinless debit card
|
28
|
+
# network, your Cybersource merchant account must accept pinless
|
29
|
+
# debit card payments.
|
27
30
|
class CyberSourceGateway < Gateway
|
28
31
|
self.test_url = 'https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor'
|
29
32
|
self.live_url = 'https://ics2ws.ic3.com/commerce/1.x/transactionProcessor'
|
@@ -132,6 +135,7 @@ module ActiveMerchant #:nodoc:
|
|
132
135
|
|
133
136
|
# Purchase is an auth followed by a capture
|
134
137
|
# You must supply an order_id in the options hash
|
138
|
+
# options[:pinless_debit_card] => true # attempts to process as pinless debit card
|
135
139
|
def purchase(money, payment_method_or_reference, options = {})
|
136
140
|
requires!(options, :order_id)
|
137
141
|
setup_address_hash(options)
|
@@ -212,6 +216,12 @@ module ActiveMerchant #:nodoc:
|
|
212
216
|
commit(build_tax_calculation_request(creditcard, options), options)
|
213
217
|
end
|
214
218
|
|
219
|
+
# Determines if a card can be used for Pinless Debit Card transactions
|
220
|
+
def validate_pinless_debit_card(creditcard, options = {})
|
221
|
+
requires!(options, :order_id)
|
222
|
+
commit(build_validate_pinless_debit_request(creditcard,options), options)
|
223
|
+
end
|
224
|
+
|
215
225
|
private
|
216
226
|
|
217
227
|
# Create all address hash key value pairs so that we still function if we
|
@@ -258,7 +268,7 @@ module ActiveMerchant #:nodoc:
|
|
258
268
|
add_check_service(xml)
|
259
269
|
else
|
260
270
|
add_purchase_service(xml, options)
|
261
|
-
add_business_rules_data(xml)
|
271
|
+
add_business_rules_data(xml) unless options[:pinless_debit_card]
|
262
272
|
end
|
263
273
|
xml.target!
|
264
274
|
end
|
@@ -349,6 +359,13 @@ module ActiveMerchant #:nodoc:
|
|
349
359
|
xml.target!
|
350
360
|
end
|
351
361
|
|
362
|
+
def build_validate_pinless_debit_request(creditcard,options)
|
363
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
364
|
+
add_creditcard(xml, creditcard)
|
365
|
+
add_validate_pinless_debit_service(xml)
|
366
|
+
xml.target!
|
367
|
+
end
|
368
|
+
|
352
369
|
def add_business_rules_data(xml)
|
353
370
|
xml.tag! 'businessRules' do
|
354
371
|
xml.tag!('ignoreAVSResult', 'true') if @options[:ignore_avs]
|
@@ -441,8 +458,12 @@ module ActiveMerchant #:nodoc:
|
|
441
458
|
end
|
442
459
|
|
443
460
|
def add_purchase_service(xml, options)
|
444
|
-
|
445
|
-
|
461
|
+
if options[:pinless_debit_card]
|
462
|
+
xml.tag! 'pinlessDebitService', {'run' => 'true'}
|
463
|
+
else
|
464
|
+
xml.tag! 'ccAuthService', {'run' => 'true'}
|
465
|
+
xml.tag! 'ccCaptureService', {'run' => 'true'}
|
466
|
+
end
|
446
467
|
end
|
447
468
|
|
448
469
|
def add_void_service(xml, request_id, request_token)
|
@@ -535,6 +556,10 @@ module ActiveMerchant #:nodoc:
|
|
535
556
|
end
|
536
557
|
end
|
537
558
|
|
559
|
+
def add_validate_pinless_debit_service(xml)
|
560
|
+
xml.tag!'pinlessDebitValidateService', {'run' => 'true'}
|
561
|
+
end
|
562
|
+
|
538
563
|
# Where we actually build the full SOAP request using builder
|
539
564
|
def build_request(body, options)
|
540
565
|
xml = Builder::XmlMarkup.new :indent => 2
|
@@ -104,6 +104,23 @@ module ActiveMerchant #:nodoc:
|
|
104
104
|
commit(url_for("GetAccessCodeResult"), request)
|
105
105
|
end
|
106
106
|
|
107
|
+
# Public: Store card details and return a valid token
|
108
|
+
#
|
109
|
+
# options - A supplemented ActiveMerchant options hash:
|
110
|
+
# :order_id - A merchant-supplied identifier for the
|
111
|
+
# transaction (optional).
|
112
|
+
# :billing_address - Standard ActiveMerchant address hash
|
113
|
+
# (required).
|
114
|
+
# :ip - The ip of the consumer initiating the
|
115
|
+
# transaction (optional).
|
116
|
+
# :application_id - A string identifying the application
|
117
|
+
# submitting the transaction
|
118
|
+
# (default: "https://github.com/Shopify/active_merchant")
|
119
|
+
def store(payment_method, options = {})
|
120
|
+
requires!(options, :billing_address)
|
121
|
+
purchase(0, payment_method, options.merge(:request_method => "CreateTokenCustomer"))
|
122
|
+
end
|
123
|
+
|
107
124
|
private
|
108
125
|
|
109
126
|
def run_purchase(identification, payment_method, endpoint)
|
@@ -118,7 +135,7 @@ module ActiveMerchant #:nodoc:
|
|
118
135
|
def add_metadata(doc, options)
|
119
136
|
doc.RedirectUrl(options[:redirect_url])
|
120
137
|
doc.CustomerIP options[:ip] if options[:ip]
|
121
|
-
doc.Method "ProcessPayment"
|
138
|
+
doc.Method options[:request_method] || "ProcessPayment"
|
122
139
|
doc.DeviceID(options[:application_id] || application_id)
|
123
140
|
end
|
124
141
|
|
@@ -148,13 +165,14 @@ module ActiveMerchant #:nodoc:
|
|
148
165
|
doc.FirstName parts.shift if parts.size > 1
|
149
166
|
doc.LastName parts.join(" ")
|
150
167
|
end
|
168
|
+
doc.Title address[:title]
|
151
169
|
doc.CompanyName address[:company] unless options[:skip_company]
|
152
170
|
doc.Street1 address[:address1]
|
153
171
|
doc.Street2 address[:address2]
|
154
172
|
doc.City address[:city]
|
155
173
|
doc.State address[:state]
|
156
174
|
doc.PostalCode address[:zip]
|
157
|
-
doc.Country address[:country]
|
175
|
+
doc.Country address[:country].to_s.downcase
|
158
176
|
doc.Phone address[:phone]
|
159
177
|
doc.Fax address[:fax]
|
160
178
|
doc.Email options[:email]
|
@@ -242,6 +260,8 @@ module ActiveMerchant #:nodoc:
|
|
242
260
|
def success?(response)
|
243
261
|
if response[:errors]
|
244
262
|
false
|
263
|
+
elsif response[:responsecode] == "00"
|
264
|
+
true
|
245
265
|
elsif response[:transactionstatus]
|
246
266
|
(response[:transactionstatus] == "true")
|
247
267
|
else
|
@@ -0,0 +1,275 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class MerchantWareVersionFourGateway < Gateway
|
4
|
+
self.live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
|
5
|
+
self.test_url = 'https://staging.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
|
6
|
+
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
9
|
+
self.homepage_url = 'http://merchantwarehouse.com/merchantware'
|
10
|
+
self.display_name = 'MerchantWARE'
|
11
|
+
|
12
|
+
ENV_NAMESPACES = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
13
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
14
|
+
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/" }
|
15
|
+
|
16
|
+
TX_NAMESPACE = "http://schemas.merchantwarehouse.com/merchantware/40/Credit/"
|
17
|
+
|
18
|
+
ACTIONS = {
|
19
|
+
:purchase => "SaleKeyed",
|
20
|
+
:reference_purchase => 'RepeatSale',
|
21
|
+
:authorize => "PreAuthorizationKeyed",
|
22
|
+
:capture => "PostAuthorization",
|
23
|
+
:void => "VoidPreAuthorization",
|
24
|
+
:refund => "Refund"
|
25
|
+
}
|
26
|
+
|
27
|
+
# Creates a new MerchantWareVersionFourGateway
|
28
|
+
#
|
29
|
+
# The gateway requires that a valid login, password, and name be passed
|
30
|
+
# in the +options+ hash.
|
31
|
+
#
|
32
|
+
# ==== Options
|
33
|
+
#
|
34
|
+
# * <tt>:login</tt> - The MerchantWARE SiteID.
|
35
|
+
# * <tt>:password</tt> - The MerchantWARE Key.
|
36
|
+
# * <tt>:name</tt> - The MerchantWARE Name.
|
37
|
+
def initialize(options = {})
|
38
|
+
requires!(options, :login, :password, :name)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
# Authorize a credit card for a given amount.
|
43
|
+
#
|
44
|
+
# ==== Parameters
|
45
|
+
# * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
|
46
|
+
# * <tt>credit_card</tt> - The CreditCard details for the transaction.
|
47
|
+
# * <tt>options</tt>
|
48
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required).
|
49
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
50
|
+
def authorize(money, credit_card, options = {})
|
51
|
+
request = build_purchase_request(:authorize, money, credit_card, options)
|
52
|
+
commit(:authorize, request)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Authorize and immediately capture funds from a credit card.
|
56
|
+
#
|
57
|
+
# ==== Parameters
|
58
|
+
# * <tt>money</tt> - The amount to be authorized as anInteger value in cents.
|
59
|
+
# * <tt>payment_source</tt> - The CreditCard details or 'token' from prior transaction
|
60
|
+
# * <tt>options</tt>
|
61
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required).
|
62
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
63
|
+
def purchase(money, payment_source, options = {})
|
64
|
+
action = payment_source.is_a?(String) ? :reference_purchase : :purchase
|
65
|
+
request = build_purchase_request(action, money, payment_source, options)
|
66
|
+
commit(action, request)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Capture authorized funds from a credit card.
|
70
|
+
#
|
71
|
+
# ==== Parameters
|
72
|
+
# * <tt>money</tt> - The amount to be captured as anInteger value in cents.
|
73
|
+
# * <tt>authorization</tt> - The authorization string returned from the initial authorization.
|
74
|
+
def capture(money, authorization, options = {})
|
75
|
+
request = build_capture_request(:capture, money, authorization, options)
|
76
|
+
commit(:capture, request)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Void a transaction.
|
80
|
+
#
|
81
|
+
# ==== Parameters
|
82
|
+
# * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
|
83
|
+
def void(authorization, options = {})
|
84
|
+
reference, options[:order_id] = split_reference(authorization)
|
85
|
+
request = soap_request(:void) do |xml|
|
86
|
+
add_reference_token(xml, reference)
|
87
|
+
end
|
88
|
+
commit(:void, request)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Refund an amount back a cardholder
|
92
|
+
#
|
93
|
+
# ==== Parameters
|
94
|
+
#
|
95
|
+
# * <tt>money</tt> - The amount to be refunded as an Integer value in cents.
|
96
|
+
# * <tt>identification</tt> - The credit card you want to refund or the authorization for the existing transaction you are refunding.
|
97
|
+
# * <tt>options</tt>
|
98
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required when performing a non-referenced credit)
|
99
|
+
def refund(money, identification, options = {})
|
100
|
+
reference, options[:order_id] = split_reference(identification)
|
101
|
+
|
102
|
+
request = soap_request(:refund) do |xml|
|
103
|
+
add_reference_token(xml, reference)
|
104
|
+
add_invoice(xml, options)
|
105
|
+
add_amount(xml, money, "overrideAmount")
|
106
|
+
end
|
107
|
+
|
108
|
+
commit(:refund, request)
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def soap_request(action)
|
114
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
115
|
+
xml.instruct!
|
116
|
+
xml.tag! "soap:Envelope", ENV_NAMESPACES do
|
117
|
+
xml.tag! "soap:Body" do
|
118
|
+
xml.tag! ACTIONS[action], "xmlns" => TX_NAMESPACE do
|
119
|
+
xml.tag! "merchantName", @options[:name]
|
120
|
+
xml.tag! "merchantSiteId", @options[:login]
|
121
|
+
xml.tag! "merchantKey", @options[:password]
|
122
|
+
yield xml
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
xml.target!
|
127
|
+
end
|
128
|
+
|
129
|
+
def build_purchase_request(action, money, payment_source, options)
|
130
|
+
requires!(options, :order_id)
|
131
|
+
|
132
|
+
request = soap_request(action) do |xml|
|
133
|
+
add_invoice(xml, options)
|
134
|
+
add_amount(xml, money)
|
135
|
+
add_payment_source(xml, payment_source)
|
136
|
+
add_address(xml, options)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def build_capture_request(action, money, identification, options)
|
141
|
+
reference, options[:order_id] = split_reference(identification)
|
142
|
+
|
143
|
+
request = soap_request(action) do |xml|
|
144
|
+
add_reference_token(xml, reference)
|
145
|
+
add_invoice(xml, options)
|
146
|
+
add_amount(xml, money)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def expdate(credit_card)
|
151
|
+
year = sprintf("%.4i", credit_card.year)
|
152
|
+
month = sprintf("%.2i", credit_card.month)
|
153
|
+
|
154
|
+
"#{month}#{year[-2..-1]}"
|
155
|
+
end
|
156
|
+
|
157
|
+
def add_invoice(xml, options)
|
158
|
+
xml.tag! "invoiceNumber", options[:order_id].to_s.gsub(/[^\w]/, '').slice(0, 25)
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_amount(xml, money, tag = "amount")
|
162
|
+
xml.tag! tag, amount(money)
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_reference_token(xml, reference)
|
166
|
+
xml.tag! "token", reference
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_address(xml, options)
|
170
|
+
address = options[:billing_address] || options[:address] || {}
|
171
|
+
xml.tag! "avsStreetAddress", address[:address1]
|
172
|
+
xml.tag! "avsStreetZipCode", address[:zip]
|
173
|
+
end
|
174
|
+
|
175
|
+
def add_payment_source(xml, source)
|
176
|
+
if source.is_a?(String)
|
177
|
+
add_reference_token(xml, source)
|
178
|
+
else
|
179
|
+
add_credit_card(xml, source)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def add_credit_card(xml, credit_card)
|
184
|
+
xml.tag! "cardNumber", credit_card.number
|
185
|
+
xml.tag! "expirationDate", expdate(credit_card)
|
186
|
+
xml.tag! "cardholder", credit_card.name
|
187
|
+
xml.tag! "cardSecurityCode", credit_card.verification_value if credit_card.verification_value?
|
188
|
+
end
|
189
|
+
|
190
|
+
def split_reference(reference)
|
191
|
+
reference.to_s.split(";")
|
192
|
+
end
|
193
|
+
|
194
|
+
def parse(action, data)
|
195
|
+
response = {}
|
196
|
+
xml = REXML::Document.new(data)
|
197
|
+
|
198
|
+
root = REXML::XPath.first(xml, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
|
199
|
+
|
200
|
+
root.elements.each do |element|
|
201
|
+
response[element.name] = element.text
|
202
|
+
end
|
203
|
+
|
204
|
+
if response["ErrorMessage"].present?
|
205
|
+
response[:message] = response["ErrorMessage"]
|
206
|
+
response[:success] = false
|
207
|
+
else
|
208
|
+
status, code, message = response["ApprovalStatus"].split(";")
|
209
|
+
response[:status] = status
|
210
|
+
|
211
|
+
if response[:success] = status == "APPROVED"
|
212
|
+
response[:message] = status
|
213
|
+
else
|
214
|
+
response[:message] = message
|
215
|
+
response[:failure_code] = code
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
response
|
220
|
+
end
|
221
|
+
|
222
|
+
def parse_error(http_response, action)
|
223
|
+
response = {}
|
224
|
+
response[:http_code] = http_response.code
|
225
|
+
response[:http_message] = http_response.message
|
226
|
+
response[:success] = false
|
227
|
+
|
228
|
+
document = REXML::Document.new(http_response.body)
|
229
|
+
node = REXML::XPath.first(document, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
|
230
|
+
|
231
|
+
node.elements.each do |element|
|
232
|
+
response[element.name] = element.text
|
233
|
+
end
|
234
|
+
|
235
|
+
response[:message] = response["ErrorMessage"].to_s.gsub("\n", " ")
|
236
|
+
response
|
237
|
+
rescue REXML::ParseException => e
|
238
|
+
response[:http_body] = http_response.body
|
239
|
+
response[:message] = "Failed to parse the failed response"
|
240
|
+
response
|
241
|
+
end
|
242
|
+
|
243
|
+
def soap_action(action)
|
244
|
+
"#{TX_NAMESPACE}#{ACTIONS[action]}"
|
245
|
+
end
|
246
|
+
|
247
|
+
def url
|
248
|
+
test? ? test_url : live_url
|
249
|
+
end
|
250
|
+
|
251
|
+
def commit(action, request)
|
252
|
+
begin
|
253
|
+
data = ssl_post(url, request,
|
254
|
+
"Content-Type" => 'text/xml; charset=utf-8',
|
255
|
+
"SOAPAction" => soap_action(action)
|
256
|
+
)
|
257
|
+
response = parse(action, data)
|
258
|
+
rescue ActiveMerchant::ResponseError => e
|
259
|
+
response = parse_error(e.response, action)
|
260
|
+
end
|
261
|
+
|
262
|
+
Response.new(response[:success], response[:message], response,
|
263
|
+
:test => test?,
|
264
|
+
:authorization => authorization_from(response),
|
265
|
+
:avs_result => { :code => response["AvsResponse"] },
|
266
|
+
:cvv_result => response["CvResponse"]
|
267
|
+
)
|
268
|
+
end
|
269
|
+
|
270
|
+
def authorization_from(response)
|
271
|
+
response['Token']
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -1,5 +1,15 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Billing #:nodoc:
|
3
|
+
# The Mercury gateway integration by default requires that the Mercury
|
4
|
+
# account being used has tokenization turned. This enables the use of
|
5
|
+
# capture/refund/void without having to pass the credit card back in each
|
6
|
+
# time. Only the "OneTime" tokenization is used; there is no use of
|
7
|
+
# "Recurring" tokenization.
|
8
|
+
#
|
9
|
+
# If you don't wish to enable Mercury tokenization, you can pass
|
10
|
+
# <code>:tokenization => false</code> as an option when creating the
|
11
|
+
# gateway. If you do so, then passing a +:credit_card+ option to +capture+
|
12
|
+
# and +refund+ will become mandatory.
|
3
13
|
class MercuryGateway < Gateway
|
4
14
|
URLS = {
|
5
15
|
:test => 'https://w1.mercurydev.net/ws/ws.asmx',
|
@@ -14,6 +24,7 @@ module ActiveMerchant #:nodoc:
|
|
14
24
|
|
15
25
|
def initialize(options = {})
|
16
26
|
requires!(options, :login, :password)
|
27
|
+
@use_tokenization = (!options.has_key?(:tokenization) || options[:tokenization])
|
17
28
|
super
|
18
29
|
end
|
19
30
|
|
@@ -34,25 +45,28 @@ module ActiveMerchant #:nodoc:
|
|
34
45
|
def authorize(money, credit_card, options = {})
|
35
46
|
requires!(options, :order_id)
|
36
47
|
|
37
|
-
options
|
38
|
-
request = build_non_authorized_request('PreAuth', money, credit_card, options)
|
48
|
+
request = build_non_authorized_request('PreAuth', money, credit_card, options.merge(:authorized => money))
|
39
49
|
commit('PreAuth', request)
|
40
50
|
end
|
41
51
|
|
42
52
|
def capture(money, authorization, options = {})
|
43
|
-
requires!(options, :credit_card)
|
44
|
-
|
45
|
-
request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options)
|
53
|
+
requires!(options, :credit_card) unless @use_tokenization
|
54
|
+
|
55
|
+
request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options.merge(:authorized => money))
|
46
56
|
commit('PreAuthCapture', request)
|
47
57
|
end
|
48
58
|
|
49
59
|
def refund(money, authorization, options = {})
|
50
|
-
requires!(options, :credit_card)
|
60
|
+
requires!(options, :credit_card) unless @use_tokenization
|
51
61
|
|
52
62
|
request = build_authorized_request('VoidSale', money, authorization, options[:credit_card], options)
|
53
63
|
commit(options[:void], request)
|
54
64
|
end
|
55
65
|
|
66
|
+
def void(authorization, options={})
|
67
|
+
refund(nil, authorization, options.merge(:void => true))
|
68
|
+
end
|
69
|
+
|
56
70
|
private
|
57
71
|
|
58
72
|
def build_non_authorized_request(action, money, credit_card, options)
|
@@ -78,19 +92,21 @@ module ActiveMerchant #:nodoc:
|
|
78
92
|
def build_authorized_request(action, money, authorization, credit_card, options)
|
79
93
|
xml = Builder::XmlMarkup.new
|
80
94
|
|
81
|
-
invoice_no, ref_no, auth_code, acq_ref_data, process_data = split_authorization(authorization)
|
95
|
+
invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = split_authorization(authorization)
|
96
|
+
ref_no = invoice_no if options[:void]
|
82
97
|
|
83
98
|
xml.tag! "TStream" do
|
84
99
|
xml.tag! "Transaction" do
|
85
100
|
xml.tag! 'TranType', 'Credit'
|
86
|
-
xml.tag! 'TranCode', action
|
101
|
+
xml.tag! 'TranCode', (@use_tokenization ? (action + "ByRecordNo") : action)
|
87
102
|
if action == 'PreAuthCapture'
|
88
103
|
xml.tag! "PartialAuth", "Allow"
|
89
104
|
end
|
90
105
|
add_invoice(xml, invoice_no, ref_no, options)
|
106
|
+
add_reference(xml, record_no) if @use_tokenization
|
91
107
|
add_customer_data(xml, options)
|
92
|
-
add_amount(xml, money, options)
|
93
|
-
add_credit_card(xml, credit_card, action)
|
108
|
+
add_amount(xml, (money || amount.to_i), options)
|
109
|
+
add_credit_card(xml, credit_card, action) if credit_card
|
94
110
|
add_address(xml, options)
|
95
111
|
xml.tag! 'TranInfo' do
|
96
112
|
xml.tag! "AuthCode", auth_code
|
@@ -108,9 +124,18 @@ module ActiveMerchant #:nodoc:
|
|
108
124
|
end
|
109
125
|
|
110
126
|
xml.tag! 'InvoiceNo', invoice_no
|
111
|
-
xml.tag! 'RefNo', ref_no || invoice_no
|
127
|
+
xml.tag! 'RefNo', (ref_no || invoice_no)
|
112
128
|
xml.tag! 'OperatorID', options[:merchant] if options[:merchant]
|
113
129
|
xml.tag! 'Memo', options[:description] if options[:description]
|
130
|
+
if @use_tokenization
|
131
|
+
xml.tag! 'Frequency', "OneTime"
|
132
|
+
xml.tag! 'RecordNo', "RecordNumberRequested"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def add_reference(xml, record_no)
|
137
|
+
xml.tag! "Frequency", "OneTime"
|
138
|
+
xml.tag! "RecordNo", record_no
|
114
139
|
end
|
115
140
|
|
116
141
|
def add_customer_data(xml, options)
|
@@ -240,18 +265,23 @@ module ActiveMerchant #:nodoc:
|
|
240
265
|
end
|
241
266
|
|
242
267
|
def authorization_from(response)
|
268
|
+
dollars, cents = (response[:purchase] || "").split(".").collect{|e| e.to_i}
|
269
|
+
dollars ||= 0
|
270
|
+
cents ||= 0
|
243
271
|
[
|
244
272
|
response[:invoice_no],
|
245
273
|
response[:ref_no],
|
246
274
|
response[:auth_code],
|
247
275
|
response[:acq_ref_data],
|
248
|
-
response[:process_data]
|
276
|
+
response[:process_data],
|
277
|
+
response[:record_no],
|
278
|
+
((dollars * 100) + cents).to_s
|
249
279
|
].join(";")
|
250
280
|
end
|
251
281
|
|
252
282
|
def split_authorization(authorization)
|
253
|
-
invoice_no, ref_no, auth_code, acq_ref_data, process_data = authorization.split(";")
|
254
|
-
[invoice_no, ref_no, auth_code, acq_ref_data, process_data]
|
283
|
+
invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = authorization.split(";")
|
284
|
+
[invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount]
|
255
285
|
end
|
256
286
|
|
257
287
|
ENVELOPE_NAMESPACES = {
|
@@ -70,6 +70,14 @@ module ActiveMerchant #:nodoc:
|
|
70
70
|
commit :refund, build_reference_request(money, authorization)
|
71
71
|
end
|
72
72
|
|
73
|
+
def authorize(money, credit_card, options = {})
|
74
|
+
commit :authorization, build_purchase_request(money, credit_card, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def capture(money, authorization)
|
78
|
+
commit :capture, build_reference_request(money, authorization)
|
79
|
+
end
|
80
|
+
|
73
81
|
def store(creditcard, options = {})
|
74
82
|
requires!(options, :billing_id, :amount)
|
75
83
|
commit_periodic(build_periodic_item(:addcrn, options[:amount], creditcard, options))
|
@@ -99,12 +99,6 @@ module ActiveMerchant #:nodoc:
|
|
99
99
|
# :language => Customer's language, for example: "en_EN"
|
100
100
|
#
|
101
101
|
class OgoneGateway < Gateway
|
102
|
-
|
103
|
-
URLS = {
|
104
|
-
:order => 'https://secure.ogone.com/ncol/%s/orderdirect.asp',
|
105
|
-
:maintenance => 'https://secure.ogone.com/ncol/%s/maintenancedirect.asp'
|
106
|
-
}
|
107
|
-
|
108
102
|
CVV_MAPPING = { 'OK' => 'M',
|
109
103
|
'KO' => 'N',
|
110
104
|
'NO' => 'P' }
|
@@ -125,8 +119,8 @@ module ActiveMerchant #:nodoc:
|
|
125
119
|
OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE = "Signature usage will be the default for a future release of ActiveMerchant. You should either begin using it, or update your configuration to explicitly disable it (signature_encryptor: none)"
|
126
120
|
OGONE_STORE_OPTION_DEPRECATION_MESSAGE = "The 'store' option has been renamed to 'billing_id', and its usage is deprecated."
|
127
121
|
|
128
|
-
self.test_url =
|
129
|
-
self.live_url =
|
122
|
+
self.test_url = "https://secure.ogone.com/ncol/test/"
|
123
|
+
self.live_url = "https://secure.ogone.com/ncol/prod/"
|
130
124
|
|
131
125
|
self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH']
|
132
126
|
# also supports Airplus and UATP
|
@@ -331,8 +325,7 @@ module ActiveMerchant #:nodoc:
|
|
331
325
|
add_pair parameters, 'USERID', @options[:user]
|
332
326
|
add_pair parameters, 'PSWD', @options[:password]
|
333
327
|
|
334
|
-
|
335
|
-
response = parse(ssl_post(url, post_data(action, parameters)))
|
328
|
+
response = parse(ssl_post(url(parameters['PAYID']), post_data(action, parameters)))
|
336
329
|
|
337
330
|
options = {
|
338
331
|
:authorization => [response["PAYID"], action].join(";"),
|
@@ -343,6 +336,10 @@ module ActiveMerchant #:nodoc:
|
|
343
336
|
OgoneResponse.new(successful?(response), message_from(response), response, options)
|
344
337
|
end
|
345
338
|
|
339
|
+
def url(payid)
|
340
|
+
(test? ? test_url : live_url) + (payid ? "maintenancedirect.asp" : "orderdirect.asp")
|
341
|
+
end
|
342
|
+
|
346
343
|
def successful?(response)
|
347
344
|
response["NCERROR"] == "0"
|
348
345
|
end
|
@@ -342,6 +342,7 @@ module ActiveMerchant #:nodoc:
|
|
342
342
|
def build_mass_pay_request(*args)
|
343
343
|
default_options = args.last.is_a?(Hash) ? args.pop : {}
|
344
344
|
recipients = args.first.is_a?(Array) ? args : [args]
|
345
|
+
receiver_type = default_options[:receiver_type]
|
345
346
|
|
346
347
|
xml = Builder::XmlMarkup.new
|
347
348
|
|
@@ -349,11 +350,18 @@ module ActiveMerchant #:nodoc:
|
|
349
350
|
xml.tag! 'MassPayRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
350
351
|
xml.tag! 'n2:Version', API_VERSION
|
351
352
|
xml.tag! 'EmailSubject', default_options[:subject] if default_options[:subject]
|
353
|
+
xml.tag! 'ReceiverType', receiver_type if receiver_type
|
352
354
|
recipients.each do |money, recipient, options|
|
353
355
|
options ||= default_options
|
354
356
|
xml.tag! 'MassPayItem' do
|
355
|
-
|
356
|
-
|
357
|
+
if(!receiver_type || receiver_type == 'EmailAddress')
|
358
|
+
xml.tag! 'ReceiverEmail', recipient
|
359
|
+
elsif receiver_type == 'UserID'
|
360
|
+
xml.tag! 'ReceiverID', recipient
|
361
|
+
else
|
362
|
+
raise ArgumentError.new("Unknown receiver_type: #{receiver_type}")
|
363
|
+
end
|
364
|
+
xml.tag! 'Amount', amount(money), 'currencyID' => (options[:currency] || currency(money))
|
357
365
|
xml.tag! 'Note', options[:note] if options[:note]
|
358
366
|
xml.tag! 'UniqueId', options[:unique_id] if options[:unique_id]
|
359
367
|
end
|
@@ -394,7 +394,7 @@ module ActiveMerchant #:nodoc:
|
|
394
394
|
post[:StreetAddress] = address[:address1]
|
395
395
|
post[:StreetAddress2] = address[:address2]
|
396
396
|
post[:City] = address[:city]
|
397
|
-
post[:State] = address[:state]
|
397
|
+
post[:State] = address[:state] || 'XX'
|
398
398
|
post[:ZipCode] = address[:zip]
|
399
399
|
post[:Country] = address[:country]
|
400
400
|
post[:Phone] = address[:phone]
|
@@ -406,7 +406,7 @@ module ActiveMerchant #:nodoc:
|
|
406
406
|
post[:ShipToStreetAddress] = address[:address1]
|
407
407
|
post[:ShipToStreetAddress2] = address[:address2]
|
408
408
|
post[:ShipToCity] = address[:city]
|
409
|
-
post[:ShipToState] = address[:state]
|
409
|
+
post[:ShipToState] = address[:state] || 'XX'
|
410
410
|
post[:ShipToZipCode] = address[:zip]
|
411
411
|
post[:ShipToCountry] = address[:country]
|
412
412
|
post[:ShipToPhone] = address[:phone]
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require 'active_support/
|
1
|
+
require 'active_support/version' # for ActiveSupport2.3
|
2
|
+
require 'active_support/core_ext/float/rounding.rb' unless ActiveSupport::VERSION::MAJOR > 3 # Float#round(precision)
|
2
3
|
|
3
4
|
module ActiveMerchant #:nodoc:
|
4
5
|
module Billing #:nodoc:
|
@@ -9,11 +10,11 @@ module ActiveMerchant #:nodoc:
|
|
9
10
|
# so preferably pass in X.2 decimal so that no rounding occurs. It is
|
10
11
|
# rounded because if it looks like 00.000 Authorize.Net fails the
|
11
12
|
# transaction as incorrectly formatted.
|
12
|
-
#
|
13
|
+
#
|
13
14
|
# payment_service_for('order_id', 'authorize_net_account', :service => :authorize_net_sim, :amount => 157.0) do |service|
|
14
|
-
#
|
15
|
+
#
|
15
16
|
# # You must call setup_hash and invoice
|
16
|
-
#
|
17
|
+
#
|
17
18
|
# service.setup_hash :transaction_key => '8CP6zJ7uD875J6tY',
|
18
19
|
# :order_timestamp => 1206836763
|
19
20
|
# service.customer_id 8
|
@@ -24,7 +25,7 @@ module ActiveMerchant #:nodoc:
|
|
24
25
|
# service.billing_address :zip => 'g',
|
25
26
|
# :country => 'United States of America',
|
26
27
|
# :address => 'g'
|
27
|
-
#
|
28
|
+
#
|
28
29
|
# service.ship_to_address :first_name => 'g',
|
29
30
|
# :last_name => 'g',
|
30
31
|
# :city => '',
|
@@ -33,7 +34,7 @@ module ActiveMerchant #:nodoc:
|
|
33
34
|
# :state => address.state,
|
34
35
|
# :country => 'United States of America',
|
35
36
|
# :zip => 'g'
|
36
|
-
#
|
37
|
+
#
|
37
38
|
# service.invoice "516428355" # your invoice number
|
38
39
|
# # The end-user is presented with the HTML produced by the notify_url.
|
39
40
|
# service.notify_url "http://t/authorize_net_sim/payment_received_notification_sub_step"
|
@@ -48,20 +49,20 @@ module ActiveMerchant #:nodoc:
|
|
48
49
|
# server.add_tax_as_line_item # same with tax
|
49
50
|
# # See the helper.rb file for various custom fields
|
50
51
|
# end
|
51
|
-
|
52
|
-
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
52
|
+
|
53
|
+
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
53
54
|
mapping :order, 'x_fp_sequence'
|
54
55
|
mapping :account, 'x_login'
|
55
|
-
|
56
|
+
|
56
57
|
mapping :customer, :first_name => 'x_first_name',
|
57
58
|
:last_name => 'x_last_name',
|
58
59
|
:email => 'x_email',
|
59
60
|
:phone => 'x_phone'
|
60
|
-
|
61
|
+
|
61
62
|
mapping :notify_url, 'x_relay_url'
|
62
63
|
mapping :return_url, '' # unused
|
63
64
|
mapping :cancel_return_url, '' # unused
|
64
|
-
|
65
|
+
|
65
66
|
# Custom fields for Authorize.net SIM.
|
66
67
|
# See http://www.Authorize.Net/support/SIM_guide.pdf for more descriptions.
|
67
68
|
mapping :fax, 'x_fax'
|
@@ -69,18 +70,18 @@ module ActiveMerchant #:nodoc:
|
|
69
70
|
mapping :description, 'x_description'
|
70
71
|
mapping :tax, 'x_tax'
|
71
72
|
mapping :shipping, 'x_freight'
|
72
|
-
|
73
|
+
|
73
74
|
# True or false, or 0 or 1 same effect [not required to send one,
|
74
75
|
# defaults to false].
|
75
76
|
mapping :test_request, 'x_test_request'
|
76
|
-
|
77
|
+
|
77
78
|
# This one is necessary for the notify url to be able to parse its
|
78
79
|
# information later! They also pass back customer id, if that's
|
79
80
|
# useful.
|
80
81
|
def invoice(number)
|
81
82
|
add_field 'x_invoice_num', number
|
82
83
|
end
|
83
|
-
|
84
|
+
|
84
85
|
# Set the billing address. Call like service.billing_address {:city =>
|
85
86
|
# 'provo, :state => 'UT'}...
|
86
87
|
def billing_address(options)
|
@@ -90,29 +91,29 @@ module ActiveMerchant #:nodoc:
|
|
90
91
|
raise 'must use address1 and address2' if options[:address]
|
91
92
|
add_field 'x_address', (options[:address1].to_s + ' ' + options[:address2].to_s).strip
|
92
93
|
end
|
93
|
-
|
94
|
+
|
94
95
|
# Adds a custom field which you submit to Authorize.Net. These fields
|
95
96
|
# are all passed back to you verbatim when it does its relay
|
96
97
|
# (callback) to you note that if you call it twice with the same name,
|
97
|
-
# this function only uses keeps the second value you called it with.
|
98
|
+
# this function only uses keeps the second value you called it with.
|
98
99
|
def add_custom_field(name, value)
|
99
100
|
add_field name, value
|
100
101
|
end
|
101
|
-
|
102
|
+
|
102
103
|
# Displays tax as a line item, so they can see it. Otherwise it isn't
|
103
104
|
# displayed.
|
104
105
|
def add_tax_as_line_item
|
105
106
|
raise unless @fields['x_tax']
|
106
107
|
add_line_item :name => 'Total Tax', :quantity => 1, :unit_price => @fields['x_tax'], :tax => 0, :line_title => 'Tax'
|
107
108
|
end
|
108
|
-
|
109
|
+
|
109
110
|
# Displays shipping as a line item, so they can see it. Otherwise it
|
110
111
|
# isn't displayed.
|
111
112
|
def add_shipping_as_line_item(extra_options = {})
|
112
113
|
raise 'must set shipping/freight before calling this' unless @fields['x_freight']
|
113
114
|
add_line_item extra_options.merge({:name => 'Shipping and Handling Cost', :quantity => 1, :unit_price => @fields['x_freight'], :line_title => 'Shipping'})
|
114
115
|
end
|
115
|
-
|
116
|
+
|
116
117
|
# Add ship_to_address in the same format as the normal address is
|
117
118
|
# added.
|
118
119
|
def ship_to_address(options)
|
@@ -124,7 +125,7 @@ module ActiveMerchant #:nodoc:
|
|
124
125
|
raise 'must use :address1 and/or :address2' if options[:address]
|
125
126
|
add_field 'x_ship_to_address', (options[:address1].to_s + ' ' + options[:address2].to_s).strip
|
126
127
|
end
|
127
|
-
|
128
|
+
|
128
129
|
# These control the look of the SIM payment page. Note that you can
|
129
130
|
# include a CSS header in descriptors, etc.
|
130
131
|
mapping :color_link, 'x_color_link'
|
@@ -133,7 +134,7 @@ module ActiveMerchant #:nodoc:
|
|
133
134
|
mapping :background_url, 'x_background_url' # background image url for the page
|
134
135
|
mapping :payment_header, 'x_header_html_payment_form'
|
135
136
|
mapping :payment_footer, 'x_footer_html_payment_form'
|
136
|
-
|
137
|
+
|
137
138
|
# For this to work you must have also passed in an email for the
|
138
139
|
# purchaser.
|
139
140
|
def yes_email_customer_from_authorizes_side
|
@@ -149,7 +150,7 @@ module ActiveMerchant #:nodoc:
|
|
149
150
|
# You can use the :line_title for the product name and then :name for description, if desired
|
150
151
|
def add_line_item(options)
|
151
152
|
raise 'needs name' unless options[:name]
|
152
|
-
|
153
|
+
|
153
154
|
if @line_item_count == 30
|
154
155
|
# Add a note that we are not showing at least one -- AN doesn't
|
155
156
|
# display more than 30 or so.
|
@@ -159,18 +160,18 @@ module ActiveMerchant #:nodoc:
|
|
159
160
|
# Create a new description, which can't be too big, so truncate here.
|
160
161
|
@raw_html_fields[-1][1] = description_of_last.gsub($1, $1[0..200] + ' + more unshown items after this one.')
|
161
162
|
end
|
162
|
-
|
163
|
+
|
163
164
|
name = options[:name]
|
164
165
|
quantity = options[:quantity] || 1
|
165
166
|
line_title = options[:line_title] || ('Item ' + (@line_item_count + 1).to_s) # left most field
|
166
167
|
unit_price = options[:unit_price] || 0
|
167
168
|
unit_price = unit_price.to_f.round(2)
|
168
169
|
tax_value = options[:tax_value] || 'N'
|
169
|
-
|
170
|
+
|
170
171
|
# Sanitization, in case they include a reserved word here, following
|
171
172
|
# their guidelines; unfortunately, they require 'raw' fields here,
|
172
173
|
# not CGI escaped, using their own delimiters.
|
173
|
-
#
|
174
|
+
#
|
174
175
|
# Authorize.net ignores the second field (sanitized_short_name)
|
175
176
|
raise 'illegal char for line item <|>' if name.include? '<|>'
|
176
177
|
raise 'illegal char for line item "' if name.include? '"'
|
@@ -180,19 +181,19 @@ module ActiveMerchant #:nodoc:
|
|
180
181
|
# the HTML presented to the end-user's browser (e.g., spaces turn
|
181
182
|
# into +'s).
|
182
183
|
sanitized_short_name = name[0..30]
|
183
|
-
name = name[0..255]
|
184
|
+
name = name[0..255]
|
184
185
|
|
185
186
|
add_raw_html_field "x_line_item", "#{line_title}<|>#{sanitized_short_name}<|>#{name}<|>#{quantity}<|>#{unit_price}<|>#{tax_value}"
|
186
187
|
|
187
188
|
@line_item_count += 1
|
188
189
|
end
|
189
|
-
|
190
|
+
|
190
191
|
# If you call this it will e-mail to this address a copy of a receipt
|
191
192
|
# after successful, from Authorize.Net.
|
192
193
|
def email_merchant_from_authorizes_side(to_this_email)
|
193
194
|
add_field 'x_email_merchant', to_this_email
|
194
195
|
end
|
195
|
-
|
196
|
+
|
196
197
|
# You MUST call this at some point for it to actually work. Options
|
197
198
|
# must include :transaction_key and :order_timestamp
|
198
199
|
def setup_hash(options)
|
@@ -204,7 +205,7 @@ module ActiveMerchant #:nodoc:
|
|
204
205
|
add_field 'x_fp_hash', hmac
|
205
206
|
add_field 'x_fp_timestamp', options[:order_timestamp].to_i
|
206
207
|
end
|
207
|
-
|
208
|
+
|
208
209
|
# Note that you should call #invoice and #setup_hash as well, for the
|
209
210
|
# response_url to actually work.
|
210
211
|
def initialize(order, account, options = {})
|
@@ -7,8 +7,8 @@ module ActiveMerchant #:nodoc:
|
|
7
7
|
autoload :Return, File.dirname(__FILE__) + '/hi_trust/return.rb'
|
8
8
|
autoload :Notification, File.dirname(__FILE__) + '/hi_trust/notification.rb'
|
9
9
|
|
10
|
-
TEST_URL = 'https://testtrustlink.hitrust.com.tw/TrustLink/
|
11
|
-
LIVE_URL = 'https://trustlink.hitrust.com.tw/TrustLink/
|
10
|
+
TEST_URL = 'https://testtrustlink.hitrust.com.tw/TrustLink/TrxReqForJava'
|
11
|
+
LIVE_URL = 'https://trustlink.hitrust.com.tw/TrustLink/TrxReqForJava'
|
12
12
|
|
13
13
|
def self.service_url
|
14
14
|
ActiveMerchant::Billing::Base.integration_mode == :test ? TEST_URL : LIVE_URL
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require 'active_support/
|
1
|
+
require 'active_support/version' # for ActiveSupport2.3
|
2
|
+
require 'active_support/core_ext/float/rounding.rb' unless ActiveSupport::VERSION::MAJOR > 3 # Float#round(precision)
|
2
3
|
|
3
4
|
module ActiveMerchant #:nodoc:
|
4
5
|
module Billing #:nodoc:
|
@@ -13,7 +14,7 @@ module ActiveMerchant #:nodoc:
|
|
13
14
|
# in addition to the user being redirected to your return_url, the return_url will
|
14
15
|
# be accessed by the PxPay servers directly, immediately after transaction success.
|
15
16
|
#
|
16
|
-
# payment_service_for('order_id', 'pxpay_user_ID', :service => :pxpay,
|
17
|
+
# payment_service_for('order_id', 'pxpay_user_ID', :service => :pxpay,
|
17
18
|
# :amount => 157.0, :currency => 'USD', :credential2 => 'pxpay_key') do |service|
|
18
19
|
#
|
19
20
|
# service.customer :email => 'customer@email.com'
|
@@ -3,40 +3,40 @@ module ActiveMerchant #:nodoc:
|
|
3
3
|
module Integrations #:nodoc:
|
4
4
|
module Verkkomaksut
|
5
5
|
class Helper < ActiveMerchant::Billing::Integrations::Helper
|
6
|
-
|
6
|
+
|
7
7
|
# Fetches the md5secret and adds MERCHANT_ID and API TYPE to the form
|
8
8
|
def initialize(order, account, options = {})
|
9
9
|
md5secret options.delete(:credential2)
|
10
10
|
super
|
11
11
|
add_field("MERCHANT_ID", account)
|
12
12
|
add_field("TYPE", "E1")
|
13
|
-
end
|
14
|
-
|
13
|
+
end
|
14
|
+
|
15
15
|
def md5secret(value)
|
16
16
|
@md5secret = value
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# Adds the AUTHCODE to the form
|
20
20
|
def form_fields
|
21
21
|
@fields.merge("AUTHCODE" => generate_md5string)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# Calculates the AUTHCODE
|
25
25
|
def generate_md5string
|
26
26
|
fields = [@md5secret, @fields["MERCHANT_ID"], @fields["ORDER_NUMBER"], @fields["REFERENCE_NUMBER"], @fields["ORDER_DESCRIPTION"], @fields["CURRENCY"], @fields["RETURN_ADDRESS"], @fields["CANCEL_ADDRESS"], @fields["PENDING_ADDRESS"],
|
27
27
|
@fields["NOTIFY_ADDRESS"], @fields["TYPE"], @fields["CULTURE"], @fields["PRESELECTED_METHOD"], @fields["MODE"], @fields["VISIBLE_METHODS"], @fields["GROUP"], @fields["CONTACT_TELNO"], @fields["CONTACT_CELLNO"],
|
28
28
|
@fields["CONTACT_EMAIL"], @fields["CONTACT_FIRSTNAME"], @fields["CONTACT_LASTNAME"], @fields["CONTACT_COMPANY"], @fields["CONTACT_ADDR_STREET"], @fields["CONTACT_ADDR_ZIP"], @fields["CONTACT_ADDR_CITY"], @fields["CONTACT_ADDR_COUNTRY"], @fields["INCLUDE_VAT"],
|
29
29
|
@fields["ITEMS"]]
|
30
|
-
|
30
|
+
|
31
31
|
(0..@fields["ITEMS"].to_i-1).each do |i|
|
32
32
|
fields += [@fields["ITEM_TITLE[#{i}]"], @fields["ITEM_NO[#{i}]"], @fields["ITEM_AMOUNT[#{i}]"], @fields["ITEM_PRICE[#{i}]"], @fields["ITEM_TAX[#{i}]"], @fields["ITEM_DISCOUNT[#{i}]"], @fields["ITEM_TYPE[#{i}]"]]
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
fields = fields.join("|")
|
36
|
-
|
36
|
+
|
37
37
|
return Digest::MD5.hexdigest(fields).upcase
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
# Mappings
|
41
41
|
mapping :merchant_id, "MERCHANT_ID"
|
42
42
|
mapping :order, "ORDER_NUMBER"
|
@@ -47,8 +47,8 @@ module ActiveMerchant #:nodoc:
|
|
47
47
|
:phone => "CONTACT_CELLNO",
|
48
48
|
:tellno => "CONTACT_TELLNO",
|
49
49
|
:company => "CONTACT_COMPANY"
|
50
|
-
|
51
|
-
|
50
|
+
|
51
|
+
|
52
52
|
mapping :billing_address, :city => "CONTACT_ADDR_CITY",
|
53
53
|
:address1 => "CONTACT_ADDR_STREET",
|
54
54
|
:address2 => "",
|
@@ -71,8 +71,9 @@ module ActiveMerchant #:nodoc:
|
|
71
71
|
mapping :mode, "MODE"
|
72
72
|
mapping :visible_methods, "VISIBLE_METHODS"
|
73
73
|
mapping :group, "GROUP"
|
74
|
-
|
74
|
+
|
75
75
|
(0..499.to_i).each do |i|
|
76
|
+
mapping "item_title_#{i}".to_sym, "ITEM_TITLE[#{i}]"
|
76
77
|
mapping "item_no_#{i}".to_sym, "ITEM_NO[#{i}]"
|
77
78
|
mapping "item_amount_#{i}".to_sym, "ITEM_AMOUNT[#{i}]"
|
78
79
|
mapping "item_price_#{i}".to_sym, "ITEM_PRICE[#{i}]"
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: activemerchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.35.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Tobias Luetke
|
@@ -37,7 +37,7 @@ cert_chain:
|
|
37
37
|
Z1BvU1BxN25rK3MyRlFVQko5VVpGSzFsZ016aG8vNGZaZ3pKd2J1K2NPOFNO
|
38
38
|
dWFMUy9iagpoUGFTVHlWVTB5Q1Nudz09Ci0tLS0tRU5EIENFUlRJRklDQVRF
|
39
39
|
LS0tLS0K
|
40
|
-
date: 2013-
|
40
|
+
date: 2013-07-25 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- lib/active_merchant/billing/gateways/balanced.rb
|
245
245
|
- lib/active_merchant/billing/gateways/banwire.rb
|
246
246
|
- lib/active_merchant/billing/gateways/barclays_epdq.rb
|
247
|
+
- lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb
|
247
248
|
- lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb
|
248
249
|
- lib/active_merchant/billing/gateways/beanstream.rb
|
249
250
|
- lib/active_merchant/billing/gateways/beanstream_interac.rb
|
@@ -289,6 +290,7 @@ files:
|
|
289
290
|
- lib/active_merchant/billing/gateways/merchant_e_solutions.rb
|
290
291
|
- lib/active_merchant/billing/gateways/merchant_one.rb
|
291
292
|
- lib/active_merchant/billing/gateways/merchant_ware.rb
|
293
|
+
- lib/active_merchant/billing/gateways/merchant_ware_version_four.rb
|
292
294
|
- lib/active_merchant/billing/gateways/merchant_warrior.rb
|
293
295
|
- lib/active_merchant/billing/gateways/mercury.rb
|
294
296
|
- lib/active_merchant/billing/gateways/metrics_global.rb
|
metadata.gz.sig
CHANGED
Binary file
|