activemerchant 1.60.0 → 1.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +64 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +1 -1
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +12 -1
- data/lib/active_merchant/billing/gateways/blue_pay.rb +1 -1
- data/lib/active_merchant/billing/gateways/blue_snap.rb +1 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +8 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +2 -0
- data/lib/active_merchant/billing/gateways/citrus_pay.rb +24 -0
- data/lib/active_merchant/billing/gateways/clearhaus.rb +12 -4
- data/lib/active_merchant/billing/gateways/conekta.rb +6 -1
- data/lib/active_merchant/billing/gateways/credorax.rb +234 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +39 -52
- data/lib/active_merchant/billing/gateways/element.rb +13 -2
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +12 -3
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +5 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +3 -1
- data/lib/active_merchant/billing/gateways/jetpay.rb +11 -3
- data/lib/active_merchant/billing/gateways/linkpoint.rb +2 -0
- data/lib/active_merchant/billing/gateways/litle.rb +28 -12
- data/lib/active_merchant/billing/gateways/mastercard.rb +261 -0
- data/lib/active_merchant/billing/gateways/migs.rb +23 -1
- data/lib/active_merchant/billing/gateways/monei.rb +1 -1
- data/lib/active_merchant/billing/gateways/moneris.rb +13 -0
- data/lib/active_merchant/billing/gateways/netbanx.rb +245 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +5 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +7 -0
- data/lib/active_merchant/billing/gateways/opp.rb +362 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +13 -0
- data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +190 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +6 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paymill.rb +10 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/payu_latam.rb +386 -0
- data/lib/active_merchant/billing/gateways/pin.rb +1 -3
- data/lib/active_merchant/billing/gateways/redsys.rb +2 -0
- data/lib/active_merchant/billing/gateways/sage.rb +22 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +12 -0
- data/lib/active_merchant/billing/gateways/securion_pay.rb +2 -2
- data/lib/active_merchant/billing/gateways/stripe.rb +29 -8
- data/lib/active_merchant/billing/gateways/telr.rb +275 -0
- data/lib/active_merchant/billing/gateways/tns.rb +12 -230
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +1 -1
- data/lib/active_merchant/billing/gateways/vanco.rb +12 -8
- data/lib/active_merchant/billing/gateways/worldpay.rb +18 -0
- data/lib/active_merchant/country.rb +6 -2
- data/lib/active_merchant/version.rb +1 -1
- metadata +11 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1fe35e2a54670d5e8b4a1b03b60e0fbdb63b862e
|
|
4
|
+
data.tar.gz: 776d6fcde383b0ca43232791f8816ea573a21b3a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c4e2de0b7a0302afbbab9c6a486db123ac8228f83d3f7ea844ccd2108d80a79234627f2a9ce5824a9782c5eff560ef644aefea40d729564e97afb30d476946b
|
|
7
|
+
data.tar.gz: 2d259ac6111733da3f2d093f8638a5f2adcd8eb47a3adcce29197e37c4605daca606a2214ed274629872bdd5d6ba931acec991abfa1c398758941542d1b03963
|
data/CHANGELOG
CHANGED
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
= ActiveMerchant CHANGELOG
|
|
2
2
|
|
|
3
|
+
== Version 1.61.0 (November 7, 2016)
|
|
4
|
+
* Add codes AQ, BQ, SX, and SS to list of countries and update SD numeric code [zxlin]
|
|
5
|
+
* AuthorizeNet: Update supported countries list [shasum]
|
|
6
|
+
* Barclay SmartPay: Add support for credit [shasum]
|
|
7
|
+
* Barclaycard SmartPay: Update supported countries [shasum]
|
|
8
|
+
* BluePay: Add Canada to supported countries list [shasum]
|
|
9
|
+
* BlueSnap: Update countries list [shasum]
|
|
10
|
+
* Braintree Blue: Add Android Pay support [mrezentes]
|
|
11
|
+
* Braintree Blue: Add remote test to verify card token [shasum]
|
|
12
|
+
* Braintree Blue: Get Android Pay tx id from payment method, not options [mrezentes]
|
|
13
|
+
* CardStream: Add MXN currency code [curiousepic]
|
|
14
|
+
* CardStream: Set captureDelay to zero on purchase [davidsantoso]
|
|
15
|
+
* CitrusPay: Add gateway [duff]
|
|
16
|
+
* CitrusPay: Update URL to current API version [davidsantoso]
|
|
17
|
+
* Clearhaus: Fix refund of captures [duff]
|
|
18
|
+
* Clearhaus: Update list of non fractal currencies [curiousepic]
|
|
19
|
+
* Clearhaus: Use localized amount [curiouspic]
|
|
20
|
+
* Conekta: Add void action [MauricioMurga]
|
|
21
|
+
* Credorax: Add gateway support [davidsantoso]
|
|
22
|
+
* CyberSource, Paymill, Payflow: Add verify_credentials [duff]
|
|
23
|
+
* CyberSource: Combine auth_reversal with Void [curiousepic]
|
|
24
|
+
* CyberSource: Increase merchant defined data fields [davidsantoso]
|
|
25
|
+
* CyberSource: Look up alpha2 country code [curiousepic]
|
|
26
|
+
* CyberSource: Use localized_amount [curiousepic]
|
|
27
|
+
* Element: Pass order_id and shipping address [curiousepic]
|
|
28
|
+
* Fat Zebra: Add cavv, xid, and sli fields [curiousepic]
|
|
29
|
+
* Fat Zebra: Fix improper descriptor nesting [curiousepic]
|
|
30
|
+
* Find countries if they are differently cased [curiousepic]
|
|
31
|
+
* GlobalCollect: Update credit card brand list [curiousepic]
|
|
32
|
+
* Jetpay: Support endpoint for Canada [shasum]
|
|
33
|
+
* Linkpoint: Clean whitespace from PEM [curiousepic]
|
|
34
|
+
* Litle: Retain amount to send in auth reversals [curiousepic]
|
|
35
|
+
* Litle: add scrubbing support [bruno]
|
|
36
|
+
* MONEI: Update supported countries list [davidgf]
|
|
37
|
+
* MiGS: Handle IDR currency [curiousepic]
|
|
38
|
+
* Migs: Add support for void [mohsenottello]
|
|
39
|
+
* Migs: Support some additional fields [duff]
|
|
40
|
+
* Moneris: Fix unit test stubs [shasum]
|
|
41
|
+
* Moneris: add scrubbing support [bruno]
|
|
42
|
+
* NMI, FirstData: Support verify_credentials [curiousepic]
|
|
43
|
+
* Openpay: Add support for verify [duff]
|
|
44
|
+
* PayJunctionV2: Add gateway support [shasum]
|
|
45
|
+
* PayU Latam: Add new gateway [shasum]
|
|
46
|
+
* PayU Latam: Update supported countries list [shasum]
|
|
47
|
+
* Payflow: Update supported countries list [shasum]
|
|
48
|
+
* PaypalExpress: Add SoftDescriptor field [talyssonoc]
|
|
49
|
+
* Redsys: Added DOP and CRC currency [davidsantoso]
|
|
50
|
+
* Sage: Add support for scrubbing [bruno]
|
|
51
|
+
* SagePay: Fix truncation [duff]
|
|
52
|
+
* SecurionPay: Update supported countries list [shasum]
|
|
53
|
+
* Stripe: Increase authorize amount during verify [davidsantoso]
|
|
54
|
+
* Stripe: Set minimum authorize amount depending on currency [davidsantoso]
|
|
55
|
+
* Stripe: Support new network tokenization API params [methodmissing]
|
|
56
|
+
* Stripe: Update supported countries list [shasum]
|
|
57
|
+
* TNS and CitrusPay: Support scrub and verify_credentials [duff]
|
|
58
|
+
* TNS and CitrusPay: Update to version 36 of the API [duff]
|
|
59
|
+
* TNS: Try TLS v1 [duff]
|
|
60
|
+
* Telr: Add gateway support [curiousepic]
|
|
61
|
+
* TransFirsTransactionExpress: Remove blank cvv element [davidsantoso]
|
|
62
|
+
* TransFirsTransactionExpress: Take into account blank string CVV [davidsantoso]
|
|
63
|
+
* Vanco: Improve handling of success determination [duff]
|
|
64
|
+
* Worldpay: Add hcgAdditionalData element [davidsantoso]
|
|
65
|
+
* Worldpay: Report error code [curiousepic]
|
|
66
|
+
|
|
3
67
|
== Version 1.60.0 (July 4, 2016)
|
|
4
68
|
* Orbital: Fix CC num leak on profile calls [drewblas]
|
|
5
69
|
* VisaNetPeru: Add ability to refund [duff]
|
|
@@ -8,7 +8,7 @@ module ActiveMerchant
|
|
|
8
8
|
self.test_url = 'https://apitest.authorize.net/xml/v1/request.api'
|
|
9
9
|
self.live_url = 'https://api2.authorize.net/xml/v1/request.api'
|
|
10
10
|
|
|
11
|
-
self.supported_countries = %w(AD AT AU BE BG CA CH CY CZ DE DK EE ES FI FR GB GB GI GR HU IE IS IT LI LT LU LV MC MT NL NO PL PT RO SE SI SK SM TR US VA)
|
|
11
|
+
self.supported_countries = %w(AD AT AU BE BG CA CH CY CZ DE DK EE ES FI FR GB GB GI GR HU IE IL IS IT LI LT LU LV MC MT NL NO PL PT RO SE SI SK SM TR US VA)
|
|
12
12
|
self.default_currency = 'USD'
|
|
13
13
|
self.money_format = :dollars
|
|
14
14
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro]
|
|
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
|
|
|
4
4
|
self.test_url = 'https://pal-test.barclaycardsmartpay.com/pal/servlet'
|
|
5
5
|
self.live_url = 'https://pal-live.barclaycardsmartpay.com/pal/servlet'
|
|
6
6
|
|
|
7
|
-
self.supported_countries = ['
|
|
7
|
+
self.supported_countries = ['AL', 'AD', 'AM', 'AT', 'AZ', 'BY', 'BE', 'BA', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'GE', 'DE', 'GR', 'HU', 'IS', 'IE', 'IT', 'KZ', 'LV', 'LI', 'LT', 'LU', 'MK', 'MT', 'MD', 'MC', 'ME', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'SM', 'RS', 'SK', 'SI', 'ES', 'SE', 'CH', 'TR', 'UA', 'GB', 'VA']
|
|
8
8
|
self.default_currency = 'EUR'
|
|
9
9
|
self.money_format = :cents
|
|
10
10
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :dankort, :maestro]
|
|
@@ -62,6 +62,14 @@ module ActiveMerchant #:nodoc:
|
|
|
62
62
|
commit('refund', post)
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
+
def credit(money, creditcard, options = {})
|
|
66
|
+
post = payment_request(money, options)
|
|
67
|
+
post[:amount] = amount_hash(money, options[:currency])
|
|
68
|
+
post[:card] = credit_card_hash(creditcard)
|
|
69
|
+
|
|
70
|
+
commit('refundWithData', post)
|
|
71
|
+
end
|
|
72
|
+
|
|
65
73
|
def void(identification, options = {})
|
|
66
74
|
requires!(options, :order_id)
|
|
67
75
|
|
|
@@ -137,6 +145,8 @@ module ActiveMerchant #:nodoc:
|
|
|
137
145
|
case e.response.code
|
|
138
146
|
when '401'
|
|
139
147
|
return Response.new(false, 'Invalid credentials', {}, :test => test?)
|
|
148
|
+
when '403'
|
|
149
|
+
return Response.new(false, 'Not allowed', {}, :test => test?)
|
|
140
150
|
when '422'
|
|
141
151
|
return Response.new(false, 'Unprocessable Entity', {}, :test => test?)
|
|
142
152
|
when '500'
|
|
@@ -198,6 +208,7 @@ module ActiveMerchant #:nodoc:
|
|
|
198
208
|
def success_from(response)
|
|
199
209
|
return true if response.has_key?('authCode')
|
|
200
210
|
return true if response['result'] == 'Success'
|
|
211
|
+
return true if response['resultCode'] == 'Received'
|
|
201
212
|
successful_responses = %w([capture-received] [cancel-received] [refund-received])
|
|
202
213
|
successful_responses.include?(response['response'])
|
|
203
214
|
end
|
|
@@ -43,7 +43,7 @@ module ActiveMerchant #:nodoc:
|
|
|
43
43
|
'USUAL_DATE' => :undoc_usual_date, # Not found in the bp20rebadmin API doc.
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
self.supported_countries = ['US']
|
|
46
|
+
self.supported_countries = ['US', 'CA']
|
|
47
47
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
|
|
48
48
|
self.homepage_url = 'http://www.bluepay.com/'
|
|
49
49
|
self.display_name = 'BluePay'
|
|
@@ -5,7 +5,7 @@ module ActiveMerchant
|
|
|
5
5
|
class BlueSnapGateway < Gateway
|
|
6
6
|
self.test_url = "https://sandbox.bluesnap.com/services/2"
|
|
7
7
|
self.live_url = "https://ws.bluesnap.com/services/2"
|
|
8
|
-
self.supported_countries = %w(US GB)
|
|
8
|
+
self.supported_countries = %w(US CA GB AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT LV LT LU MT NL PL PT RO SK SI ES SE)
|
|
9
9
|
|
|
10
10
|
self.default_currency = 'USD'
|
|
11
11
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club, :maestro]
|
|
@@ -576,6 +576,14 @@ module ActiveMerchant #:nodoc:
|
|
|
576
576
|
:cardholder_name => "#{credit_card_or_vault_id.first_name} #{credit_card_or_vault_id.last_name}",
|
|
577
577
|
:cryptogram => credit_card_or_vault_id.payment_cryptogram
|
|
578
578
|
}
|
|
579
|
+
elsif credit_card_or_vault_id.source == :android_pay
|
|
580
|
+
parameters[:android_pay_card] = {
|
|
581
|
+
:number => credit_card_or_vault_id.number,
|
|
582
|
+
:cryptogram => credit_card_or_vault_id.payment_cryptogram,
|
|
583
|
+
:expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, "0"),
|
|
584
|
+
:expiration_year => credit_card_or_vault_id.year.to_s,
|
|
585
|
+
:google_transaction_id => credit_card_or_vault_id.transaction_id
|
|
586
|
+
}
|
|
579
587
|
end
|
|
580
588
|
else
|
|
581
589
|
parameters[:credit_card] = {
|
|
@@ -25,6 +25,7 @@ module ActiveMerchant #:nodoc:
|
|
|
25
25
|
"HKD" => "344",
|
|
26
26
|
"ICK" => "352",
|
|
27
27
|
"JPY" => "392",
|
|
28
|
+
"MXN" => "484",
|
|
28
29
|
"NOK" => "578",
|
|
29
30
|
"NZD" => "554",
|
|
30
31
|
"SEK" => "752",
|
|
@@ -87,6 +88,7 @@ module ActiveMerchant #:nodoc:
|
|
|
87
88
|
|
|
88
89
|
def purchase(money, credit_card_or_reference, options = {})
|
|
89
90
|
post = {}
|
|
91
|
+
add_pair(post, :captureDelay, 0)
|
|
90
92
|
add_amount(post, money, options)
|
|
91
93
|
add_invoice(post, credit_card_or_reference, money, options)
|
|
92
94
|
add_credit_card_or_reference(post, credit_card_or_reference)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module ActiveMerchant
|
|
2
|
+
module Billing
|
|
3
|
+
class CitrusPayGateway < Gateway
|
|
4
|
+
include MastercardGateway
|
|
5
|
+
|
|
6
|
+
class_attribute :live_na_url, :live_ap_url, :test_na_url, :test_ap_url
|
|
7
|
+
|
|
8
|
+
self.test_na_url = 'https://test-gateway.mastercard.com/api/rest/version/39/'
|
|
9
|
+
self.test_ap_url = 'https://test-gateway.mastercard.com/api/rest/version/39/'
|
|
10
|
+
|
|
11
|
+
self.live_na_url = 'https://na-gateway.mastercard.com/api/rest/version/39/'
|
|
12
|
+
self.live_ap_url = 'https://ap-gateway.mastercard.com/api/rest/version/39/'
|
|
13
|
+
|
|
14
|
+
self.display_name = 'Citrus Pay'
|
|
15
|
+
self.homepage_url = 'http://www.citruspay.com/'
|
|
16
|
+
self.supported_countries = %w(AR AU BR FR DE HK MX NZ SG GB US)
|
|
17
|
+
self.default_currency = 'USD'
|
|
18
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro, :laser]
|
|
19
|
+
self.ssl_version = :TLSv1
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
@@ -10,6 +10,7 @@ module ActiveMerchant #:nodoc:
|
|
|
10
10
|
'HU', 'IS', 'IE', 'IT', 'LV', 'LI', 'LT', 'LU', 'MT', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'GB']
|
|
11
11
|
|
|
12
12
|
self.default_currency = 'EUR'
|
|
13
|
+
self.currencies_without_fractions = %w(BIF BYR DJF GNF JPY KMF KRW PYG RWF VND VUV XAF XOF XPF)
|
|
13
14
|
self.supported_cardtypes = [:visa, :master]
|
|
14
15
|
|
|
15
16
|
self.homepage_url = 'https://www.clearhaus.com'
|
|
@@ -121,7 +122,7 @@ module ActiveMerchant #:nodoc:
|
|
|
121
122
|
end
|
|
122
123
|
|
|
123
124
|
def add_amount(post, amount, options)
|
|
124
|
-
post[:amount] =
|
|
125
|
+
post[:amount] = localized_amount(amount, options[:currency] || default_currency)
|
|
125
126
|
post[:currency] = (options[:currency] || default_currency)
|
|
126
127
|
end
|
|
127
128
|
|
|
@@ -173,7 +174,7 @@ module ActiveMerchant #:nodoc:
|
|
|
173
174
|
success_from(response),
|
|
174
175
|
message_from(response),
|
|
175
176
|
response,
|
|
176
|
-
authorization: authorization_from(response),
|
|
177
|
+
authorization: authorization_from(action, response),
|
|
177
178
|
test: test?,
|
|
178
179
|
error_code: error_code_from(response)
|
|
179
180
|
)
|
|
@@ -193,8 +194,15 @@ module ActiveMerchant #:nodoc:
|
|
|
193
194
|
end
|
|
194
195
|
end
|
|
195
196
|
|
|
196
|
-
def authorization_from(response)
|
|
197
|
-
response['id']
|
|
197
|
+
def authorization_from(action, response)
|
|
198
|
+
id_of_auth_for_capture(action) || response['id']
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def id_of_auth_for_capture(action)
|
|
202
|
+
match = action.match(/authorizations\/(.+)\/captures/)
|
|
203
|
+
return nil unless match
|
|
204
|
+
|
|
205
|
+
match.captures.first
|
|
198
206
|
end
|
|
199
207
|
|
|
200
208
|
def generate_signature(body)
|
|
@@ -12,7 +12,7 @@ module ActiveMerchant #:nodoc:
|
|
|
12
12
|
|
|
13
13
|
def initialize(options = {})
|
|
14
14
|
requires!(options, :key)
|
|
15
|
-
options[:version] ||= '0.
|
|
15
|
+
options[:version] ||= '1.0.0'
|
|
16
16
|
super
|
|
17
17
|
end
|
|
18
18
|
|
|
@@ -55,6 +55,11 @@ module ActiveMerchant #:nodoc:
|
|
|
55
55
|
commit(:post, "charges/#{identifier}/refund", post)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
+
def void(identifier, options = {})
|
|
59
|
+
post = {}
|
|
60
|
+
commit(:post, "charges/#{identifier}/void", post)
|
|
61
|
+
end
|
|
62
|
+
|
|
58
63
|
def supports_scrubbing
|
|
59
64
|
true
|
|
60
65
|
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
|
2
|
+
module Billing #:nodoc:
|
|
3
|
+
class CredoraxGateway < Gateway
|
|
4
|
+
class_attribute :test_url, :live_na_url, :live_eu_url
|
|
5
|
+
|
|
6
|
+
self.display_name = "Credorax Gateway"
|
|
7
|
+
self.homepage_url = "https://www.credorax.com/"
|
|
8
|
+
|
|
9
|
+
self.test_url = "https://intconsole.credorax.com/intenv/service/gateway"
|
|
10
|
+
|
|
11
|
+
# The live URL is assigned on a per merchant basis once certification has passed
|
|
12
|
+
# See the Credorax remote tests for the full certification test suite
|
|
13
|
+
#
|
|
14
|
+
# Once you have your assigned subdomain, you can override the live URL in your application via:
|
|
15
|
+
# ActiveMerchant::Billing::CredoraxGateway.live_url = "https://assigned-subdomain.credorax.net/crax_gate/service/gateway"
|
|
16
|
+
self.live_url = 'https://assigned-subdomain.credorax.net/crax_gate/service/gateway'
|
|
17
|
+
|
|
18
|
+
self.supported_countries = %w(DE GB FR IT ES PL NL BE GR CZ PT SE HU RS AT CH BG DK FI SK NO IE HR BA AL LT MK SI LV EE ME LU MT IS AD MC LI SM)
|
|
19
|
+
self.default_currency = "EUR"
|
|
20
|
+
self.money_format = :cents
|
|
21
|
+
self.supported_cardtypes = [:visa, :master, :maestro]
|
|
22
|
+
|
|
23
|
+
def initialize(options={})
|
|
24
|
+
requires!(options, :merchant_id, :cipher_key)
|
|
25
|
+
super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def purchase(amount, payment_method, options={})
|
|
29
|
+
post = {}
|
|
30
|
+
add_invoice(post, amount, options)
|
|
31
|
+
add_payment_method(post, payment_method)
|
|
32
|
+
add_customer_data(post, options)
|
|
33
|
+
add_email(post, options)
|
|
34
|
+
add_echo(post, options)
|
|
35
|
+
|
|
36
|
+
commit(:purchase, post)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def authorize(amount, payment_method, options={})
|
|
40
|
+
post = {}
|
|
41
|
+
add_invoice(post, amount, options)
|
|
42
|
+
add_payment_method(post, payment_method)
|
|
43
|
+
add_customer_data(post, options)
|
|
44
|
+
add_email(post, options)
|
|
45
|
+
add_echo(post, options)
|
|
46
|
+
|
|
47
|
+
commit(:authorize, post)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def capture(amount, authorization, options={})
|
|
51
|
+
post = {}
|
|
52
|
+
add_invoice(post, amount, options)
|
|
53
|
+
add_reference(post, authorization)
|
|
54
|
+
add_customer_data(post, options)
|
|
55
|
+
add_echo(post, options)
|
|
56
|
+
|
|
57
|
+
commit(:capture, post)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def void(authorization, options={})
|
|
61
|
+
post = {}
|
|
62
|
+
add_customer_data(post, options)
|
|
63
|
+
reference_action = add_reference(post, authorization)
|
|
64
|
+
add_echo(post, options)
|
|
65
|
+
post[:a1] = options[:order_id] || generate_unique_id
|
|
66
|
+
|
|
67
|
+
commit(:void, post, reference_action)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def refund(amount, authorization, options={})
|
|
71
|
+
post = {}
|
|
72
|
+
add_invoice(post, amount, options)
|
|
73
|
+
add_reference(post, authorization)
|
|
74
|
+
add_customer_data(post, options)
|
|
75
|
+
add_echo(post, options)
|
|
76
|
+
|
|
77
|
+
commit(:refund, post)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def credit(amount, payment_method, options={})
|
|
81
|
+
post = {}
|
|
82
|
+
add_invoice(post, amount, options)
|
|
83
|
+
add_payment_method(post, payment_method)
|
|
84
|
+
add_customer_data(post, options)
|
|
85
|
+
add_email(post, options)
|
|
86
|
+
add_echo(post, options)
|
|
87
|
+
|
|
88
|
+
commit(:credit, post)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def verify(credit_card, options={})
|
|
92
|
+
MultiResponse.run(:use_first_response) do |r|
|
|
93
|
+
r.process { authorize(100, credit_card, options) }
|
|
94
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def supports_scrubbing?
|
|
99
|
+
true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def scrub(transcript)
|
|
103
|
+
transcript.
|
|
104
|
+
gsub(%r((b1=)\d+), '\1[FILTERED]').
|
|
105
|
+
gsub(%r((b5=)\d+), '\1[FILTERED]')
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
def add_invoice(post, money, options)
|
|
111
|
+
post[:a4] = amount(money)
|
|
112
|
+
post[:a1] = options[:order_id] || generate_unique_id
|
|
113
|
+
post[:a5] = options[:currency] || currency(money)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
CARD_TYPES = {
|
|
117
|
+
"visa" => '1',
|
|
118
|
+
"mastercard" => '2',
|
|
119
|
+
"maestro" => '9'
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
def add_payment_method(post, payment_method)
|
|
123
|
+
post[:c1] = payment_method.name
|
|
124
|
+
post[:b2] = CARD_TYPES[payment_method.brand] || ''
|
|
125
|
+
post[:b1] = payment_method.number
|
|
126
|
+
post[:b5] = payment_method.verification_value
|
|
127
|
+
post[:b4] = format(payment_method.year, :two_digits)
|
|
128
|
+
post[:b3] = format(payment_method.month, :two_digits)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def add_customer_data(post, options)
|
|
132
|
+
post[:d1] = options[:ip] || '127.0.0.1'
|
|
133
|
+
if (billing_address = options[:billing_address])
|
|
134
|
+
# Credorax has separate fields for street number and street name
|
|
135
|
+
post[:c4] = billing_address[:address1].split.first
|
|
136
|
+
post[:c5] = billing_address[:address1].split.drop(1).join(" ")
|
|
137
|
+
post[:c7] = billing_address[:city]
|
|
138
|
+
post[:c10] = billing_address[:zip]
|
|
139
|
+
post[:c8] = billing_address[:state]
|
|
140
|
+
post[:c9] = billing_address[:country]
|
|
141
|
+
post[:c2] = billing_address[:phone]
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def add_reference(post, authorization)
|
|
146
|
+
response_id, authorization_code, request_id, action = authorization.split(";")
|
|
147
|
+
post[:g2] = response_id
|
|
148
|
+
post[:g3] = authorization_code
|
|
149
|
+
post[:g4] = request_id
|
|
150
|
+
action || :authorize
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def add_email(post, options)
|
|
154
|
+
post[:c3] = options[:email] || 'unspecified@example.com'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def add_echo(post, options)
|
|
158
|
+
# The d2 parameter is used during the certification process
|
|
159
|
+
# See remote tests for full certification test suite
|
|
160
|
+
post[:d2] = options[:echo] unless options[:echo].blank?
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
ACTIONS = {
|
|
164
|
+
purchase: '1',
|
|
165
|
+
authorize: '2',
|
|
166
|
+
capture: '3',
|
|
167
|
+
authorize_void:'4',
|
|
168
|
+
refund: '5',
|
|
169
|
+
credit: '6',
|
|
170
|
+
purchase_void: '7',
|
|
171
|
+
refund_void: '8',
|
|
172
|
+
capture_void: '9'
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
def commit(action, params, reference_action = nil)
|
|
176
|
+
raw_response = ssl_post(url, post_data(action, params, reference_action))
|
|
177
|
+
response = parse(raw_response)
|
|
178
|
+
|
|
179
|
+
Response.new(
|
|
180
|
+
success_from(response),
|
|
181
|
+
message_from(response),
|
|
182
|
+
response,
|
|
183
|
+
authorization: "#{response["Z1"]};#{response["Z4"]};#{response["A1"]};#{action}",
|
|
184
|
+
avs_result: AVSResult.new(code: response["Z9"]),
|
|
185
|
+
cvv_result: CVVResult.new(response["Z14"]),
|
|
186
|
+
test: test?
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def sign_request(params)
|
|
191
|
+
params = params.sort
|
|
192
|
+
params.each { |param| param[1].gsub!(/[<>()\\]/, ' ') }
|
|
193
|
+
values = params.map { |param| param[1].strip }
|
|
194
|
+
Digest::MD5.hexdigest(values.join + @options[:cipher_key])
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def post_data(action, params, reference_action)
|
|
198
|
+
params.keys.each { |key| params[key] = params[key].to_s}
|
|
199
|
+
params[:M] = @options[:merchant_id]
|
|
200
|
+
params[:O] = request_action(action, reference_action)
|
|
201
|
+
params[:K] = sign_request(params)
|
|
202
|
+
params.map {|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def request_action(action, reference_action)
|
|
206
|
+
if reference_action
|
|
207
|
+
ACTIONS["#{reference_action}_#{action}".to_sym]
|
|
208
|
+
else
|
|
209
|
+
ACTIONS[action]
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def url
|
|
214
|
+
test? ? test_url : live_url
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def parse(body)
|
|
218
|
+
Hash[CGI::parse(body).map{|k,v| [k.upcase,v.first]}]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def success_from(response)
|
|
222
|
+
response["Z2"] == "0"
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def message_from(response)
|
|
226
|
+
if success_from(response)
|
|
227
|
+
"Succeeded"
|
|
228
|
+
else
|
|
229
|
+
response["Z3"] || "Unable to read error message"
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|