activemerchant 1.121.0 → 1.123.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 +86 -0
- data/README.md +1 -1
- data/lib/active_merchant/billing/check.rb +13 -16
- data/lib/active_merchant/billing/credit_card.rb +3 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +1 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +21 -12
- data/lib/active_merchant/billing/gateways/adyen.rb +15 -19
- data/lib/active_merchant/billing/gateways/authorize_net.rb +10 -8
- data/lib/active_merchant/billing/gateways/blue_pay.rb +29 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +2 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +6 -3
- data/lib/active_merchant/billing/gateways/credorax.rb +2 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +30 -3
- data/lib/active_merchant/billing/gateways/decidir.rb +7 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +60 -28
- data/lib/active_merchant/billing/gateways/element.rb +2 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +19 -10
- data/lib/active_merchant/billing/gateways/kushki.rb +23 -0
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +3 -2
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -0
- data/lib/active_merchant/billing/gateways/moka.rb +277 -0
- data/lib/active_merchant/billing/gateways/monei.rb +228 -144
- data/lib/active_merchant/billing/gateways/mundipagg.rb +14 -5
- data/lib/active_merchant/billing/gateways/nmi.rb +14 -9
- data/lib/active_merchant/billing/gateways/orbital.rb +28 -6
- data/lib/active_merchant/billing/gateways/pay_arc.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_trace.rb +404 -0
- data/lib/active_merchant/billing/gateways/payeezy.rb +4 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +9 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/paymentez.rb +5 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +291 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -3
- data/lib/active_merchant/billing/gateways/redsys.rb +35 -32
- data/lib/active_merchant/billing/gateways/safe_charge.rb +2 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +13 -4
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +19 -1
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +1 -1
- data/lib/active_merchant/billing/gateways/vpos.rb +49 -6
- data/lib/active_merchant/billing/gateways/worldpay.rb +39 -7
- data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
- data/lib/active_merchant/billing.rb +1 -0
- data/lib/active_merchant/version.rb +1 -1
- metadata +8 -3
@@ -40,7 +40,7 @@ module ActiveMerchant #:nodoc:
|
|
40
40
|
add_shipping_address(post, options)
|
41
41
|
add_payment(post, payment, options)
|
42
42
|
add_submerchant(post, options)
|
43
|
-
|
43
|
+
add_auth_key(post, options)
|
44
44
|
commit('sale', post)
|
45
45
|
end
|
46
46
|
|
@@ -52,6 +52,7 @@ module ActiveMerchant #:nodoc:
|
|
52
52
|
add_payment(post, payment, options)
|
53
53
|
add_capture_flag(post, payment)
|
54
54
|
add_submerchant(post, options)
|
55
|
+
add_auth_key(post, options)
|
55
56
|
commit('authonly', post)
|
56
57
|
end
|
57
58
|
|
@@ -229,9 +230,16 @@ module ActiveMerchant #:nodoc:
|
|
229
230
|
end
|
230
231
|
end
|
231
232
|
|
232
|
-
def
|
233
|
+
def add_auth_key(post, options)
|
234
|
+
if authorization_secret_key = options[:authorization_secret_key]
|
235
|
+
post[:authorization_secret_key] = authorization_secret_key
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def headers(authorization_secret_key = nil)
|
240
|
+
basic_token = authorization_secret_key || @options[:api_key]
|
233
241
|
{
|
234
|
-
'Authorization' => 'Basic ' + Base64.strict_encode64("#{
|
242
|
+
'Authorization' => 'Basic ' + Base64.strict_encode64("#{basic_token}:"),
|
235
243
|
'Content-Type' => 'application/json',
|
236
244
|
'Accept' => 'application/json'
|
237
245
|
}
|
@@ -259,11 +267,12 @@ module ActiveMerchant #:nodoc:
|
|
259
267
|
|
260
268
|
def commit(action, parameters, auth = nil)
|
261
269
|
url = url_for(action, auth)
|
270
|
+
authorization_secret_key = parameters[:authorization_secret_key] if parameters
|
262
271
|
parameters.merge!(parameters[:payment][:credit_card].delete(:card)).delete(:payment) if action == 'store'
|
263
272
|
response = if %w[refund void].include? action
|
264
|
-
parse(ssl_request(:delete, url, post_data(parameters), headers))
|
273
|
+
parse(ssl_request(:delete, url, post_data(parameters), headers(authorization_secret_key)))
|
265
274
|
else
|
266
|
-
parse(ssl_post(url, post_data(parameters), headers))
|
275
|
+
parse(ssl_post(url, post_data(parameters), headers(authorization_secret_key)))
|
267
276
|
end
|
268
277
|
|
269
278
|
Response.new(
|
@@ -251,15 +251,20 @@ module ActiveMerchant #:nodoc:
|
|
251
251
|
end
|
252
252
|
|
253
253
|
def add_three_d_secure(post, options)
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
254
|
+
three_d_secure = options[:three_d_secure]
|
255
|
+
return unless three_d_secure
|
256
|
+
|
257
|
+
post[:cardholder_auth] = cardholder_auth(three_d_secure[:authentication_response_status])
|
258
|
+
post[:cavv] = three_d_secure[:cavv]
|
259
|
+
post[:xid] = three_d_secure[:xid]
|
260
|
+
post[:three_ds_version] = three_d_secure[:version]
|
261
|
+
post[:directory_server_id] = three_d_secure[:ds_transaction_id]
|
262
|
+
end
|
263
|
+
|
264
|
+
def cardholder_auth(trans_status)
|
265
|
+
return nil if trans_status.nil?
|
266
|
+
|
267
|
+
trans_status == 'Y' ? 'verified' : 'attempted'
|
263
268
|
end
|
264
269
|
|
265
270
|
def add_reference(post, authorization)
|
@@ -42,6 +42,7 @@ module ActiveMerchant #:nodoc:
|
|
42
42
|
}
|
43
43
|
|
44
44
|
SUCCESS = '0'
|
45
|
+
APPROVAL_SUCCESS = '1'
|
45
46
|
|
46
47
|
APPROVED = [
|
47
48
|
'00', # Approved
|
@@ -334,7 +335,9 @@ module ActiveMerchant #:nodoc:
|
|
334
335
|
gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
|
335
336
|
gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
|
336
337
|
gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2').
|
337
|
-
gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2')
|
338
|
+
gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2').
|
339
|
+
gsub(%r((<CheckDDA>).+(</CheckDDA>)), '\1[FILTERED]\2').
|
340
|
+
gsub(%r((<BCRtNum>).+(</BCRtNum>)), '\1[FILTERED]\2')
|
338
341
|
end
|
339
342
|
|
340
343
|
private
|
@@ -602,8 +605,10 @@ module ActiveMerchant #:nodoc:
|
|
602
605
|
|
603
606
|
def add_mc_program_protocol(xml, creditcard, three_d_secure)
|
604
607
|
return unless three_d_secure && creditcard.brand == 'master'
|
608
|
+
return unless three_d_secure[:version]
|
605
609
|
|
606
|
-
|
610
|
+
truncated_version = three_d_secure[:version].to_s[0]
|
611
|
+
xml.tag!(:MCProgramProtocol, truncated_version)
|
607
612
|
end
|
608
613
|
|
609
614
|
def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
|
@@ -612,12 +617,20 @@ module ActiveMerchant #:nodoc:
|
|
612
617
|
xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
|
613
618
|
end
|
614
619
|
|
615
|
-
def
|
620
|
+
def add_mc_ucafind(xml, creditcard, three_d_secure)
|
616
621
|
return unless three_d_secure && creditcard.brand == 'master'
|
617
622
|
|
618
623
|
xml.tag! :UCAFInd, '4'
|
619
624
|
end
|
620
625
|
|
626
|
+
def add_mc_scarecurring(xml, creditcard, parameters, three_d_secure)
|
627
|
+
return unless parameters && parameters[:sca_recurring] && creditcard.brand == 'master'
|
628
|
+
|
629
|
+
valid_eci = three_d_secure && three_d_secure[:eci] && three_d_secure[:eci] == '7'
|
630
|
+
|
631
|
+
xml.tag!(:SCARecurringPayment, parameters[:sca_recurring]) if valid_eci
|
632
|
+
end
|
633
|
+
|
621
634
|
def add_dpanind(xml, creditcard)
|
622
635
|
return unless creditcard.is_a?(NetworkTokenizationCreditCard)
|
623
636
|
|
@@ -745,7 +758,7 @@ module ActiveMerchant #:nodoc:
|
|
745
758
|
|
746
759
|
def parse(body)
|
747
760
|
response = {}
|
748
|
-
xml = REXML::Document.new(body)
|
761
|
+
xml = REXML::Document.new(strip_invalid_xml_chars(body))
|
749
762
|
root = REXML::XPath.first(xml, '//Response') ||
|
750
763
|
REXML::XPath.first(xml, '//ErrorResponse')
|
751
764
|
if root
|
@@ -799,8 +812,10 @@ module ActiveMerchant #:nodoc:
|
|
799
812
|
end
|
800
813
|
|
801
814
|
def success?(response, message_type)
|
802
|
-
if %i[
|
815
|
+
if %i[void].include?(message_type)
|
803
816
|
response[:proc_status] == SUCCESS
|
817
|
+
elsif %i[refund].include?(message_type)
|
818
|
+
response[:proc_status] == SUCCESS && response[:approval_status] == APPROVAL_SUCCESS
|
804
819
|
elsif response[:customer_profile_action]
|
805
820
|
response[:profile_proc_status] == SUCCESS
|
806
821
|
else
|
@@ -884,9 +899,10 @@ module ActiveMerchant #:nodoc:
|
|
884
899
|
add_card_indicators(xml, parameters)
|
885
900
|
add_stored_credentials(xml, parameters)
|
886
901
|
add_pymt_brand_program_code(xml, payment_source, three_d_secure)
|
902
|
+
add_mc_scarecurring(xml, payment_source, parameters, three_d_secure)
|
887
903
|
add_mc_program_protocol(xml, payment_source, three_d_secure)
|
888
904
|
add_mc_directory_trans_id(xml, payment_source, three_d_secure)
|
889
|
-
|
905
|
+
add_mc_ucafind(xml, payment_source, three_d_secure)
|
890
906
|
end
|
891
907
|
end
|
892
908
|
xml.target!
|
@@ -985,6 +1001,12 @@ module ActiveMerchant #:nodoc:
|
|
985
1001
|
options[:billing_address] || options[:address]
|
986
1002
|
end
|
987
1003
|
|
1004
|
+
# Null characters are possible in some responses (namely, the respMsg field), causing XML parsing errors
|
1005
|
+
# Prevent by substituting these with a valid placeholder string
|
1006
|
+
def strip_invalid_xml_chars(xml)
|
1007
|
+
xml.gsub(/\u0000/, '[null]')
|
1008
|
+
end
|
1009
|
+
|
988
1010
|
# The valid characters include:
|
989
1011
|
#
|
990
1012
|
# 1. all letters and digits
|
@@ -0,0 +1,390 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PayArcGateway < Gateway
|
4
|
+
self.test_url = 'https://testapi.payarc.net/v1'
|
5
|
+
self.live_url = 'https://api.payarc.net/v1'
|
6
|
+
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.default_currency = 'usd'
|
9
|
+
self.supported_cardtypes = %i[visa master american_express discover jcb]
|
10
|
+
|
11
|
+
self.homepage_url = 'https://www.payarc.net/'
|
12
|
+
self.display_name = 'PAYARC Gateway'
|
13
|
+
|
14
|
+
STANDARD_ERROR_CODE_MAPPING = {}
|
15
|
+
STANDARD_ACTIONS = {
|
16
|
+
token:
|
17
|
+
{ end_point: 'tokens',
|
18
|
+
allowed_fields: %i[card_source card_number exp_month exp_year cvv card_holder_name
|
19
|
+
address_line1 address_line2 city state zip country] },
|
20
|
+
capture:
|
21
|
+
{ end_point: 'charges',
|
22
|
+
allowed_fields: %i[amount statement_description card_id currency customer_id token_id card_source tip_amount
|
23
|
+
card_level sales_tax purchase_order supplier_reference_number customer_ref_id ship_to_zip
|
24
|
+
amex_descriptor customer_vat_number summary_commodity_code shipping_charges duty_charges
|
25
|
+
ship_from_zip destination_country_code vat_invoice order_date tax_category tax_type
|
26
|
+
tax_amount tax_rate address_line1 zip terminal_id surcharge description email receipt_phone statement_descriptor ] },
|
27
|
+
void:
|
28
|
+
{ end_point: 'charges/{{chargeID}}/void',
|
29
|
+
allowed_fields: %i[reason void_description] },
|
30
|
+
refund:
|
31
|
+
{ end_point: 'charges/{{charge_id}}/refunds',
|
32
|
+
allowed_fields: %i[amount reason description] },
|
33
|
+
credit:
|
34
|
+
{ end_point: 'refunds/wo_reference',
|
35
|
+
allowed_fields: %i[amount charge_description statement_description terminal_id card_source card_number
|
36
|
+
exp_month exp_year cvv card_holder_name address_line1 address_line2 city state zip
|
37
|
+
country currency reason receipt_phone receipt_email ] }
|
38
|
+
}
|
39
|
+
|
40
|
+
SUCCESS_STATUS = %w[
|
41
|
+
submitted_for_settlement authorized partially_submitted_for_settlement
|
42
|
+
credit partial_refund void refunded settled
|
43
|
+
]
|
44
|
+
|
45
|
+
FAILURE_STATUS = %w[not_processed failed_by_gateway invalid_track_data authorization_expired]
|
46
|
+
|
47
|
+
# The gateway must be configured with Bearer token.
|
48
|
+
#
|
49
|
+
# <tt>:api_key</tt> PAYARC's Bearer token must be passsed to initialise the gateway.
|
50
|
+
|
51
|
+
def initialize(options = {})
|
52
|
+
requires!(options, :api_key)
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Purchase API through PAYARC.
|
58
|
+
#
|
59
|
+
# <tt>:money</tt> A positive integer in cents representing how much to charge. The minimum amount is 50c USD.
|
60
|
+
#
|
61
|
+
# <tt>:creditcard</tt> <tt>CreditCard</tt> object with card details.
|
62
|
+
#
|
63
|
+
# <tt>:options</tt> Other information like address, card source etc can be passed in options
|
64
|
+
#
|
65
|
+
# ==== Options
|
66
|
+
#
|
67
|
+
# * <tt>:card_source </tt> -- Source of payment (REQUIRED) ( INTERNET, SWIPE, PHONE, MAIL, MANUAL )
|
68
|
+
# * <tt>:currency </tt> -- Three-letter ISO currency code, in lowercase (REQUIRED)
|
69
|
+
# * <tt>:card_holder_name</tt> --Name of the Card Holder (OPTIONAL)
|
70
|
+
# * <tt>:address_line1</tt> -- Set in payment method's billing address (OPTIONAL)
|
71
|
+
# * <tt>:address_line2</tt> -- Set in payment method's billing address (OPTIONAL)
|
72
|
+
# * <tt>:state </tt> -- State (OPTIONAL)
|
73
|
+
# * <tt>:country </tt> -- Country (OPTIONAL)
|
74
|
+
# * <tt>:statement_description </tt> -- An arbitrary string to be displayed on your costomer's credit card statement. This may be up to 22 characters. (OPTIONAL)
|
75
|
+
# * <tt> :card_level </tt> -- Commercial card level - "LEVEL2" OR "LEVEL3" (OPTIONAL)
|
76
|
+
# * <tt> :sales_tax </tt> -- A positive integer in cents representing sales tax. (OPTIONAL)
|
77
|
+
# * <tt> :terminal_id </tt> -- Optional terminal id. (OPTIONAL)
|
78
|
+
# * <tt> :tip_amount </tt> -- A positive integer in cents representing tip amount. (OPTIONAL)
|
79
|
+
# * <tt> :sales_tax </tt> -- Applicable for LEVEL2 or LEVEL3 Charge. A positive integer in cents representing sales tax. (REQUIRED for LEVEL2 0r LEVEL3)
|
80
|
+
# * <tt> :purchase_order </tt> -- Applicable for Level2 or Level3 Charge. The value used by the customer to identify an order. Issued by the buyer to the seller. (REQUIRED for LEVEL2 0r LEVEL3)
|
81
|
+
# * <tt> :order_date </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 Charge. The date the order was processed. Format: Alphanumeric and Special Character |Min Length=0 Max Length=10|Allowed format: MM/DD/YYYY For example: 12/01/2016
|
82
|
+
# * <tt> :customer_ref_id </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 Charge. The reference identifier supplied by the Commercial Card cardholder. Format: Alphanumeric and Special Character |Min Length=0 Max Length=17| a-z A-Z 0-9 Space <>
|
83
|
+
# * <tt> :ship_to_zip </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 Charge. The postal code for the address to which the goods are being shipped. Format: Alphanumeric |Min Length=2 Max Length=10
|
84
|
+
# * <tt> :amex_descriptor </tt> -- Applicable for Level2 Charge for AMEX card only. The value of the Transaction Advice Addendum field, displays descriptive information about a transactions on a customer's AMEX card statement. Format: Alphanumeric and Special Character |Min Length=0 Max Length=40|a-z A-Z 0-9 Space <>
|
85
|
+
# * <tt> :supplier_reference_number </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 charge. The value used by the customer to identify an order. Issued by the buyer to the seller.
|
86
|
+
# * <tt> :tax_amount </tt> -- Applicable for Level3 Charge. The tax amount. Format: Numeric|Max Length=12|Allowed characters: 0-9 .(dot) Note: If a decimal point is included, the amount reflects a dollar value. If a decimal point is not included, the amount reflects a cent value.
|
87
|
+
# * <tt> :tax_category </tt> -- Applicable for Level3 Charge. The type of tax. Formerly established through TaxCategory messages. Allowed values: SERVICE, DUTY, VAT, ALTERNATE, NATIONAL, TAX_EXEMPT
|
88
|
+
# * <tt> :customer_vat_number </tt> -- Applicable for Level3 Charge. Indicates the customer's government assigned tax identification number or the identification number assigned to their purchasing company by the tax authorities. Format: Alphanumeric and Special Character|Min Length=0 Max Length=13| a-z A-Z 0-9 Space <>
|
89
|
+
# * <tt> :summary_commodity_code </tt> -- Applicable for Level3 Charge. The international description code of the overall goods or services being supplied. Format: Alphanumeric and Special Character |Min Length=0 Max Length=4|Allowed character: a-z A-Z 0-9 Space <>
|
90
|
+
# * <tt> :shipping_charges </tt> -- Applicable for Level3 Charge. The dollar amount for shipping or freight charges applied to a product or transaction. Format: Numeric |Max Length=12|Allowed characters: 0-9 .(dot) Note: If a decimal point is included, the amount reflects a dollar value. If a decimal point is not included, the amount reflects a cent value.
|
91
|
+
# * <tt> :duty_charges </tt> -- Applicable for Level3 Charge. Indicates the total charges for any import or export duties included in the order. Format: Numeric |Max Length=12|Allowed characters: 0-9 . (dot) Note: If a decimal point is included, the amount reflects a dollar value. If a decimal point is not included, the amount reflects a cent value.
|
92
|
+
# * <tt> :ship_from_zip </tt> -- Applicable for Level3 Charge. The postal code for the address to which the goods are being shipped. Format: Alphanumeric |Min Length=2 Max Length=10
|
93
|
+
# * <tt> :destination_country_code </tt> -- Applicable for Level3 Charge. The destination country code indicator. Format: Alphanumeric.
|
94
|
+
# * <tt> :tax_type </tt> -- Applicable for Level3 Charge. The type of tax. For example, VAT, NATIONAL, Service Tax. Format: Alphanumeric and Special Character
|
95
|
+
# * <tt> :vat_invoice </tt> -- Applicable for Level3 Charge. The Value Added Tax (VAT) invoice number associated with the transaction. Format: Alphanumeric and Special Character |Min Length=0 Max Length=15|Allowed character: a-z A-Z 0-9 Space <>
|
96
|
+
# * <tt> :tax_rate </tt> -- Applicable for Level3 Charge. The type of tax rate. This field is used if taxCategory is not used. Default sale tax rate in percentage Must be between 0.1% - 22% ,Applicable only Level 2 AutoFill. Format: Decimal Number |Max Length=4|Allowed characters: 0-9 .(dot) Allowed range: 0.01 - 100
|
97
|
+
# * <tt> :email </tt> -- Customer's email address sent with payment method.
|
98
|
+
|
99
|
+
def purchase(money, creditcard, options = {})
|
100
|
+
options[:capture] = 1
|
101
|
+
MultiResponse.run do |r|
|
102
|
+
r.process { token(creditcard, options) }
|
103
|
+
r.process { charge(money, r.authorization, options) }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Authorize the payment API through PAYARC.
|
109
|
+
#
|
110
|
+
# <tt>:money</tt> A positive integer in cents representing how much to charge. The minimum amount is 50c USD.
|
111
|
+
#
|
112
|
+
# <tt>:creditcard</tt> <tt>CreditCard</tt> object with card details.
|
113
|
+
#
|
114
|
+
# <tt>:options</tt> Other information like address, card source etc can be passed in options
|
115
|
+
#
|
116
|
+
# ==== Options
|
117
|
+
#
|
118
|
+
# * <tt>:card_source </tt> -- Source of payment (REQUIRED) ( INTERNET, SWIPE, PHONE, MAIL, MANUAL )
|
119
|
+
# * <tt>:currency </tt> -- Three-letter ISO currency code, in lowercase (REQUIRED)
|
120
|
+
# * <tt>:card_holder_name</tt> --Name of the Card Holder (OPTIONAL)
|
121
|
+
# * <tt>:address_line1</tt> -- Set in payment method's billing address (OPTIONAL)
|
122
|
+
# * <tt>:address_line2</tt> -- Set in payment method's billing address (OPTIONAL)
|
123
|
+
# * <tt>:state </tt> -- State (OPTIONAL)
|
124
|
+
# * <tt>:country </tt> -- Country (OPTIONAL)
|
125
|
+
# * <tt>:statement_description </tt> -- An arbitrary string to be displayed on your costomer's credit card statement. This may be up to 22 characters. (OPTIONAL)
|
126
|
+
# * <tt> :card_level </tt> -- Commercial card level - "LEVEL2" OR "LEVEL3" (OPTIONAL)
|
127
|
+
# * <tt> :sales_tax </tt> -- A positive integer in cents representing sales tax. (OPTIONAL)
|
128
|
+
# * <tt> :terminal_id </tt> -- Optional terminal id. (OPTIONAL)
|
129
|
+
# * <tt> :tip_amount </tt> -- A positive integer in cents representing tip amount. (OPTIONAL)
|
130
|
+
# * <tt> :sales_tax </tt> -- Applicable for LEVEL2 or LEVEL3 Charge. A positive integer in cents representing sales tax. (REQUIRED for LEVEL2 0r LEVEL3)
|
131
|
+
# * <tt> :purchase_order </tt> -- Applicable for Level2 or Level3 Charge. The value used by the customer to identify an order. Issued by the buyer to the seller. (REQUIRED for LEVEL2 0r LEVEL3)
|
132
|
+
# * <tt> :order_date </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 Charge. The date the order was processed. Format: Alphanumeric and Special Character |Min Length=0 Max Length=10|Allowed format: MM/DD/YYYY For example: 12/01/2016
|
133
|
+
# * <tt> :customer_ref_id </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 Charge. The reference identifier supplied by the Commercial Card cardholder. Format: Alphanumeric and Special Character |Min Length=0 Max Length=17| a-z A-Z 0-9 Space <>
|
134
|
+
# * <tt> :ship_to_zip </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 Charge. The postal code for the address to which the goods are being shipped. Format: Alphanumeric |Min Length=2 Max Length=10
|
135
|
+
# * <tt> :amex_descriptor </tt> -- Applicable for Level2 Charge for AMEX card only. The value of the Transaction Advice Addendum field, displays descriptive information about a transactions on a customer's AMEX card statement. Format: Alphanumeric and Special Character |Min Length=0 Max Length=40|a-z A-Z 0-9 Space <>
|
136
|
+
# * <tt> :supplier_reference_number </tt> -- Applicable for Level2 Charge for AMEX card only or Level3 charge. The value used by the customer to identify an order. Issued by the buyer to the seller.
|
137
|
+
# * <tt> :tax_amount </tt> -- Applicable for Level3 Charge. The tax amount. Format: Numeric|Max Length=12|Allowed characters: 0-9 .(dot) Note: If a decimal point is included, the amount reflects a dollar value. If a decimal point is not included, the amount reflects a cent value.
|
138
|
+
# * <tt> :tax_category </tt> -- Applicable for Level3 Charge. The type of tax. Formerly established through TaxCategory messages. Allowed values: SERVICE, DUTY, VAT, ALTERNATE, NATIONAL, TAX_EXEMPT
|
139
|
+
# * <tt> :customer_vat_number </tt> -- Applicable for Level3 Charge. Indicates the customer's government assigned tax identification number or the identification number assigned to their purchasing company by the tax authorities. Format: Alphanumeric and Special Character|Min Length=0 Max Length=13| a-z A-Z 0-9 Space <>
|
140
|
+
# * <tt> :summary_commodity_code </tt> -- Applicable for Level3 Charge. The international description code of the overall goods or services being supplied. Format: Alphanumeric and Special Character |Min Length=0 Max Length=4|Allowed character: a-z A-Z 0-9 Space <>
|
141
|
+
# * <tt> :shipping_charges </tt> -- Applicable for Level3 Charge. The dollar amount for shipping or freight charges applied to a product or transaction. Format: Numeric |Max Length=12|Allowed characters: 0-9 .(dot) Note: If a decimal point is included, the amount reflects a dollar value. If a decimal point is not included, the amount reflects a cent value.
|
142
|
+
# * <tt> :duty_charges </tt> -- Applicable for Level3 Charge. Indicates the total charges for any import or export duties included in the order. Format: Numeric |Max Length=12|Allowed characters: 0-9 . (dot) Note: If a decimal point is included, the amount reflects a dollar value. If a decimal point is not included, the amount reflects a cent value.
|
143
|
+
# * <tt> :ship_from_zip </tt> -- Applicable for Level3 Charge. The postal code for the address to which the goods are being shipped. Format: Alphanumeric |Min Length=2 Max Length=10
|
144
|
+
# * <tt> :destination_country_code </tt> -- Applicable for Level3 Charge. The destination country code indicator. Format: Alphanumeric.
|
145
|
+
# * <tt> :tax_type </tt> -- Applicable for Level3 Charge. The type of tax. For example, VAT, NATIONAL, Service Tax. Format: Alphanumeric and Special Character
|
146
|
+
# * <tt> :vat_invoice </tt> -- Applicable for Level3 Charge. The Value Added Tax (VAT) invoice number associated with the transaction. Format: Alphanumeric and Special Character |Min Length=0 Max Length=15|Allowed character: a-z A-Z 0-9 Space <>
|
147
|
+
# * <tt> :tax_rate </tt> -- Applicable for Level3 Charge. The type of tax rate. This field is used if taxCategory is not used. Default sale tax rate in percentage Must be between 0.1% - 22% ,Applicable only Level 2 AutoFill. Format: Decimal Number |Max Length=4|Allowed characters: 0-9 .(dot) Allowed range: 0.01 - 100
|
148
|
+
# * <tt> :email </tt> -- Customer's email address.
|
149
|
+
|
150
|
+
def authorize(money, creditcard, options = {})
|
151
|
+
options[:capture] = '0'
|
152
|
+
MultiResponse.run do |r|
|
153
|
+
r.process { token(creditcard, options) }
|
154
|
+
r.process { charge(money, r.authorization, options) }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# Capture the payment of an existing, uncaptured, charge.
|
160
|
+
# This is the second half of the two-step payment flow, where first you created / authorized a charge
|
161
|
+
# with the capture option set to false.
|
162
|
+
#
|
163
|
+
# <tt>:money</tt> A positive integer in cents representing how much to charge. The minimum amount is 50c USD.
|
164
|
+
#
|
165
|
+
# <tt>:tx_reference</tt> charge_id from previously created / authorized a charge
|
166
|
+
#
|
167
|
+
# <tt>:options</tt> Other information like address, card source etc can be passed in options
|
168
|
+
|
169
|
+
def capture(money, tx_reference, options = {})
|
170
|
+
post = {}
|
171
|
+
add_money(post, money, options)
|
172
|
+
action = "#{STANDARD_ACTIONS[:capture][:end_point]}/#{tx_reference}/capture"
|
173
|
+
post = filter_gateway_fields(post, options, STANDARD_ACTIONS[:capture][:allowed_fields])
|
174
|
+
commit(action, post)
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# Voids the transaction / charge.
|
179
|
+
#
|
180
|
+
# <tt>:tx_reference</tt> charge_id from previously created charge
|
181
|
+
#
|
182
|
+
# <tt>:options</tt> Other information like address, card source etc can be passed in options
|
183
|
+
#
|
184
|
+
# ==== Options
|
185
|
+
#
|
186
|
+
# * <tt> :reason </tt> -- Reason for voiding transaction (REQUIRED) ( requested_by_customer, duplicate, fraudulent, other )
|
187
|
+
|
188
|
+
def void(tx_reference, options = {})
|
189
|
+
post = {}
|
190
|
+
post['reason'] = options[:reason]
|
191
|
+
action = STANDARD_ACTIONS[:void][:end_point].gsub(/{{chargeID}}/, tx_reference)
|
192
|
+
post = filter_gateway_fields(post, options, STANDARD_ACTIONS[:void][:allowed_fields])
|
193
|
+
commit(action, post)
|
194
|
+
end
|
195
|
+
|
196
|
+
#
|
197
|
+
# Refund full / partial payment of an successful charge / capture / purchase.
|
198
|
+
#
|
199
|
+
# <tt>:money</tt> A positive integer in cents representing how much to charge. The minimum amount is 50c USD.
|
200
|
+
#
|
201
|
+
# <tt>:tx_reference</tt> charge_id from previously created / authorized a charge
|
202
|
+
#
|
203
|
+
# <tt>:options</tt> Other information like address, card source etc can be passed in options
|
204
|
+
|
205
|
+
def refund(money, tx_reference, options = {})
|
206
|
+
post = {}
|
207
|
+
add_money(post, money, options)
|
208
|
+
action = STANDARD_ACTIONS[:refund][:end_point].gsub(/{{charge_id}}/, tx_reference)
|
209
|
+
post = filter_gateway_fields(post, options, STANDARD_ACTIONS[:refund][:allowed_fields])
|
210
|
+
commit(action, post)
|
211
|
+
end
|
212
|
+
|
213
|
+
def credit(money, creditcard, options = {})
|
214
|
+
post = {}
|
215
|
+
add_money(post, money, options)
|
216
|
+
add_creditcard(post, creditcard, options)
|
217
|
+
add_address(post, options)
|
218
|
+
add_phone(post, options)
|
219
|
+
post['receipt_email'] = options[:email] if options[:email]
|
220
|
+
action = STANDARD_ACTIONS[:credit][:end_point]
|
221
|
+
post = filter_gateway_fields(post, options, STANDARD_ACTIONS[:credit][:allowed_fields])
|
222
|
+
commit(action, post)
|
223
|
+
end
|
224
|
+
|
225
|
+
#
|
226
|
+
# Verify the creditcard API through PAYARC.
|
227
|
+
#
|
228
|
+
# <tt>:creditcard</tt> <tt>CreditCard</tt> object with card details.
|
229
|
+
#
|
230
|
+
# <tt>:options</tt> Other information like address, card source etc can be passed in options
|
231
|
+
#
|
232
|
+
# ==== Options
|
233
|
+
#
|
234
|
+
# * <tt>:card_source </tt> -- Source of payment (REQUIRED) ( INTERNET, SWIPE, PHONE, MAIL, MANUAL )
|
235
|
+
# * <tt>:card_holder_name</tt> --Name of the Card Holder (OPTIONAL)
|
236
|
+
# * <tt>:address_line1</tt> -- Set in payment method's billing address (OPTIONAL)
|
237
|
+
# * <tt>:address_line2</tt> -- Set in payment method's billing address (OPTIONAL)
|
238
|
+
# * <tt>:state </tt> -- State (OPTIONAL)
|
239
|
+
# * <tt>:country </tt> -- Country (OPTIONAL)
|
240
|
+
|
241
|
+
def verify(creditcard, options = {})
|
242
|
+
token(creditcard, options)
|
243
|
+
end
|
244
|
+
|
245
|
+
#:nodoc:
|
246
|
+
def token(creditcard, options = {})
|
247
|
+
post = {}
|
248
|
+
post['authorize_card'] = 1
|
249
|
+
post['card_source'] = options[:card_source]
|
250
|
+
add_creditcard(post, creditcard, options)
|
251
|
+
add_address(post, options)
|
252
|
+
post = filter_gateway_fields(post, options, STANDARD_ACTIONS[:token][:allowed_fields])
|
253
|
+
commit(STANDARD_ACTIONS[:token][:end_point], post)
|
254
|
+
end
|
255
|
+
|
256
|
+
def supports_scrubbing? #:nodoc:
|
257
|
+
true
|
258
|
+
end
|
259
|
+
|
260
|
+
def scrub(transcript)
|
261
|
+
#:nodoc:
|
262
|
+
transcript.
|
263
|
+
gsub(%r((Authorization: Bearer )[^\s]+\s)i, '\1[FILTERED]\2').
|
264
|
+
gsub(%r((&?card_number=)[^&]*)i, '\1[FILTERED]').
|
265
|
+
gsub(%r((&?cvv=)[^&]*)i, '\1[BLANK]')
|
266
|
+
end
|
267
|
+
|
268
|
+
private
|
269
|
+
|
270
|
+
def charge(money, authorization, options = {})
|
271
|
+
post = {}
|
272
|
+
post['token_id'] = authorization
|
273
|
+
post['capture'] = options[:capture] || 1
|
274
|
+
add_money(post, money, options)
|
275
|
+
add_phone(post, options)
|
276
|
+
post = filter_gateway_fields(post, options, STANDARD_ACTIONS[:capture][:allowed_fields])
|
277
|
+
commit(STANDARD_ACTIONS[:capture][:end_point], post)
|
278
|
+
end
|
279
|
+
|
280
|
+
def add_creditcard(post, creditcard, options)
|
281
|
+
post['card_number'] = creditcard.number
|
282
|
+
post['exp_month'] = format(creditcard.month, :two_digits)
|
283
|
+
post['exp_year'] = creditcard.year
|
284
|
+
post['cvv'] = creditcard.verification_value unless creditcard.verification_value.nil?
|
285
|
+
post['card_holder_name'] = options[:card_holder_name] || "#{creditcard.first_name} #{creditcard.last_name}"
|
286
|
+
end
|
287
|
+
|
288
|
+
def add_address(post, options)
|
289
|
+
post['address_line1'] = options[:billing_address][:address1]
|
290
|
+
post['address_line2'] = options[:billing_address][:address2]
|
291
|
+
post['city'] = options[:billing_address][:city]
|
292
|
+
post['state'] = options[:billing_address][:state]
|
293
|
+
post['zip'] = options[:billing_address][:zip]
|
294
|
+
post['country'] = options[:billing_address][:country]
|
295
|
+
end
|
296
|
+
|
297
|
+
def add_phone(post, options)
|
298
|
+
post['receipt_phone'] = options[:billing_address][:phone] if options[:billing_address][:phone]
|
299
|
+
end
|
300
|
+
|
301
|
+
def add_money(post, money, options)
|
302
|
+
post['amount'] = money
|
303
|
+
post['currency'] = currency(money) unless options[:currency]
|
304
|
+
post['statement_description'] = options[:statement_description]
|
305
|
+
end
|
306
|
+
|
307
|
+
def headers(api_key)
|
308
|
+
{
|
309
|
+
'Authorization' => 'Bearer ' + api_key.strip,
|
310
|
+
'Accept' => 'application/json',
|
311
|
+
'User-Agent' => "PayArc ActiveMerchantBindings/#{ActiveMerchant::VERSION}"
|
312
|
+
}
|
313
|
+
end
|
314
|
+
|
315
|
+
def parse(body)
|
316
|
+
JSON.parse(body)
|
317
|
+
rescue JSON::ParserError
|
318
|
+
body
|
319
|
+
end
|
320
|
+
|
321
|
+
def filter_gateway_fields(post, options, gateway_fields)
|
322
|
+
filtered_options = options.slice(*gateway_fields).compact
|
323
|
+
post.update(filtered_options)
|
324
|
+
post
|
325
|
+
end
|
326
|
+
|
327
|
+
def commit(action, parameters)
|
328
|
+
url = (test? ? test_url : live_url)
|
329
|
+
headers = headers(@options[:api_key])
|
330
|
+
end_point = "#{url}/#{action}"
|
331
|
+
begin
|
332
|
+
response = ssl_post(end_point, post_data(parameters), headers)
|
333
|
+
parsed_response = parse(response)
|
334
|
+
|
335
|
+
Response.new(
|
336
|
+
success_from(parsed_response, action),
|
337
|
+
message_from(parsed_response, action),
|
338
|
+
parsed_response,
|
339
|
+
test: test?,
|
340
|
+
authorization: parse_response_id(parsed_response),
|
341
|
+
error_code: error_code_from(parsed_response, action)
|
342
|
+
)
|
343
|
+
rescue ResponseError => e
|
344
|
+
parsed_response = parse(e.response.body)
|
345
|
+
Response.new(
|
346
|
+
false,
|
347
|
+
message_from(parsed_response, action),
|
348
|
+
parsed_response,
|
349
|
+
test: test?,
|
350
|
+
authorization: nil,
|
351
|
+
error_code: error_code_from(parsed_response, action)
|
352
|
+
)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def success_from(response, action)
|
357
|
+
if action == STANDARD_ACTIONS[:token][:end_point]
|
358
|
+
token = parse_response_id(response)
|
359
|
+
(!token.nil? && !token.empty?)
|
360
|
+
elsif response
|
361
|
+
return SUCCESS_STATUS.include? response['data']['status'] if response['data']
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def message_from(response, action)
|
366
|
+
if success_from(response, action)
|
367
|
+
if action == STANDARD_ACTIONS[:token][:end_point]
|
368
|
+
return response['data']['id']
|
369
|
+
else
|
370
|
+
return response['data']['status']
|
371
|
+
end
|
372
|
+
else
|
373
|
+
return response['message']
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def parse_response_id(response)
|
378
|
+
response['data']['id'] if response && response['data']
|
379
|
+
end
|
380
|
+
|
381
|
+
def post_data(params)
|
382
|
+
params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
|
383
|
+
end
|
384
|
+
|
385
|
+
def error_code_from(response, action)
|
386
|
+
response['status_code'] unless success_from(response, action)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|