activemerchant 1.121.0 → 1.125.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 +217 -0
- data/README.md +1 -1
- data/lib/active_merchant/billing/check.rb +13 -19
- data/lib/active_merchant/billing/credit_card.rb +13 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +1 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +24 -12
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/adyen.rb +75 -27
- 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/card_stream.rb +17 -13
- data/lib/active_merchant/billing/gateways/cashnet.rb +15 -5
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +33 -4
- data/lib/active_merchant/billing/gateways/credorax.rb +2 -1
- data/lib/active_merchant/billing/gateways/cyber_source.rb +41 -6
- data/lib/active_merchant/billing/gateways/d_local.rb +12 -6
- data/lib/active_merchant/billing/gateways/decidir.rb +7 -1
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +173 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +16 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +65 -30
- data/lib/active_merchant/billing/gateways/element.rb +22 -2
- data/lib/active_merchant/billing/gateways/global_collect.rb +130 -26
- data/lib/active_merchant/billing/gateways/ipg.rb +416 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +30 -0
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +6 -3
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -0
- data/lib/active_merchant/billing/gateways/mit.rb +260 -0
- data/lib/active_merchant/billing/gateways/moka.rb +290 -0
- data/lib/active_merchant/billing/gateways/monei.rb +228 -144
- data/lib/active_merchant/billing/gateways/mundipagg.rb +22 -11
- data/lib/active_merchant/billing/gateways/nmi.rb +29 -10
- data/lib/active_merchant/billing/gateways/orbital.rb +46 -8
- data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_conex.rb +3 -1
- 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 +21 -4
- data/lib/active_merchant/billing/gateways/payment_express.rb +2 -2
- data/lib/active_merchant/billing/gateways/paymentez.rb +14 -2
- data/lib/active_merchant/billing/gateways/paysafe.rb +412 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +9 -4
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +3 -3
- data/lib/active_merchant/billing/gateways/pin.rb +31 -4
- data/lib/active_merchant/billing/gateways/priority.rb +347 -0
- data/lib/active_merchant/billing/gateways/realex.rb +18 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +35 -32
- data/lib/active_merchant/billing/gateways/safe_charge.rb +8 -2
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +13 -4
- data/lib/active_merchant/billing/gateways/stripe.rb +27 -7
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +115 -39
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +2 -1
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +21 -7
- data/lib/active_merchant/billing/gateways/vpos.rb +49 -6
- data/lib/active_merchant/billing/gateways/wompi.rb +193 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +226 -62
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/billing/response.rb +4 -0
- 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 +13 -3
@@ -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
|
@@ -219,8 +220,9 @@ module ActiveMerchant #:nodoc:
|
|
219
220
|
end
|
220
221
|
|
221
222
|
def verify(creditcard, options = {})
|
223
|
+
amount = allow_0_auth?(creditcard) ? 0 : 100
|
222
224
|
MultiResponse.run(:use_first_response) do |r|
|
223
|
-
r.process { authorize(
|
225
|
+
r.process { authorize(amount, creditcard, options) }
|
224
226
|
r.process(:ignore_result) { void(r.authorization) }
|
225
227
|
end
|
226
228
|
end
|
@@ -275,6 +277,11 @@ module ActiveMerchant #:nodoc:
|
|
275
277
|
commit(order, :void, options[:retry_logic], options[:trace_number])
|
276
278
|
end
|
277
279
|
|
280
|
+
def allow_0_auth?(credit_card)
|
281
|
+
# Discover does not support a $0.00 authorization instead use $1.00
|
282
|
+
%w(visa master american_express diners_club jcb).include?(credit_card.brand)
|
283
|
+
end
|
284
|
+
|
278
285
|
# ==== Customer Profiles
|
279
286
|
# :customer_ref_num should be set unless you're happy with Orbital providing one
|
280
287
|
#
|
@@ -334,7 +341,10 @@ module ActiveMerchant #:nodoc:
|
|
334
341
|
gsub(%r((<CardSecVal>).+(</CardSecVal>)), '\1[FILTERED]\2').
|
335
342
|
gsub(%r((<MerchantID>).+(</MerchantID>)), '\1[FILTERED]\2').
|
336
343
|
gsub(%r((<CustomerMerchantID>).+(</CustomerMerchantID>)), '\1[FILTERED]\2').
|
337
|
-
gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2')
|
344
|
+
gsub(%r((<CustomerProfileMessage>).+(</CustomerProfileMessage>)), '\1[FILTERED]\2').
|
345
|
+
gsub(%r((<CheckDDA>).+(</CheckDDA>)), '\1[FILTERED]\2').
|
346
|
+
gsub(%r((<BCRtNum>).+(</BCRtNum>)), '\1[FILTERED]\2').
|
347
|
+
gsub(%r((<DigitalTokenCryptogram>).+(</DigitalTokenCryptogram>)), '\1[FILTERED]\2')
|
338
348
|
end
|
339
349
|
|
340
350
|
private
|
@@ -566,7 +576,7 @@ module ActiveMerchant #:nodoc:
|
|
566
576
|
# - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
567
577
|
unless creditcard.nil?
|
568
578
|
if creditcard.verification_value?
|
569
|
-
xml.tag! :CardSecValInd, '1' if %w(visa discover).include?(creditcard.brand)
|
579
|
+
xml.tag! :CardSecValInd, '1' if %w(visa master discover).include?(creditcard.brand)
|
570
580
|
xml.tag! :CardSecVal, creditcard.verification_value
|
571
581
|
end
|
572
582
|
end
|
@@ -602,8 +612,10 @@ module ActiveMerchant #:nodoc:
|
|
602
612
|
|
603
613
|
def add_mc_program_protocol(xml, creditcard, three_d_secure)
|
604
614
|
return unless three_d_secure && creditcard.brand == 'master'
|
615
|
+
return unless three_d_secure[:version]
|
605
616
|
|
606
|
-
|
617
|
+
truncated_version = three_d_secure[:version].to_s[0]
|
618
|
+
xml.tag!(:MCProgramProtocol, truncated_version)
|
607
619
|
end
|
608
620
|
|
609
621
|
def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
|
@@ -612,12 +624,28 @@ module ActiveMerchant #:nodoc:
|
|
612
624
|
xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
|
613
625
|
end
|
614
626
|
|
615
|
-
def
|
627
|
+
def add_mc_ucafind(xml, creditcard, three_d_secure)
|
616
628
|
return unless three_d_secure && creditcard.brand == 'master'
|
617
629
|
|
618
630
|
xml.tag! :UCAFInd, '4'
|
619
631
|
end
|
620
632
|
|
633
|
+
def add_mc_scarecurring(xml, creditcard, parameters, three_d_secure)
|
634
|
+
return unless parameters && parameters[:sca_recurring] && creditcard.brand == 'master'
|
635
|
+
|
636
|
+
valid_eci = three_d_secure && three_d_secure[:eci] && three_d_secure[:eci] == '7'
|
637
|
+
|
638
|
+
xml.tag!(:SCARecurringPayment, parameters[:sca_recurring]) if valid_eci
|
639
|
+
end
|
640
|
+
|
641
|
+
def add_mc_sca_merchant_initiated(xml, creditcard, parameters, three_d_secure)
|
642
|
+
return unless parameters && parameters[:sca_merchant_initiated] && creditcard.brand == 'master'
|
643
|
+
|
644
|
+
valid_eci = three_d_secure && three_d_secure[:eci] && three_d_secure[:eci] == '7'
|
645
|
+
|
646
|
+
xml.tag!(:SCAMerchantInitiatedTransaction, parameters[:sca_merchant_initiated]) if valid_eci
|
647
|
+
end
|
648
|
+
|
621
649
|
def add_dpanind(xml, creditcard)
|
622
650
|
return unless creditcard.is_a?(NetworkTokenizationCreditCard)
|
623
651
|
|
@@ -745,7 +773,7 @@ module ActiveMerchant #:nodoc:
|
|
745
773
|
|
746
774
|
def parse(body)
|
747
775
|
response = {}
|
748
|
-
xml = REXML::Document.new(body)
|
776
|
+
xml = REXML::Document.new(strip_invalid_xml_chars(body))
|
749
777
|
root = REXML::XPath.first(xml, '//Response') ||
|
750
778
|
REXML::XPath.first(xml, '//ErrorResponse')
|
751
779
|
if root
|
@@ -799,8 +827,10 @@ module ActiveMerchant #:nodoc:
|
|
799
827
|
end
|
800
828
|
|
801
829
|
def success?(response, message_type)
|
802
|
-
if %i[
|
830
|
+
if %i[void].include?(message_type)
|
803
831
|
response[:proc_status] == SUCCESS
|
832
|
+
elsif %i[refund].include?(message_type)
|
833
|
+
response[:proc_status] == SUCCESS && response[:approval_status] == APPROVAL_SUCCESS
|
804
834
|
elsif response[:customer_profile_action]
|
805
835
|
response[:profile_proc_status] == SUCCESS
|
806
836
|
else
|
@@ -884,9 +914,11 @@ module ActiveMerchant #:nodoc:
|
|
884
914
|
add_card_indicators(xml, parameters)
|
885
915
|
add_stored_credentials(xml, parameters)
|
886
916
|
add_pymt_brand_program_code(xml, payment_source, three_d_secure)
|
917
|
+
add_mc_sca_merchant_initiated(xml, payment_source, parameters, three_d_secure)
|
918
|
+
add_mc_scarecurring(xml, payment_source, parameters, three_d_secure)
|
887
919
|
add_mc_program_protocol(xml, payment_source, three_d_secure)
|
888
920
|
add_mc_directory_trans_id(xml, payment_source, three_d_secure)
|
889
|
-
|
921
|
+
add_mc_ucafind(xml, payment_source, three_d_secure)
|
890
922
|
end
|
891
923
|
end
|
892
924
|
xml.target!
|
@@ -985,6 +1017,12 @@ module ActiveMerchant #:nodoc:
|
|
985
1017
|
options[:billing_address] || options[:address]
|
986
1018
|
end
|
987
1019
|
|
1020
|
+
# Null characters are possible in some responses (namely, the respMsg field), causing XML parsing errors
|
1021
|
+
# Prevent by substituting these with a valid placeholder string
|
1022
|
+
def strip_invalid_xml_chars(xml)
|
1023
|
+
xml.gsub(/\u0000/, '[null]')
|
1024
|
+
end
|
1025
|
+
|
988
1026
|
# The valid characters include:
|
989
1027
|
#
|
990
1028
|
# 1. all letters and digits
|
@@ -0,0 +1,392 @@
|
|
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
|
+
return unless billing_address = options[:billing_address]
|
290
|
+
|
291
|
+
post['address_line1'] = billing_address[:address1]
|
292
|
+
post['address_line2'] = billing_address[:address2]
|
293
|
+
post['city'] = billing_address[:city]
|
294
|
+
post['state'] = billing_address[:state]
|
295
|
+
post['zip'] = billing_address[:zip]
|
296
|
+
post['country'] = billing_address[:country]
|
297
|
+
end
|
298
|
+
|
299
|
+
def add_phone(post, options)
|
300
|
+
post['phone_number'] = options[:billing_address][:phone] if options.dig(:billing_address, :phone)
|
301
|
+
end
|
302
|
+
|
303
|
+
def add_money(post, money, options)
|
304
|
+
post['amount'] = money
|
305
|
+
post['currency'] = currency(money) unless options[:currency]
|
306
|
+
post['statement_description'] = options[:statement_description]
|
307
|
+
end
|
308
|
+
|
309
|
+
def headers(api_key)
|
310
|
+
{
|
311
|
+
'Authorization' => 'Bearer ' + api_key.strip,
|
312
|
+
'Accept' => 'application/json',
|
313
|
+
'User-Agent' => "PayArc ActiveMerchantBindings/#{ActiveMerchant::VERSION}"
|
314
|
+
}
|
315
|
+
end
|
316
|
+
|
317
|
+
def parse(body)
|
318
|
+
JSON.parse(body)
|
319
|
+
rescue JSON::ParserError
|
320
|
+
body
|
321
|
+
end
|
322
|
+
|
323
|
+
def filter_gateway_fields(post, options, gateway_fields)
|
324
|
+
filtered_options = options.slice(*gateway_fields).compact
|
325
|
+
post.update(filtered_options)
|
326
|
+
post
|
327
|
+
end
|
328
|
+
|
329
|
+
def commit(action, parameters)
|
330
|
+
url = (test? ? test_url : live_url)
|
331
|
+
headers = headers(@options[:api_key])
|
332
|
+
end_point = "#{url}/#{action}"
|
333
|
+
begin
|
334
|
+
response = ssl_post(end_point, post_data(parameters), headers)
|
335
|
+
parsed_response = parse(response)
|
336
|
+
|
337
|
+
Response.new(
|
338
|
+
success_from(parsed_response, action),
|
339
|
+
message_from(parsed_response, action),
|
340
|
+
parsed_response,
|
341
|
+
test: test?,
|
342
|
+
authorization: parse_response_id(parsed_response),
|
343
|
+
error_code: error_code_from(parsed_response, action)
|
344
|
+
)
|
345
|
+
rescue ResponseError => e
|
346
|
+
parsed_response = parse(e.response.body)
|
347
|
+
Response.new(
|
348
|
+
false,
|
349
|
+
message_from(parsed_response, action),
|
350
|
+
parsed_response,
|
351
|
+
test: test?,
|
352
|
+
authorization: nil,
|
353
|
+
error_code: error_code_from(parsed_response, action)
|
354
|
+
)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def success_from(response, action)
|
359
|
+
if action == STANDARD_ACTIONS[:token][:end_point]
|
360
|
+
token = parse_response_id(response)
|
361
|
+
(!token.nil? && !token.empty?)
|
362
|
+
elsif response
|
363
|
+
return SUCCESS_STATUS.include? response['data']['status'] if response['data']
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def message_from(response, action)
|
368
|
+
if success_from(response, action)
|
369
|
+
if action == STANDARD_ACTIONS[:token][:end_point]
|
370
|
+
return response['data']['id']
|
371
|
+
else
|
372
|
+
return response['data']['status']
|
373
|
+
end
|
374
|
+
else
|
375
|
+
return response['message']
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
def parse_response_id(response)
|
380
|
+
response['data']['id'] if response && response['data']
|
381
|
+
end
|
382
|
+
|
383
|
+
def post_data(params)
|
384
|
+
params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join('&')
|
385
|
+
end
|
386
|
+
|
387
|
+
def error_code_from(response, action)
|
388
|
+
response['status_code'] unless success_from(response, action)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
@@ -79,7 +79,9 @@ module ActiveMerchant #:nodoc:
|
|
79
79
|
force_utf8(transcript).
|
80
80
|
gsub(%r((api_accesskey=)\w+), '\1[FILTERED]').
|
81
81
|
gsub(%r((card_number=)\w+), '\1[FILTERED]').
|
82
|
-
gsub(%r((card_verification=)\w+), '\1[FILTERED]')
|
82
|
+
gsub(%r((card_verification=)\w+), '\1[FILTERED]').
|
83
|
+
gsub(%r((bank_account_number=)\w+), '\1[FILTERED]').
|
84
|
+
gsub(%r((bank_routing_number=)\w+), '\1[FILTERED]')
|
83
85
|
end
|
84
86
|
|
85
87
|
private
|