activemerchant 1.120.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 +227 -1
- 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 +81 -26
- 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 +9 -5
- 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 +43 -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 +55 -9
- 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 +1 -1
- data/lib/active_merchant/billing/gateways/paymentez.rb +14 -2
- data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
- 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 +58 -10
- 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
|
@@ -464,7 +474,7 @@ module ActiveMerchant #:nodoc:
|
|
464
474
|
xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
|
465
475
|
end
|
466
476
|
|
467
|
-
xml.tag! :AVSname, (payment_source
|
477
|
+
xml.tag! :AVSname, billing_name(payment_source, options)
|
468
478
|
xml.tag! :AVScountryCode, (avs_supported ? byte_limit(format_address_field(address[:country]), 2) : '')
|
469
479
|
|
470
480
|
# Needs to come after AVScountryCode
|
@@ -472,6 +482,14 @@ module ActiveMerchant #:nodoc:
|
|
472
482
|
end
|
473
483
|
end
|
474
484
|
|
485
|
+
def billing_name(payment_source, options)
|
486
|
+
if payment_source&.name.present?
|
487
|
+
payment_source.name[0..29]
|
488
|
+
elsif options[:billing_address][:name].present?
|
489
|
+
options[:billing_address][:name][0..29]
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
475
493
|
def add_destination_address(xml, address)
|
476
494
|
if address[:dest_zip]
|
477
495
|
avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:dest_country].to_s)
|
@@ -558,7 +576,7 @@ module ActiveMerchant #:nodoc:
|
|
558
576
|
# - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
559
577
|
unless creditcard.nil?
|
560
578
|
if creditcard.verification_value?
|
561
|
-
xml.tag! :CardSecValInd, '1' if %w(visa discover).include?(creditcard.brand)
|
579
|
+
xml.tag! :CardSecValInd, '1' if %w(visa master discover).include?(creditcard.brand)
|
562
580
|
xml.tag! :CardSecVal, creditcard.verification_value
|
563
581
|
end
|
564
582
|
end
|
@@ -594,8 +612,10 @@ module ActiveMerchant #:nodoc:
|
|
594
612
|
|
595
613
|
def add_mc_program_protocol(xml, creditcard, three_d_secure)
|
596
614
|
return unless three_d_secure && creditcard.brand == 'master'
|
615
|
+
return unless three_d_secure[:version]
|
597
616
|
|
598
|
-
|
617
|
+
truncated_version = three_d_secure[:version].to_s[0]
|
618
|
+
xml.tag!(:MCProgramProtocol, truncated_version)
|
599
619
|
end
|
600
620
|
|
601
621
|
def add_mc_directory_trans_id(xml, creditcard, three_d_secure)
|
@@ -604,12 +624,28 @@ module ActiveMerchant #:nodoc:
|
|
604
624
|
xml.tag!(:MCDirectoryTransID, three_d_secure[:ds_transaction_id]) if three_d_secure[:ds_transaction_id]
|
605
625
|
end
|
606
626
|
|
607
|
-
def
|
627
|
+
def add_mc_ucafind(xml, creditcard, three_d_secure)
|
608
628
|
return unless three_d_secure && creditcard.brand == 'master'
|
609
629
|
|
610
630
|
xml.tag! :UCAFInd, '4'
|
611
631
|
end
|
612
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
|
+
|
613
649
|
def add_dpanind(xml, creditcard)
|
614
650
|
return unless creditcard.is_a?(NetworkTokenizationCreditCard)
|
615
651
|
|
@@ -737,7 +773,7 @@ module ActiveMerchant #:nodoc:
|
|
737
773
|
|
738
774
|
def parse(body)
|
739
775
|
response = {}
|
740
|
-
xml = REXML::Document.new(body)
|
776
|
+
xml = REXML::Document.new(strip_invalid_xml_chars(body))
|
741
777
|
root = REXML::XPath.first(xml, '//Response') ||
|
742
778
|
REXML::XPath.first(xml, '//ErrorResponse')
|
743
779
|
if root
|
@@ -791,8 +827,10 @@ module ActiveMerchant #:nodoc:
|
|
791
827
|
end
|
792
828
|
|
793
829
|
def success?(response, message_type)
|
794
|
-
if %i[
|
830
|
+
if %i[void].include?(message_type)
|
795
831
|
response[:proc_status] == SUCCESS
|
832
|
+
elsif %i[refund].include?(message_type)
|
833
|
+
response[:proc_status] == SUCCESS && response[:approval_status] == APPROVAL_SUCCESS
|
796
834
|
elsif response[:customer_profile_action]
|
797
835
|
response[:profile_proc_status] == SUCCESS
|
798
836
|
else
|
@@ -876,9 +914,11 @@ module ActiveMerchant #:nodoc:
|
|
876
914
|
add_card_indicators(xml, parameters)
|
877
915
|
add_stored_credentials(xml, parameters)
|
878
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)
|
879
919
|
add_mc_program_protocol(xml, payment_source, three_d_secure)
|
880
920
|
add_mc_directory_trans_id(xml, payment_source, three_d_secure)
|
881
|
-
|
921
|
+
add_mc_ucafind(xml, payment_source, three_d_secure)
|
882
922
|
end
|
883
923
|
end
|
884
924
|
xml.target!
|
@@ -977,6 +1017,12 @@ module ActiveMerchant #:nodoc:
|
|
977
1017
|
options[:billing_address] || options[:address]
|
978
1018
|
end
|
979
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
|
+
|
980
1026
|
# The valid characters include:
|
981
1027
|
#
|
982
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
|