activemerchant 1.133.0 → 1.137.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +240 -0
  3. data/lib/active_merchant/billing/check.rb +2 -2
  4. data/lib/active_merchant/billing/compatibility.rb +4 -4
  5. data/lib/active_merchant/billing/credit_card.rb +11 -8
  6. data/lib/active_merchant/billing/credit_card_formatting.rb +4 -0
  7. data/lib/active_merchant/billing/credit_card_methods.rb +59 -6
  8. data/lib/active_merchant/billing/gateway.rb +9 -0
  9. data/lib/active_merchant/billing/gateways/adyen.rb +162 -43
  10. data/lib/active_merchant/billing/gateways/airwallex.rb +26 -12
  11. data/lib/active_merchant/billing/gateways/alelo.rb +23 -5
  12. data/lib/active_merchant/billing/gateways/authorize_net.rb +43 -35
  13. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +10 -6
  14. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -3
  15. data/lib/active_merchant/billing/gateways/axcessms.rb +6 -2
  16. data/lib/active_merchant/billing/gateways/banwire.rb +4 -2
  17. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -3
  18. data/lib/active_merchant/billing/gateways/blue_pay.rb +13 -5
  19. data/lib/active_merchant/billing/gateways/blue_snap.rb +5 -5
  20. data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +65 -20
  21. data/lib/active_merchant/billing/gateways/braintree_blue.rb +226 -73
  22. data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/card_connect.rb +5 -2
  24. data/lib/active_merchant/billing/gateways/card_stream.rb +4 -6
  25. data/lib/active_merchant/billing/gateways/cashnet.rb +1 -1
  26. data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
  27. data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +316 -0
  28. data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
  29. data/lib/active_merchant/billing/gateways/cecabank.rb +7 -240
  30. data/lib/active_merchant/billing/gateways/checkout_v2.rb +238 -34
  31. data/lib/active_merchant/billing/gateways/commerce_hub.rb +63 -6
  32. data/lib/active_merchant/billing/gateways/credorax.rb +3 -5
  33. data/lib/active_merchant/billing/gateways/cyber_source.rb +185 -47
  34. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +102 -58
  35. data/lib/active_merchant/billing/gateways/d_local.rb +26 -15
  36. data/lib/active_merchant/billing/gateways/data_cash.rb +21 -17
  37. data/lib/active_merchant/billing/gateways/datatrans.rb +279 -0
  38. data/lib/active_merchant/billing/gateways/decidir.rb +53 -18
  39. data/lib/active_merchant/billing/gateways/decidir_plus.rb +4 -1
  40. data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
  41. data/lib/active_merchant/billing/gateways/ebanx.rb +40 -36
  42. data/lib/active_merchant/billing/gateways/efsnet.rb +6 -2
  43. data/lib/active_merchant/billing/gateways/elavon.rb +99 -33
  44. data/lib/active_merchant/billing/gateways/element.rb +36 -7
  45. data/lib/active_merchant/billing/gateways/epay.rb +6 -2
  46. data/lib/active_merchant/billing/gateways/evo_ca.rb +6 -2
  47. data/lib/active_merchant/billing/gateways/eway.rb +4 -2
  48. data/lib/active_merchant/billing/gateways/eway_managed.rb +6 -2
  49. data/lib/active_merchant/billing/gateways/exact.rb +6 -2
  50. data/lib/active_merchant/billing/gateways/fat_zebra.rb +31 -3
  51. data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -2
  52. data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
  53. data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
  54. data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
  55. data/lib/active_merchant/billing/gateways/first_pay.rb +6 -172
  56. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -2
  57. data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +7 -3
  58. data/lib/active_merchant/billing/gateways/flex_charge.rb +347 -0
  59. data/lib/active_merchant/billing/gateways/garanti.rb +4 -2
  60. data/lib/active_merchant/billing/gateways/global_collect.rb +45 -37
  61. data/lib/active_merchant/billing/gateways/hi_pay.rb +286 -0
  62. data/lib/active_merchant/billing/gateways/hps.rb +1 -1
  63. data/lib/active_merchant/billing/gateways/iats_payments.rb +7 -2
  64. data/lib/active_merchant/billing/gateways/inspire.rb +6 -4
  65. data/lib/active_merchant/billing/gateways/instapay.rb +7 -4
  66. data/lib/active_merchant/billing/gateways/ipg.rb +9 -5
  67. data/lib/active_merchant/billing/gateways/iridium.rb +15 -5
  68. data/lib/active_merchant/billing/gateways/itransact.rb +6 -2
  69. data/lib/active_merchant/billing/gateways/iveri.rb +3 -3
  70. data/lib/active_merchant/billing/gateways/ixopay.rb +2 -2
  71. data/lib/active_merchant/billing/gateways/jetpay.rb +4 -2
  72. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +4 -2
  73. data/lib/active_merchant/billing/gateways/kushki.rb +72 -12
  74. data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -2
  75. data/lib/active_merchant/billing/gateways/litle.rb +33 -50
  76. data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
  77. data/lib/active_merchant/billing/gateways/maxipago.rb +2 -2
  78. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +8 -5
  79. data/lib/active_merchant/billing/gateways/merchant_ware.rb +11 -4
  80. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +11 -4
  81. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +19 -3
  82. data/lib/active_merchant/billing/gateways/mercury.rb +6 -2
  83. data/lib/active_merchant/billing/gateways/metrics_global.rb +8 -6
  84. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +1 -0
  85. data/lib/active_merchant/billing/gateways/migs.rb +6 -2
  86. data/lib/active_merchant/billing/gateways/mit.rb +8 -3
  87. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +18 -10
  88. data/lib/active_merchant/billing/gateways/monei.rb +1 -1
  89. data/lib/active_merchant/billing/gateways/moneris.rb +9 -3
  90. data/lib/active_merchant/billing/gateways/money_movers.rb +6 -2
  91. data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -4
  92. data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
  93. data/lib/active_merchant/billing/gateways/netbanx.rb +1 -3
  94. data/lib/active_merchant/billing/gateways/netbilling.rb +6 -2
  95. data/lib/active_merchant/billing/gateways/network_merchants.rb +6 -2
  96. data/lib/active_merchant/billing/gateways/nmi.rb +18 -6
  97. data/lib/active_merchant/billing/gateways/ogone.rb +6 -2
  98. data/lib/active_merchant/billing/gateways/openpay.rb +4 -2
  99. data/lib/active_merchant/billing/gateways/opp.rb +1 -2
  100. data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -2
  101. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +1 -3
  102. data/lib/active_merchant/billing/gateways/orbital.rb +83 -24
  103. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +7 -4
  104. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +6 -2
  105. data/lib/active_merchant/billing/gateways/pay_hub.rb +4 -2
  106. data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -2
  107. data/lib/active_merchant/billing/gateways/pay_secure.rb +6 -2
  108. data/lib/active_merchant/billing/gateways/pay_trace.rb +31 -18
  109. data/lib/active_merchant/billing/gateways/payeezy.rb +19 -8
  110. data/lib/active_merchant/billing/gateways/payex.rb +4 -2
  111. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
  112. data/lib/active_merchant/billing/gateways/payflow.rb +1 -3
  113. data/lib/active_merchant/billing/gateways/payment_express.rb +8 -4
  114. data/lib/active_merchant/billing/gateways/paymentez.rb +23 -11
  115. data/lib/active_merchant/billing/gateways/paysafe.rb +12 -11
  116. data/lib/active_merchant/billing/gateways/payscout.rb +7 -4
  117. data/lib/active_merchant/billing/gateways/paystation.rb +7 -3
  118. data/lib/active_merchant/billing/gateways/payway.rb +6 -2
  119. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +2 -2
  120. data/lib/active_merchant/billing/gateways/pin.rb +22 -4
  121. data/lib/active_merchant/billing/gateways/plexo.rb +49 -10
  122. data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
  123. data/lib/active_merchant/billing/gateways/priority.rb +6 -5
  124. data/lib/active_merchant/billing/gateways/psigate.rb +6 -2
  125. data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
  126. data/lib/active_merchant/billing/gateways/qbms.rb +6 -2
  127. data/lib/active_merchant/billing/gateways/quantum.rb +6 -2
  128. data/lib/active_merchant/billing/gateways/quickbooks.rb +6 -5
  129. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
  130. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +6 -2
  131. data/lib/active_merchant/billing/gateways/rapyd.rb +148 -46
  132. data/lib/active_merchant/billing/gateways/reach.rb +11 -4
  133. data/lib/active_merchant/billing/gateways/redsys.rb +2 -10
  134. data/lib/active_merchant/billing/gateways/redsys_rest.rb +507 -0
  135. data/lib/active_merchant/billing/gateways/s5.rb +3 -3
  136. data/lib/active_merchant/billing/gateways/safe_charge.rb +36 -16
  137. data/lib/active_merchant/billing/gateways/sage.rb +12 -4
  138. data/lib/active_merchant/billing/gateways/sage_pay.rb +79 -5
  139. data/lib/active_merchant/billing/gateways/sallie_mae.rb +6 -2
  140. data/lib/active_merchant/billing/gateways/secure_net.rb +6 -2
  141. data/lib/active_merchant/billing/gateways/secure_pay.rb +8 -6
  142. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -4
  143. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +6 -2
  144. data/lib/active_merchant/billing/gateways/securion_pay.rb +24 -10
  145. data/lib/active_merchant/billing/gateways/shift4.rb +17 -20
  146. data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
  147. data/lib/active_merchant/billing/gateways/simetrik.rb +17 -11
  148. data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -2
  149. data/lib/active_merchant/billing/gateways/smart_ps.rb +7 -4
  150. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +4 -2
  151. data/lib/active_merchant/billing/gateways/spreedly_core.rb +2 -4
  152. data/lib/active_merchant/billing/gateways/stripe.rb +53 -21
  153. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +199 -50
  154. data/lib/active_merchant/billing/gateways/sum_up.rb +223 -0
  155. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +4 -2
  156. data/lib/active_merchant/billing/gateways/telr.rb +3 -4
  157. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
  158. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +8 -16
  159. data/lib/active_merchant/billing/gateways/transact_pro.rb +1 -1
  160. data/lib/active_merchant/billing/gateways/trust_commerce.rb +6 -2
  161. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -8
  162. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -2
  163. data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
  164. data/lib/active_merchant/billing/gateways/vantiv_express.rb +587 -0
  165. data/lib/active_merchant/billing/gateways/verifi.rb +6 -2
  166. data/lib/active_merchant/billing/gateways/viaklix.rb +6 -2
  167. data/lib/active_merchant/billing/gateways/visanet_peru.rb +2 -2
  168. data/lib/active_merchant/billing/gateways/vpos.rb +3 -3
  169. data/lib/active_merchant/billing/gateways/wirecard.rb +7 -3
  170. data/lib/active_merchant/billing/gateways/wompi.rb +5 -0
  171. data/lib/active_merchant/billing/gateways/worldpay.rb +140 -73
  172. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +13 -10
  173. data/lib/active_merchant/billing/gateways/xpay.rb +242 -0
  174. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  175. data/lib/active_merchant/billing/response.rb +2 -2
  176. data/lib/active_merchant/connection.rb +3 -17
  177. data/lib/active_merchant/country.rb +1 -0
  178. data/lib/active_merchant/errors.rb +10 -0
  179. data/lib/active_merchant/version.rb +1 -1
  180. data/lib/support/gateway_support.rb +2 -2
  181. data/lib/support/ssl_verify.rb +4 -4
  182. data/lib/support/ssl_version.rb +6 -6
  183. metadata +30 -9
@@ -208,9 +208,9 @@ module ActiveMerchant #:nodoc:
208
208
  # The amount to be billed to the customer
209
209
  # for each payment in the subscription
210
210
  xml.tag!('amount', amount(options[:amount])) if options[:amount]
211
- if trial = options[:trial]
211
+ if trial = options[:trial] && (trial[:amount])
212
212
  # The amount to be charged for each payment during a trial period (conditional)
213
- xml.tag!('trialAmount', amount(trial[:amount])) if trial[:amount]
213
+ xml.tag!('trialAmount', amount(trial[:amount]))
214
214
  end
215
215
  # Contains either the customer’s credit card
216
216
  # or bank account payment information
@@ -260,9 +260,9 @@ module ActiveMerchant #:nodoc:
260
260
  # Contains information about the interval of time between payments
261
261
  add_interval(xml, options)
262
262
  add_duration(xml, options)
263
- if trial = options[:trial]
263
+ if trial = options[:trial] && (trial[:occurrences])
264
264
  # Number of billing occurrences or payments in the trial period (optional)
265
- xml.tag!('trialOccurrences', trial[:occurrences]) if trial[:occurrences]
265
+ xml.tag!('trialOccurrences', trial[:occurrences])
266
266
  end
267
267
  end
268
268
  end
@@ -393,9 +393,13 @@ module ActiveMerchant #:nodoc:
393
393
  test_mode = test? || message =~ /Test Mode/
394
394
  success = response[:result_code] == 'Ok'
395
395
 
396
- Response.new(success, message, response,
396
+ Response.new(
397
+ success,
398
+ message,
399
+ response,
397
400
  test: test_mode,
398
- authorization: response[:subscription_id])
401
+ authorization: response[:subscription_id]
402
+ )
399
403
  end
400
404
 
401
405
  def recurring_parse(action, xml)
@@ -695,9 +695,7 @@ module ActiveMerchant #:nodoc:
695
695
  add_order(xml, transaction[:order]) if transaction[:order].present?
696
696
 
697
697
  end
698
- if %i[auth_capture auth_only capture_only].include?(transaction[:type])
699
- xml.tag!('recurringBilling', transaction[:recurring_billing]) if transaction.has_key?(:recurring_billing)
700
- end
698
+ xml.tag!('recurringBilling', transaction[:recurring_billing]) if %i[auth_capture auth_only capture_only].include?(transaction[:type]) && transaction.has_key?(:recurring_billing)
701
699
  tag_unless_blank(xml, 'cardCode', transaction[:card_code]) unless %i[void refund prior_auth_capture].include?(transaction[:type])
702
700
  end
703
701
  end
@@ -71,9 +71,13 @@ module ActiveMerchant #:nodoc:
71
71
  message = "#{response[:reason]} - #{response[:return]}"
72
72
  authorization = response[:unique_id]
73
73
 
74
- Response.new(success, message, response,
74
+ Response.new(
75
+ success,
76
+ message,
77
+ response,
75
78
  authorization: authorization,
76
- test: (response[:mode] != 'LIVE'))
79
+ test: (response[:mode] != 'LIVE')
80
+ )
77
81
  end
78
82
 
79
83
  def parse(body)
@@ -89,11 +89,13 @@ module ActiveMerchant #:nodoc:
89
89
  response = json_error(raw_response)
90
90
  end
91
91
 
92
- Response.new(success?(response),
92
+ Response.new(
93
+ success?(response),
93
94
  response['message'],
94
95
  response,
95
96
  test: test?,
96
- authorization: response['code_auth'])
97
+ authorization: response['code_auth']
98
+ )
97
99
  end
98
100
 
99
101
  def success?(response)
@@ -228,7 +228,7 @@ module ActiveMerchant #:nodoc:
228
228
 
229
229
  if billing_address = options[:billing_address] || options[:address]
230
230
  post[:ordName] = billing_address[:name]
231
- post[:ordPhoneNumber] = billing_address[:phone]
231
+ post[:ordPhoneNumber] = billing_address[:phone] || billing_address[:phone_number]
232
232
  post[:ordAddress1] = billing_address[:address1]
233
233
  post[:ordAddress2] = billing_address[:address2]
234
234
  post[:ordCity] = billing_address[:city]
@@ -413,11 +413,15 @@ module ActiveMerchant #:nodoc:
413
413
  def post(data, use_profile_api = nil)
414
414
  response = parse(ssl_post((use_profile_api ? SECURE_PROFILE_URL : self.live_url), data))
415
415
  response[:customer_vault_id] = response[:customerCode] if response[:customerCode]
416
- build_response(success?(response), message_from(response), response,
416
+ build_response(
417
+ success?(response),
418
+ message_from(response),
419
+ response,
417
420
  test: test? || response[:authCode] == 'TEST',
418
421
  authorization: authorization_from(response),
419
422
  cvv_result: CVD_CODES[response[:cvdId]],
420
- avs_result: { code: AVS_CODES.include?(response[:avsId]) ? AVS_CODES[response[:avsId]] : response[:avsId] })
423
+ avs_result: { code: AVS_CODES.include?(response[:avsId]) ? AVS_CODES[response[:avsId]] : response[:avsId] }
424
+ )
421
425
  end
422
426
 
423
427
  def recurring_post(data)
@@ -344,14 +344,18 @@ module ActiveMerchant #:nodoc:
344
344
  success = parsed[:status] != 'error'
345
345
  message = parsed[:status]
346
346
 
347
- Response.new(success, message, parsed,
347
+ Response.new(
348
+ success,
349
+ message,
350
+ parsed,
348
351
  test: test?,
349
- authorization: parsed[:rebill_id])
352
+ authorization: parsed[:rebill_id]
353
+ )
350
354
  end
351
355
 
352
356
  def parse(body)
353
357
  # The bp20api has max one value per form field.
354
- response_fields = Hash[CGI::parse(body).map { |k, v| [k.upcase, v.first] }]
358
+ response_fields = CGI::parse(body).map { |k, v| [k.upcase, v.first] }.to_h
355
359
 
356
360
  return parse_recurring(response_fields) if response_fields.include? 'REBILL_ID'
357
361
 
@@ -364,11 +368,15 @@ module ActiveMerchant #:nodoc:
364
368
  # normalize message
365
369
  message = message_from(parsed)
366
370
  success = parsed[:response_code] == '1'
367
- Response.new(success, message, parsed,
371
+ Response.new(
372
+ success,
373
+ message,
374
+ parsed,
368
375
  test: test?,
369
376
  authorization: (parsed[:rebid] && parsed[:rebid] != '' ? parsed[:rebid] : parsed[:transaction_id]),
370
377
  avs_result: { code: parsed[:avs_result_code] },
371
- cvv_result: parsed[:card_code])
378
+ cvv_result: parsed[:card_code]
379
+ )
372
380
  end
373
381
 
374
382
  def message_from(parsed)
@@ -446,10 +446,10 @@ module ActiveMerchant
446
446
  end
447
447
 
448
448
  def parse_element(parsed, node)
449
- if !node.elements.empty?
450
- node.elements.each { |e| parse_element(parsed, e) }
451
- else
449
+ if node.elements.empty?
452
450
  parsed[node.name.downcase] = node.text
451
+ else
452
+ node.elements.each { |e| parse_element(parsed, e) }
453
453
  end
454
454
  end
455
455
 
@@ -459,8 +459,8 @@ module ActiveMerchant
459
459
  e.response
460
460
  end
461
461
 
462
- def commit(action, options, verb = :post, payment_method_details = PaymentMethodDetails.new())
463
- request = build_xml_request(action, payment_method_details) { |doc| yield(doc) }
462
+ def commit(action, options, verb = :post, payment_method_details = PaymentMethodDetails.new(), &block)
463
+ request = build_xml_request(action, payment_method_details, &block)
464
464
  response = api_request(action, request, verb, payment_method_details, options)
465
465
  parsed = parse(response)
466
466
 
@@ -18,10 +18,10 @@ module ActiveMerchant #:nodoc:
18
18
  "https://payments#{'.sandbox' if sandbox}.braintree-api.com/graphql"
19
19
  end
20
20
 
21
- def create_token_nonce_for_payment_method(payment_method)
21
+ def create_token_nonce_for_payment_method(payment_method, options = {})
22
22
  headers = {
23
23
  'Accept' => 'application/json',
24
- 'Authorization' => "Bearer #{client_token}",
24
+ 'Authorization' => "Bearer #{client_token(options)['authorizationFingerprint']}",
25
25
  'Content-Type' => 'application/json',
26
26
  'Braintree-Version' => '2018-05-10'
27
27
  }
@@ -29,19 +29,19 @@ module ActiveMerchant #:nodoc:
29
29
  json_response = JSON.parse(resp)
30
30
 
31
31
  message = json_response['errors'].map { |err| err['message'] }.join("\n") if json_response['errors'].present?
32
- token = json_response.dig('data', 'tokenizeUsBankAccount', 'paymentMethod', 'id')
32
+ token = token_from(payment_method, json_response)
33
33
 
34
34
  return token, message
35
35
  end
36
36
 
37
- def client_token
38
- base64_token = @braintree_gateway.client_token.generate
39
- JSON.parse(Base64.decode64(base64_token))['authorizationFingerprint']
37
+ def client_token(options = {})
38
+ base64_token = @braintree_gateway.client_token.generate({ merchant_account_id: options[:merchant_account_id] || @options[:merchant_account_id] }.compact)
39
+ JSON.parse(Base64.decode64(base64_token))
40
40
  end
41
41
 
42
42
  private
43
43
 
44
- def graphql_query
44
+ def graphql_bank_query
45
45
  <<-GRAPHQL
46
46
  mutation TokenizeUsBankAccount($input: TokenizeUsBankAccountInput!) {
47
47
  tokenizeUsBankAccount(input: $input) {
@@ -58,6 +58,23 @@ module ActiveMerchant #:nodoc:
58
58
  GRAPHQL
59
59
  end
60
60
 
61
+ def graphql_credit_query
62
+ <<-GRAPHQL
63
+ mutation TokenizeCreditCard($input: TokenizeCreditCardInput!) {
64
+ tokenizeCreditCard(input: $input) {
65
+ paymentMethod {
66
+ id
67
+ details {
68
+ ... on CreditCardDetails {
69
+ last4
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ GRAPHQL
76
+ end
77
+
61
78
  def billing_address_from_options
62
79
  return nil if options[:billing_address].blank?
63
80
 
@@ -72,7 +89,42 @@ module ActiveMerchant #:nodoc:
72
89
  }.compact
73
90
  end
74
91
 
92
+ def build_nonce_credit_card_request(payment_method)
93
+ billing_address = billing_address_from_options
94
+ key_replacements = { city: :locality, state: :region, zipCode: :postalCode }
95
+ billing_address&.transform_keys! { |key| key_replacements[key] || key }
96
+ {
97
+ creditCard: {
98
+ number: payment_method.number,
99
+ expirationYear: payment_method.year.to_s,
100
+ expirationMonth: payment_method.month.to_s.rjust(2, '0'),
101
+ cvv: payment_method.verification_value,
102
+ cardholderName: payment_method.name,
103
+ billingAddress: billing_address
104
+ }
105
+ }
106
+ end
107
+
75
108
  def build_nonce_request(payment_method)
109
+ input = payment_method.is_a?(Check) ? build_nonce_bank_request(payment_method) : build_nonce_credit_card_request(payment_method)
110
+ graphql_query = payment_method.is_a?(Check) ? graphql_bank_query : graphql_credit_query
111
+
112
+ {
113
+ clientSdkMetadata: {
114
+ platform: 'web',
115
+ source: 'client',
116
+ integration: 'custom',
117
+ sessionId: SecureRandom.uuid,
118
+ version: '3.83.0'
119
+ },
120
+ query: graphql_query,
121
+ variables: {
122
+ input: input
123
+ }
124
+ }.to_json
125
+ end
126
+
127
+ def build_nonce_bank_request(payment_method)
76
128
  input = {
77
129
  usBankAccount: {
78
130
  achMandate: options[:ach_mandate],
@@ -94,19 +146,12 @@ module ActiveMerchant #:nodoc:
94
146
  }
95
147
  end
96
148
 
97
- {
98
- clientSdkMetadata: {
99
- platform: 'web',
100
- source: 'client',
101
- integration: 'custom',
102
- sessionId: SecureRandom.uuid,
103
- version: '3.83.0'
104
- },
105
- query: graphql_query,
106
- variables: {
107
- input: input
108
- }
109
- }.to_json
149
+ input
150
+ end
151
+
152
+ def token_from(payment_method, response)
153
+ tokenized_field = payment_method.is_a?(Check) ? 'tokenizeUsBankAccount' : 'tokenizeCreditCard'
154
+ response.dig('data', tokenized_field, 'paymentMethod', 'id')
110
155
  end
111
156
  end
112
157
  end