activemerchant 1.34.1 → 1.35.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 +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
|
+
[![Build Status](https://secure.travis-ci.org/Shopify/active_merchant.png)](http://travis-ci.org/Shopify/active_merchant)
|
3
|
+
[![Code Climate](https://codeclimate.com/badge.png)](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
|
-
[![Build Status](https://secure.travis-ci.org/Shopify/active_merchant.png)](http://travis-ci.org/Shopify/active_merchant)
|
220
|
-
|
221
|
-
[![Code Climate](https://codeclimate.com/badge.png)](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
|