activemerchant 1.130.0 → 1.137.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +268 -0
- data/lib/active_merchant/billing/check.rb +2 -2
- data/lib/active_merchant/billing/compatibility.rb +4 -4
- data/lib/active_merchant/billing/credit_card.rb +13 -8
- data/lib/active_merchant/billing/credit_card_formatting.rb +4 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +64 -7
- data/lib/active_merchant/billing/gateway.rb +9 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +240 -41
- data/lib/active_merchant/billing/gateways/airwallex.rb +26 -12
- data/lib/active_merchant/billing/gateways/alelo.rb +23 -5
- data/lib/active_merchant/billing/gateways/authorize_net.rb +44 -36
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +10 -6
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -3
- data/lib/active_merchant/billing/gateways/axcessms.rb +6 -2
- data/lib/active_merchant/billing/gateways/banwire.rb +4 -2
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -3
- data/lib/active_merchant/billing/gateways/blue_pay.rb +13 -5
- data/lib/active_merchant/billing/gateways/blue_snap.rb +5 -5
- data/lib/active_merchant/billing/gateways/borgun.rb +6 -4
- data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +65 -20
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +226 -73
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
- data/lib/active_merchant/billing/gateways/card_connect.rb +5 -2
- data/lib/active_merchant/billing/gateways/card_stream.rb +4 -6
- data/lib/active_merchant/billing/gateways/cashnet.rb +1 -1
- data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
- data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +316 -0
- data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +7 -240
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +252 -41
- data/lib/active_merchant/billing/gateways/commerce_hub.rb +69 -8
- data/lib/active_merchant/billing/gateways/credorax.rb +3 -5
- data/lib/active_merchant/billing/gateways/cyber_source.rb +192 -41
- data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +102 -58
- data/lib/active_merchant/billing/gateways/d_local.rb +26 -15
- data/lib/active_merchant/billing/gateways/data_cash.rb +21 -17
- data/lib/active_merchant/billing/gateways/datatrans.rb +279 -0
- data/lib/active_merchant/billing/gateways/decidir.rb +53 -18
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +4 -1
- data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +40 -36
- data/lib/active_merchant/billing/gateways/efsnet.rb +6 -2
- data/lib/active_merchant/billing/gateways/elavon.rb +99 -33
- data/lib/active_merchant/billing/gateways/element.rb +36 -7
- data/lib/active_merchant/billing/gateways/epay.rb +6 -2
- data/lib/active_merchant/billing/gateways/evo_ca.rb +6 -2
- data/lib/active_merchant/billing/gateways/eway.rb +4 -2
- data/lib/active_merchant/billing/gateways/eway_managed.rb +6 -2
- data/lib/active_merchant/billing/gateways/exact.rb +6 -2
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +31 -3
- data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -2
- data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
- data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
- data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +6 -172
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -2
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +7 -3
- data/lib/active_merchant/billing/gateways/flex_charge.rb +347 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +4 -2
- data/lib/active_merchant/billing/gateways/global_collect.rb +45 -37
- data/lib/active_merchant/billing/gateways/hi_pay.rb +286 -0
- data/lib/active_merchant/billing/gateways/hps.rb +1 -1
- data/lib/active_merchant/billing/gateways/iats_payments.rb +7 -2
- data/lib/active_merchant/billing/gateways/inspire.rb +6 -4
- data/lib/active_merchant/billing/gateways/instapay.rb +7 -4
- data/lib/active_merchant/billing/gateways/ipg.rb +10 -6
- data/lib/active_merchant/billing/gateways/iridium.rb +15 -5
- data/lib/active_merchant/billing/gateways/itransact.rb +6 -2
- data/lib/active_merchant/billing/gateways/iveri.rb +3 -3
- data/lib/active_merchant/billing/gateways/ixopay.rb +2 -2
- data/lib/active_merchant/billing/gateways/jetpay.rb +4 -2
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +4 -2
- data/lib/active_merchant/billing/gateways/kushki.rb +73 -13
- data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -2
- data/lib/active_merchant/billing/gateways/litle.rb +33 -50
- data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
- data/lib/active_merchant/billing/gateways/maxipago.rb +2 -2
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +8 -5
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +11 -4
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +11 -4
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +19 -3
- data/lib/active_merchant/billing/gateways/mercury.rb +6 -2
- data/lib/active_merchant/billing/gateways/metrics_global.rb +8 -6
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +1 -0
- data/lib/active_merchant/billing/gateways/migs.rb +6 -2
- data/lib/active_merchant/billing/gateways/mit.rb +25 -20
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +18 -10
- data/lib/active_merchant/billing/gateways/monei.rb +1 -1
- data/lib/active_merchant/billing/gateways/moneris.rb +9 -3
- data/lib/active_merchant/billing/gateways/money_movers.rb +6 -2
- data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -4
- data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
- data/lib/active_merchant/billing/gateways/netbanx.rb +1 -3
- data/lib/active_merchant/billing/gateways/netbilling.rb +6 -2
- data/lib/active_merchant/billing/gateways/network_merchants.rb +6 -2
- data/lib/active_merchant/billing/gateways/nmi.rb +23 -6
- data/lib/active_merchant/billing/gateways/ogone.rb +6 -2
- data/lib/active_merchant/billing/gateways/openpay.rb +4 -2
- data/lib/active_merchant/billing/gateways/opp.rb +1 -2
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -2
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +1 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +83 -24
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +7 -4
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +6 -2
- data/lib/active_merchant/billing/gateways/pay_hub.rb +4 -2
- data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -2
- data/lib/active_merchant/billing/gateways/pay_secure.rb +6 -2
- data/lib/active_merchant/billing/gateways/pay_trace.rb +31 -18
- data/lib/active_merchant/billing/gateways/payeezy.rb +19 -8
- data/lib/active_merchant/billing/gateways/payex.rb +4 -2
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +1 -3
- data/lib/active_merchant/billing/gateways/payment_express.rb +8 -4
- data/lib/active_merchant/billing/gateways/paymentez.rb +23 -11
- data/lib/active_merchant/billing/gateways/paysafe.rb +12 -11
- data/lib/active_merchant/billing/gateways/payscout.rb +7 -4
- data/lib/active_merchant/billing/gateways/paystation.rb +7 -3
- data/lib/active_merchant/billing/gateways/payway.rb +6 -2
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +3 -3
- data/lib/active_merchant/billing/gateways/pin.rb +22 -4
- data/lib/active_merchant/billing/gateways/plexo.rb +49 -10
- data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
- data/lib/active_merchant/billing/gateways/priority.rb +6 -5
- data/lib/active_merchant/billing/gateways/psigate.rb +6 -2
- data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
- data/lib/active_merchant/billing/gateways/qbms.rb +6 -2
- data/lib/active_merchant/billing/gateways/quantum.rb +6 -2
- data/lib/active_merchant/billing/gateways/quickbooks.rb +6 -5
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +6 -2
- data/lib/active_merchant/billing/gateways/rapyd.rb +148 -46
- data/lib/active_merchant/billing/gateways/reach.rb +11 -4
- data/lib/active_merchant/billing/gateways/redsys.rb +3 -11
- data/lib/active_merchant/billing/gateways/redsys_rest.rb +507 -0
- data/lib/active_merchant/billing/gateways/s5.rb +3 -3
- data/lib/active_merchant/billing/gateways/safe_charge.rb +38 -17
- data/lib/active_merchant/billing/gateways/sage.rb +12 -4
- data/lib/active_merchant/billing/gateways/sage_pay.rb +79 -5
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +6 -2
- data/lib/active_merchant/billing/gateways/secure_net.rb +6 -2
- data/lib/active_merchant/billing/gateways/secure_pay.rb +8 -6
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -4
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +6 -2
- data/lib/active_merchant/billing/gateways/securion_pay.rb +24 -10
- data/lib/active_merchant/billing/gateways/shift4.rb +17 -20
- data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
- data/lib/active_merchant/billing/gateways/simetrik.rb +17 -11
- data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -2
- data/lib/active_merchant/billing/gateways/smart_ps.rb +7 -4
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +4 -2
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +2 -4
- data/lib/active_merchant/billing/gateways/stripe.rb +63 -19
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +280 -88
- data/lib/active_merchant/billing/gateways/sum_up.rb +223 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +4 -2
- data/lib/active_merchant/billing/gateways/telr.rb +3 -4
- data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +8 -16
- data/lib/active_merchant/billing/gateways/transact_pro.rb +1 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +6 -2
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -8
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -2
- data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
- data/lib/active_merchant/billing/gateways/vantiv_express.rb +587 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +6 -2
- data/lib/active_merchant/billing/gateways/viaklix.rb +6 -2
- data/lib/active_merchant/billing/gateways/visanet_peru.rb +2 -2
- data/lib/active_merchant/billing/gateways/vpos.rb +4 -4
- data/lib/active_merchant/billing/gateways/wirecard.rb +7 -3
- data/lib/active_merchant/billing/gateways/wompi.rb +5 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +147 -93
- data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +13 -10
- data/lib/active_merchant/billing/gateways/xpay.rb +242 -0
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/billing/response.rb +2 -2
- data/lib/active_merchant/connection.rb +3 -17
- data/lib/active_merchant/country.rb +1 -0
- data/lib/active_merchant/errors.rb +10 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/support/gateway_support.rb +2 -2
- data/lib/support/ssl_verify.rb +4 -4
- data/lib/support/ssl_version.rb +6 -6
- metadata +30 -9
@@ -0,0 +1,347 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class FlexChargeGateway < Gateway
|
4
|
+
self.test_url = 'https://api-sandbox.flex-charge.com/v1/'
|
5
|
+
self.live_url = 'https://api.flex-charge.com/v1/'
|
6
|
+
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.default_currency = 'USD'
|
9
|
+
self.supported_cardtypes = %i[visa master american_express discover]
|
10
|
+
self.money_format = :cents
|
11
|
+
self.homepage_url = 'https://www.flex-charge.com/'
|
12
|
+
self.display_name = 'FlexCharge'
|
13
|
+
|
14
|
+
ENDPOINTS_MAPPING = {
|
15
|
+
authenticate: 'oauth2/token',
|
16
|
+
purchase: 'evaluate',
|
17
|
+
sync: 'outcome',
|
18
|
+
refund: 'orders/%s/refund',
|
19
|
+
store: 'tokenize',
|
20
|
+
inquire: 'orders/%s',
|
21
|
+
capture: 'capture',
|
22
|
+
void: 'orders/%s/cancel'
|
23
|
+
}
|
24
|
+
|
25
|
+
SUCCESS_MESSAGES = %w(APPROVED CHALLENGE SUBMITTED SUCCESS PROCESSING CAPTUREREQUIRED).freeze
|
26
|
+
|
27
|
+
def initialize(options = {})
|
28
|
+
requires!(options, :app_key, :app_secret, :site_id, :mid)
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def purchase(money, credit_card, options = {})
|
33
|
+
post = { transactionType: options.fetch(:transactionType, 'Purchase') }
|
34
|
+
|
35
|
+
add_merchant_data(post, options)
|
36
|
+
add_base_data(post, options)
|
37
|
+
add_invoice(post, money, credit_card, options)
|
38
|
+
add_mit_data(post, options)
|
39
|
+
add_payment_method(post, credit_card, address(options), options)
|
40
|
+
add_address(post, credit_card, address(options), :billingInformation)
|
41
|
+
add_address(post, credit_card, options[:shipping_address], :shippingInformation)
|
42
|
+
add_customer_data(post, options)
|
43
|
+
add_three_ds(post, options)
|
44
|
+
add_metadata(post, options)
|
45
|
+
|
46
|
+
commit(:purchase, post)
|
47
|
+
end
|
48
|
+
|
49
|
+
def authorize(money, credit_card, options = {})
|
50
|
+
options[:transactionType] = 'Authorization'
|
51
|
+
purchase(money, credit_card, options)
|
52
|
+
end
|
53
|
+
|
54
|
+
def capture(money, authorization, options = {})
|
55
|
+
order_id, currency = authorization.split('#')
|
56
|
+
post = {
|
57
|
+
idempotencyKey: options[:idempotency_key] || SecureRandom.uuid,
|
58
|
+
orderId: order_id,
|
59
|
+
amount: money,
|
60
|
+
currency: currency
|
61
|
+
}
|
62
|
+
|
63
|
+
commit(:capture, post, authorization)
|
64
|
+
end
|
65
|
+
|
66
|
+
def refund(money, authorization, options = {})
|
67
|
+
order_id, _currency = authorization.split('#')
|
68
|
+
self.money_format = :dollars
|
69
|
+
commit(:refund, { amountToRefund: localized_amount(money, 2).to_f }, order_id)
|
70
|
+
end
|
71
|
+
|
72
|
+
def void(authorization, options = {})
|
73
|
+
order_id, _currency = authorization.split('#')
|
74
|
+
commit(:void, {}, order_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
def store(credit_card, options = {})
|
78
|
+
first_name, last_name = names_from_address(address(options), credit_card)
|
79
|
+
|
80
|
+
post = {
|
81
|
+
payment_method: {
|
82
|
+
credit_card: {
|
83
|
+
first_name: first_name,
|
84
|
+
last_name: last_name,
|
85
|
+
month: credit_card.month,
|
86
|
+
year: credit_card.year,
|
87
|
+
number: credit_card.number,
|
88
|
+
verification_value: credit_card.verification_value
|
89
|
+
}.compact
|
90
|
+
}
|
91
|
+
}
|
92
|
+
commit(:store, post)
|
93
|
+
end
|
94
|
+
|
95
|
+
def supports_scrubbing?
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
def scrub(transcript)
|
100
|
+
transcript.
|
101
|
+
gsub(%r((Authorization: Bearer )[a-zA-Z0-9._-]+)i, '\1[FILTERED]').
|
102
|
+
gsub(%r(("AppKey\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
103
|
+
gsub(%r(("AppSecret\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
104
|
+
gsub(%r(("accessToken\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
105
|
+
gsub(%r(("mid\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
106
|
+
gsub(%r(("siteId\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
107
|
+
gsub(%r(("environment\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
108
|
+
gsub(%r(("number\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
109
|
+
gsub(%r(("cardNumber\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
|
110
|
+
gsub(%r(("verification_value\\?":\\?")\d+), '\1[FILTERED]')
|
111
|
+
end
|
112
|
+
|
113
|
+
def inquire(authorization, options = {})
|
114
|
+
order_id, _currency = authorization.split('#')
|
115
|
+
commit(:inquire, {}, order_id, :get)
|
116
|
+
end
|
117
|
+
|
118
|
+
def add_metadata(post, options)
|
119
|
+
post[:Source] = 'Spreedly'
|
120
|
+
post[:ExtraData] = options[:extra_data] if options[:extra_data].present?
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def address(options)
|
126
|
+
options[:billing_address] || options[:address] || {}
|
127
|
+
end
|
128
|
+
|
129
|
+
def add_three_ds(post, options)
|
130
|
+
return unless three_d_secure = options[:three_d_secure]
|
131
|
+
|
132
|
+
post[:threeDSecure] = {
|
133
|
+
threeDsVersion: three_d_secure[:version],
|
134
|
+
EcommerceIndicator: three_d_secure[:eci],
|
135
|
+
authenticationValue: three_d_secure[:cavv],
|
136
|
+
directoryServerTransactionId: three_d_secure[:ds_transaction_id],
|
137
|
+
xid: three_d_secure[:xid],
|
138
|
+
authenticationValueAlgorithm: three_d_secure[:cavv_algorithm],
|
139
|
+
directoryResponseStatus: three_d_secure[:directory_response_status],
|
140
|
+
authenticationResponseStatus: three_d_secure[:authentication_response_status],
|
141
|
+
enrolled: three_d_secure[:enrolled]
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
def add_merchant_data(post, options)
|
146
|
+
post[:siteId] = @options[:site_id]
|
147
|
+
post[:mid] = @options[:mid]
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_base_data(post, options)
|
151
|
+
post[:isDeclined] = cast_bool(options[:is_declined])
|
152
|
+
post[:orderId] = options[:order_id]
|
153
|
+
post[:idempotencyKey] = options[:idempotency_key] || SecureRandom.uuid
|
154
|
+
post[:senseKey] = options[:sense_key]
|
155
|
+
end
|
156
|
+
|
157
|
+
def add_mit_data(post, options)
|
158
|
+
return if options[:is_mit].nil?
|
159
|
+
|
160
|
+
post[:isMIT] = cast_bool(options[:is_mit])
|
161
|
+
post[:isRecurring] = cast_bool(options[:is_recurring])
|
162
|
+
post[:expiryDateUtc] = options[:mit_expiry_date_utc]
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_customer_data(post, options)
|
166
|
+
post[:payer] = { email: options[:email] || 'NA', phone: phone_from(options) }.compact
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_address(post, payment, address, address_type)
|
170
|
+
return unless address.present?
|
171
|
+
|
172
|
+
first_name, last_name = names_from_address(address, payment)
|
173
|
+
|
174
|
+
post[address_type] = {
|
175
|
+
firstName: first_name,
|
176
|
+
lastName: last_name,
|
177
|
+
country: address[:country],
|
178
|
+
phone: address[:phone],
|
179
|
+
countryCode: address[:country],
|
180
|
+
addressLine1: address[:address1],
|
181
|
+
state: address[:state],
|
182
|
+
city: address[:city],
|
183
|
+
zipCode: address[:zip]
|
184
|
+
}.compact
|
185
|
+
end
|
186
|
+
|
187
|
+
def add_invoice(post, money, credit_card, options)
|
188
|
+
post[:transaction] = {
|
189
|
+
id: options[:order_id],
|
190
|
+
dynamicDescriptor: options[:description],
|
191
|
+
timestamp: Time.now.utc.iso8601,
|
192
|
+
timezoneUtcOffset: options[:timezone_utc_offset],
|
193
|
+
amount: money,
|
194
|
+
currency: (options[:currency] || currency(money)),
|
195
|
+
responseCode: options[:response_code],
|
196
|
+
responseCodeSource: options[:response_code_source] || '',
|
197
|
+
avsResultCode: options[:avs_result_code],
|
198
|
+
cvvResultCode: options[:cvv_result_code],
|
199
|
+
cavvResultCode: options[:cavv_result_code],
|
200
|
+
cardNotPresent: credit_card.is_a?(String) ? false : credit_card.verification_value.blank?
|
201
|
+
}.compact
|
202
|
+
end
|
203
|
+
|
204
|
+
def add_payment_method(post, credit_card, address, options)
|
205
|
+
payment_method = case credit_card
|
206
|
+
when String
|
207
|
+
{ Token: true, cardNumber: credit_card }
|
208
|
+
when CreditCard
|
209
|
+
if credit_card.number
|
210
|
+
{
|
211
|
+
holderName: credit_card.name,
|
212
|
+
cardType: 'CREDIT',
|
213
|
+
cardBrand: credit_card.brand&.upcase,
|
214
|
+
cardCountry: address[:country],
|
215
|
+
expirationMonth: credit_card.month,
|
216
|
+
expirationYear: credit_card.year,
|
217
|
+
cardBinNumber: credit_card.number[0..5],
|
218
|
+
cardLast4Digits: credit_card.number[-4..-1],
|
219
|
+
cardNumber: credit_card.number,
|
220
|
+
Token: false
|
221
|
+
}
|
222
|
+
else
|
223
|
+
{}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
post[:paymentMethod] = payment_method.compact
|
227
|
+
end
|
228
|
+
|
229
|
+
def names_from_address(address, payment_method)
|
230
|
+
split_names(address[:name]).tap do |names|
|
231
|
+
names[0] = payment_method&.first_name unless names[0].present? || payment_method.is_a?(String)
|
232
|
+
names[1] = payment_method&.last_name unless names[1].present? || payment_method.is_a?(String)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def phone_from(options)
|
237
|
+
options[:phone] || options.dig(:billing_address, :phone_number)
|
238
|
+
end
|
239
|
+
|
240
|
+
def access_token_valid?
|
241
|
+
@options[:access_token].present? && @options.fetch(:token_expires, 0) > DateTime.now.strftime('%Q').to_i
|
242
|
+
end
|
243
|
+
|
244
|
+
def fetch_access_token
|
245
|
+
params = { AppKey: @options[:app_key], AppSecret: @options[:app_secret] }
|
246
|
+
response = parse(ssl_post(url(:authenticate), params.to_json, headers))
|
247
|
+
|
248
|
+
@options[:access_token] = response[:accessToken]
|
249
|
+
@options[:token_expires] = response[:expires]
|
250
|
+
@options[:new_credentials] = true
|
251
|
+
|
252
|
+
Response.new(
|
253
|
+
response[:accessToken].present?,
|
254
|
+
message_from(response),
|
255
|
+
response,
|
256
|
+
test: test?,
|
257
|
+
error_code: response[:statusCode]
|
258
|
+
)
|
259
|
+
rescue ResponseError => e
|
260
|
+
raise OAuthResponseError.new(e)
|
261
|
+
end
|
262
|
+
|
263
|
+
def url(action, id = nil)
|
264
|
+
"#{test? ? test_url : live_url}#{ENDPOINTS_MAPPING[action] % id}"
|
265
|
+
end
|
266
|
+
|
267
|
+
def headers
|
268
|
+
{ 'Content-Type' => 'application/json' }.tap do |headers|
|
269
|
+
headers['Authorization'] = "Bearer #{@options[:access_token]}" if @options[:access_token]
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
def parse(body)
|
274
|
+
body = '{}' if body.blank?
|
275
|
+
|
276
|
+
JSON.parse(body).with_indifferent_access
|
277
|
+
rescue JSON::ParserError
|
278
|
+
{
|
279
|
+
errors: body,
|
280
|
+
status: 'Unable to parse JSON response'
|
281
|
+
}.with_indifferent_access
|
282
|
+
end
|
283
|
+
|
284
|
+
def commit(action, post, authorization = nil, method = :post)
|
285
|
+
MultiResponse.run do |r|
|
286
|
+
r.process { fetch_access_token } unless access_token_valid?
|
287
|
+
r.process do
|
288
|
+
api_request(action, post, authorization, method).tap do |response|
|
289
|
+
response.params.merge!(@options.slice(:access_token, :token_expires)) if @options[:new_credentials]
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def api_request(action, post, authorization = nil, method = :post)
|
296
|
+
response = parse ssl_request(method, url(action, authorization), post.to_json, headers)
|
297
|
+
|
298
|
+
Response.new(
|
299
|
+
success_from(action, response),
|
300
|
+
message_from(response),
|
301
|
+
response,
|
302
|
+
authorization: authorization_from(action, response, post),
|
303
|
+
test: test?,
|
304
|
+
error_code: error_code_from(action, response)
|
305
|
+
)
|
306
|
+
rescue ResponseError => e
|
307
|
+
response = parse(e.response.body)
|
308
|
+
# if current access_token is invalid then clean it
|
309
|
+
if e.response.code == '401'
|
310
|
+
@options[:access_token] = ''
|
311
|
+
@options[:new_credentials] = true
|
312
|
+
end
|
313
|
+
Response.new(false, message_from(response), response, test: test?)
|
314
|
+
end
|
315
|
+
|
316
|
+
def success_from(action, response)
|
317
|
+
case action
|
318
|
+
when :store then response.dig(:transaction, :payment_method, :token).present?
|
319
|
+
when :inquire then response[:id].present? && SUCCESS_MESSAGES.include?(response[:statusName])
|
320
|
+
when :void then response.empty?
|
321
|
+
else
|
322
|
+
response[:success] && SUCCESS_MESSAGES.include?(response[:status])
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def message_from(response)
|
327
|
+
response[:title] || response[:responseMessage] || response[:statusName] || response[:status]
|
328
|
+
end
|
329
|
+
|
330
|
+
def authorization_from(action, response, options)
|
331
|
+
if action == :store
|
332
|
+
response.dig(:transaction, :payment_method, :token)
|
333
|
+
elsif success_from(action, response)
|
334
|
+
[response[:orderId], options[:currency] || default_currency].compact.join('#')
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def error_code_from(action, response)
|
339
|
+
(response[:statusName] || response[:status]) unless success_from(action, response)
|
340
|
+
end
|
341
|
+
|
342
|
+
def cast_bool(value)
|
343
|
+
![false, 0, '', '0', 'f', 'F', 'false', 'FALSE'].include?(value)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
@@ -219,11 +219,13 @@ module ActiveMerchant #:nodoc:
|
|
219
219
|
|
220
220
|
success = success?(response)
|
221
221
|
|
222
|
-
Response.new(
|
222
|
+
Response.new(
|
223
|
+
success,
|
223
224
|
success ? 'Approved' : "Declined (Reason: #{response[:reason_code]} - #{response[:error_msg]} - #{response[:sys_err_msg]})",
|
224
225
|
response,
|
225
226
|
test: test?,
|
226
|
-
authorization: response[:order_id]
|
227
|
+
authorization: response[:order_id]
|
228
|
+
)
|
227
229
|
end
|
228
230
|
|
229
231
|
def parse(body)
|
@@ -5,19 +5,19 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
class_attribute :ogone_direct_test
|
6
6
|
class_attribute :ogone_direct_live
|
7
7
|
|
8
|
-
self.display_name = 'GlobalCollect'
|
8
|
+
self.display_name = 'Worldline (formerly GlobalCollect)'
|
9
9
|
self.homepage_url = 'http://www.globalcollect.com/'
|
10
10
|
|
11
11
|
self.test_url = 'https://eu.sandbox.api-ingenico.com'
|
12
|
-
self.preproduction_url = 'https://
|
13
|
-
self.live_url = 'https://
|
12
|
+
self.preproduction_url = 'https://api.preprod.connect.worldline-solutions.com'
|
13
|
+
self.live_url = 'https://api.connect.worldline-solutions.com'
|
14
14
|
self.ogone_direct_test = 'https://payment.preprod.direct.worldline-solutions.com'
|
15
15
|
self.ogone_direct_live = 'https://payment.direct.worldline-solutions.com'
|
16
16
|
|
17
17
|
self.supported_countries = %w[AD AE AG AI AL AM AO AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BW BY BZ CA CC CD CF CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HN HR HT HU ID IE IL IM IN IS IT JM JO JP KE KG KH KI KM KN KR KW KY KZ LA LB LC LI LK LR LS LT LU LV MA MC MD ME MF MG MH MK MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PL PN PS PT PW QA RE RO RS RU RW SA SB SC SE SG SH SI SJ SK SL SM SN SR ST SV SZ TC TD TG TH TJ TL TM TN TO TR TT TV TW TZ UA UG US UY UZ VC VE VG VI VN WF WS ZA ZM ZW]
|
18
18
|
self.default_currency = 'USD'
|
19
19
|
self.money_format = :cents
|
20
|
-
self.supported_cardtypes = %i[visa master american_express discover naranja cabal]
|
20
|
+
self.supported_cardtypes = %i[visa master american_express discover naranja cabal tuya]
|
21
21
|
|
22
22
|
def initialize(options = {})
|
23
23
|
requires!(options, :merchant_id, :api_key_id, :secret_api_key)
|
@@ -40,6 +40,7 @@ module ActiveMerchant #:nodoc:
|
|
40
40
|
add_creator_info(post, options)
|
41
41
|
add_fraud_fields(post, options)
|
42
42
|
add_external_cardholder_authentication_data(post, options)
|
43
|
+
add_threeds_exemption_data(post, options)
|
43
44
|
commit(:post, :authorize, post, options: options)
|
44
45
|
end
|
45
46
|
|
@@ -101,8 +102,8 @@ module ActiveMerchant #:nodoc:
|
|
101
102
|
'diners_club' => '132',
|
102
103
|
'cabal' => '135',
|
103
104
|
'naranja' => '136',
|
104
|
-
|
105
|
-
|
105
|
+
apple_pay: '302',
|
106
|
+
google_pay: '320'
|
106
107
|
}
|
107
108
|
|
108
109
|
def add_order(post, money, options, capture: false)
|
@@ -138,6 +139,7 @@ module ActiveMerchant #:nodoc:
|
|
138
139
|
airline_data['isThirdParty'] = options[:airline_data][:is_third_party] if options[:airline_data][:is_third_party]
|
139
140
|
airline_data['issueDate'] = options[:airline_data][:issue_date] if options[:airline_data][:issue_date]
|
140
141
|
airline_data['merchantCustomerId'] = options[:airline_data][:merchant_customer_id] if options[:airline_data][:merchant_customer_id]
|
142
|
+
airline_data['agentNumericCode'] = options[:airline_data][:agent_numeric_code] if options[:airline_data][:agent_numeric_code]
|
141
143
|
airline_data['flightLegs'] = add_flight_legs(airline_options)
|
142
144
|
airline_data['passengers'] = add_passengers(airline_options)
|
143
145
|
|
@@ -275,7 +277,7 @@ module ActiveMerchant #:nodoc:
|
|
275
277
|
if payment.is_a?(NetworkTokenizationCreditCard)
|
276
278
|
add_mobile_credit_card(post, payment, options, specifics_inputs, expirydate)
|
277
279
|
elsif payment.is_a?(CreditCard)
|
278
|
-
|
280
|
+
add_credit_card(post, payment, specifics_inputs, expirydate)
|
279
281
|
end
|
280
282
|
end
|
281
283
|
|
@@ -291,31 +293,32 @@ module ActiveMerchant #:nodoc:
|
|
291
293
|
end
|
292
294
|
|
293
295
|
def add_mobile_credit_card(post, payment, options, specifics_inputs, expirydate)
|
294
|
-
specifics_inputs['paymentProductId'] =
|
296
|
+
specifics_inputs['paymentProductId'] = BRAND_MAP[payment.source]
|
295
297
|
post['mobilePaymentMethodSpecificInput'] = specifics_inputs
|
296
|
-
|
298
|
+
|
299
|
+
if options[:use_encrypted_payment_data]
|
300
|
+
post['mobilePaymentMethodSpecificInput']['encryptedPaymentData'] = payment.payment_data
|
301
|
+
else
|
302
|
+
add_decrypted_payment_data(post, payment, options, expirydate)
|
303
|
+
end
|
297
304
|
end
|
298
305
|
|
299
306
|
def add_decrypted_payment_data(post, payment, options, expirydate)
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
'paymentMethod' => 'CARD'
|
316
|
-
}
|
317
|
-
end
|
318
|
-
post['mobilePaymentMethodSpecificInput']['decryptedPaymentData'] = data if data
|
307
|
+
data_type = payment.source == :apple_pay ? 'decrypted' : 'encrypted'
|
308
|
+
data = case payment.source
|
309
|
+
when :apple_pay
|
310
|
+
{
|
311
|
+
'cardholderName' => payment.name,
|
312
|
+
'cryptogram' => payment.payment_cryptogram,
|
313
|
+
'eci' => payment.eci,
|
314
|
+
'expiryDate' => expirydate,
|
315
|
+
'dpan' => payment.number
|
316
|
+
}
|
317
|
+
when :google_pay
|
318
|
+
payment.payment_data
|
319
|
+
end
|
320
|
+
|
321
|
+
post['mobilePaymentMethodSpecificInput']["#{data_type}PaymentData"] = data if data
|
319
322
|
end
|
320
323
|
|
321
324
|
def add_customer_data(post, options, payment = nil)
|
@@ -326,8 +329,8 @@ module ActiveMerchant #:nodoc:
|
|
326
329
|
post['order']['customer']['merchantCustomerId'] = options[:customer] if options[:customer]
|
327
330
|
post['order']['customer']['companyInformation']['name'] = options[:company] if options[:company]
|
328
331
|
post['order']['customer']['contactDetails']['emailAddress'] = options[:email] if options[:email]
|
329
|
-
if address = options[:billing_address] || options[:address]
|
330
|
-
post['order']['customer']['contactDetails']['phoneNumber'] = address[:phone]
|
332
|
+
if address = options[:billing_address] || options[:address] && (address[:phone])
|
333
|
+
post['order']['customer']['contactDetails']['phoneNumber'] = address[:phone]
|
331
334
|
end
|
332
335
|
end
|
333
336
|
|
@@ -337,8 +340,8 @@ module ActiveMerchant #:nodoc:
|
|
337
340
|
'countryCode' => address[:country]
|
338
341
|
}
|
339
342
|
post['customer']['contactDetails']['emailAddress'] = options[:email] if options[:email]
|
340
|
-
if address = options[:billing_address] || options[:address]
|
341
|
-
post['customer']['contactDetails']['phoneNumber'] = address[:phone]
|
343
|
+
if address = options[:billing_address] || options[:address] && (address[:phone])
|
344
|
+
post['customer']['contactDetails']['phoneNumber'] = address[:phone]
|
342
345
|
end
|
343
346
|
end
|
344
347
|
end
|
@@ -347,7 +350,8 @@ module ActiveMerchant #:nodoc:
|
|
347
350
|
shipping_address = options[:shipping_address]
|
348
351
|
if billing_address = options[:billing_address] || options[:address]
|
349
352
|
post['order']['customer']['billingAddress'] = {
|
350
|
-
'street' => truncate(billing_address[:address1], 50),
|
353
|
+
'street' => truncate(split_address(billing_address[:address1])[1], 50),
|
354
|
+
'houseNumber' => split_address(billing_address[:address1])[0],
|
351
355
|
'additionalInfo' => truncate(billing_address[:address2], 50),
|
352
356
|
'zip' => billing_address[:zip],
|
353
357
|
'city' => billing_address[:city],
|
@@ -357,7 +361,8 @@ module ActiveMerchant #:nodoc:
|
|
357
361
|
end
|
358
362
|
if shipping_address
|
359
363
|
post['order']['customer']['shippingAddress'] = {
|
360
|
-
'street' => truncate(shipping_address[:address1], 50),
|
364
|
+
'street' => truncate(split_address(shipping_address[:address1])[1], 50),
|
365
|
+
'houseNumber' => split_address(shipping_address[:address1])[0],
|
361
366
|
'additionalInfo' => truncate(shipping_address[:address2], 50),
|
362
367
|
'zip' => shipping_address[:zip],
|
363
368
|
'city' => shipping_address[:city],
|
@@ -374,7 +379,6 @@ module ActiveMerchant #:nodoc:
|
|
374
379
|
def add_fraud_fields(post, options)
|
375
380
|
fraud_fields = {}
|
376
381
|
fraud_fields.merge!(options[:fraud_fields]) if options[:fraud_fields]
|
377
|
-
fraud_fields[:customerIpAddress] = options[:ip] if options[:ip]
|
378
382
|
|
379
383
|
post['fraudFields'] = fraud_fields unless fraud_fields.empty?
|
380
384
|
end
|
@@ -403,6 +407,12 @@ module ActiveMerchant #:nodoc:
|
|
403
407
|
post['cardPaymentMethodSpecificInput']['threeDSecure']['externalCardholderAuthenticationData'] = authentication_data unless authentication_data.empty?
|
404
408
|
end
|
405
409
|
|
410
|
+
def add_threeds_exemption_data(post, options)
|
411
|
+
return unless options[:three_ds_exemption_type]
|
412
|
+
|
413
|
+
post['cardPaymentMethodSpecificInput']['transactionChannel'] = 'MOTO' if options[:three_ds_exemption_type] == 'moto'
|
414
|
+
end
|
415
|
+
|
406
416
|
def add_number_of_installments(post, options)
|
407
417
|
post['order']['additionalInput']['numberOfInstallments'] = options[:number_of_installments] if options[:number_of_installments]
|
408
418
|
end
|
@@ -512,8 +522,6 @@ module ActiveMerchant #:nodoc:
|
|
512
522
|
def success_from(action, response)
|
513
523
|
return false if response['errorId'] || response['error_message']
|
514
524
|
|
515
|
-
return %w(CAPTURED CAPTURE_REQUESTED).include?(response.dig('payment', 'status')) if response.dig('payment', 'paymentOutput', 'paymentMethod') == 'mobile'
|
516
|
-
|
517
525
|
case action
|
518
526
|
when :authorize
|
519
527
|
response.dig('payment', 'statusOutput', 'isAuthorized')
|