swiss-crm-activemerchant 1.0.12
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 +7 -0
- data/CHANGELOG +4033 -0
- data/CONTRIBUTORS +568 -0
- data/MIT-LICENSE +20 -0
- data/README.md +252 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/avs_result.rb +95 -0
- data/lib/active_merchant/billing/base.rb +48 -0
- data/lib/active_merchant/billing/check.rb +112 -0
- data/lib/active_merchant/billing/compatibility.rb +118 -0
- data/lib/active_merchant/billing/credit_card.rb +451 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +512 -0
- data/lib/active_merchant/billing/cvv_result.rb +37 -0
- data/lib/active_merchant/billing/gateway.rb +332 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +774 -0
- data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
- data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
- data/lib/active_merchant/billing/gateways/allied_wallet.rb +205 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +1125 -0
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +424 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +977 -0
- data/lib/active_merchant/billing/gateways/axcessms.rb +242 -0
- data/lib/active_merchant/billing/gateways/balanced.rb +263 -0
- data/lib/active_merchant/billing/gateways/bambora_apac.rb +222 -0
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/banwire.rb +116 -0
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +397 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
- data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +474 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +238 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +57 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +549 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +644 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +190 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +272 -0
- data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +28 -0
- data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +952 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +19 -0
- data/lib/active_merchant/billing/gateways/bridge_pay.rb +244 -0
- data/lib/active_merchant/billing/gateways/cams.rb +230 -0
- data/lib/active_merchant/billing/gateways/card_connect.rb +338 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +21 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +394 -0
- data/lib/active_merchant/billing/gateways/cardknox.rb +327 -0
- data/lib/active_merchant/billing/gateways/cardprocess.rb +256 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +235 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +198 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +249 -0
- data/lib/active_merchant/billing/gateways/cenpos.rb +328 -0
- data/lib/active_merchant/billing/gateways/checkout.rb +212 -0
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +587 -0
- data/lib/active_merchant/billing/gateways/citrus_pay.rb +21 -0
- data/lib/active_merchant/billing/gateways/clearhaus.rb +219 -0
- data/lib/active_merchant/billing/gateways/commerce_hub.rb +366 -0
- data/lib/active_merchant/billing/gateways/commercegate.rb +142 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +230 -0
- data/lib/active_merchant/billing/gateways/creditcall.rb +272 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +526 -0
- data/lib/active_merchant/billing/gateways/ct_payment.rb +269 -0
- data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
- data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +1148 -0
- data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +454 -0
- data/lib/active_merchant/billing/gateways/d_local.rb +343 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +302 -0
- data/lib/active_merchant/billing/gateways/decidir.rb +358 -0
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +344 -0
- data/lib/active_merchant/billing/gateways/dibs.rb +199 -0
- data/lib/active_merchant/billing/gateways/digitzs.rb +295 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +346 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +215 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +475 -0
- data/lib/active_merchant/billing/gateways/element.rb +406 -0
- data/lib/active_merchant/billing/gateways/epay.rb +296 -0
- data/lib/active_merchant/billing/gateways/evo_ca.rb +307 -0
- data/lib/active_merchant/billing/gateways/eway.rb +226 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +289 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +578 -0
- data/lib/active_merchant/billing/gateways/exact.rb +219 -0
- data/lib/active_merchant/billing/gateways/ezic.rb +195 -0
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +223 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +158 -0
- data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
- data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +182 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +452 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +505 -0
- data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
- data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
- data/lib/active_merchant/billing/gateways/fluidpay.rb +275 -0
- data/lib/active_merchant/billing/gateways/forte.rb +286 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +256 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +580 -0
- data/lib/active_merchant/billing/gateways/global_transport.rb +193 -0
- data/lib/active_merchant/billing/gateways/hdfc.rb +205 -0
- data/lib/active_merchant/billing/gateways/hps.rb +472 -0
- data/lib/active_merchant/billing/gateways/iats_payments.rb +312 -0
- data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +159 -0
- data/lib/active_merchant/billing/gateways/ipg.rb +420 -0
- data/lib/active_merchant/billing/gateways/ipp.rb +176 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +467 -0
- data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
- data/lib/active_merchant/billing/gateways/iveri.rb +290 -0
- data/lib/active_merchant/billing/gateways/ixopay.rb +320 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +395 -0
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +432 -0
- data/lib/active_merchant/billing/gateways/klarna.rb +317 -0
- data/lib/active_merchant/billing/gateways/komoju.rb +115 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +297 -0
- data/lib/active_merchant/billing/gateways/latitude19.rb +412 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +448 -0
- data/lib/active_merchant/billing/gateways/litle.rb +643 -0
- data/lib/active_merchant/billing/gateways/mastercard.rb +286 -0
- data/lib/active_merchant/billing/gateways/maxipago.rb +220 -0
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +348 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +228 -0
- data/lib/active_merchant/billing/gateways/merchant_one.rb +110 -0
- data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +313 -0
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +284 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +248 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +352 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +293 -0
- data/lib/active_merchant/billing/gateways/micropayment.rb +182 -0
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
- data/lib/active_merchant/billing/gateways/migs.rb +329 -0
- data/lib/active_merchant/billing/gateways/mit.rb +260 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +215 -0
- data/lib/active_merchant/billing/gateways/moka.rb +290 -0
- data/lib/active_merchant/billing/gateways/monei.rb +424 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +488 -0
- data/lib/active_merchant/billing/gateways/money_movers.rb +150 -0
- data/lib/active_merchant/billing/gateways/mundipagg.rb +366 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +299 -0
- data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +163 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +180 -0
- data/lib/active_merchant/billing/gateways/netbanx.rb +376 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +229 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/network_merchants.rb +238 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +396 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +509 -0
- data/lib/active_merchant/billing/gateways/omise.rb +323 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +246 -0
- data/lib/active_merchant/billing/gateways/opp.rb +394 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +331 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +45 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +1267 -0
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +206 -0
- data/lib/active_merchant/billing/gateways/pagarme.rb +239 -0
- data/lib/active_merchant/billing/gateways/pago_facil.rb +120 -0
- data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_conex.rb +245 -0
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
- data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +206 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +110 -0
- data/lib/active_merchant/billing/gateways/pay_trace.rb +450 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +224 -0
- data/lib/active_merchant/billing/gateways/payeezy.rb +513 -0
- data/lib/active_merchant/billing/gateways/payex.rb +409 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +235 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +42 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +473 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +220 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +14 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +20 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +373 -0
- data/lib/active_merchant/billing/gateways/paymentez.rb +365 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +369 -0
- data/lib/active_merchant/billing/gateways/paynetworx.rb +228 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +718 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +69 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +136 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +272 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
- data/lib/active_merchant/billing/gateways/paypal_standard.rb +281 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +420 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +159 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +204 -0
- data/lib/active_merchant/billing/gateways/payu_in.rb +249 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +482 -0
- data/lib/active_merchant/billing/gateways/payway.rb +207 -0
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
- data/lib/active_merchant/billing/gateways/pin.rb +273 -0
- data/lib/active_merchant/billing/gateways/pixxels.rb +263 -0
- data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
- data/lib/active_merchant/billing/gateways/priority.rb +392 -0
- data/lib/active_merchant/billing/gateways/pro_pay.rb +325 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +227 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +295 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +302 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +274 -0
- data/lib/active_merchant/billing/gateways/quickbooks.rb +377 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +184 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +297 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +226 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +24 -0
- data/lib/active_merchant/billing/gateways/qvalent.rb +305 -0
- data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
- data/lib/active_merchant/billing/gateways/reach.rb +277 -0
- data/lib/active_merchant/billing/gateways/realex.rb +400 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +723 -0
- data/lib/active_merchant/billing/gateways/s5.rb +247 -0
- data/lib/active_merchant/billing/gateways/safe_charge.rb +298 -0
- data/lib/active_merchant/billing/gateways/sage.rb +446 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +434 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +141 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +260 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +191 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +290 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +103 -0
- data/lib/active_merchant/billing/gateways/securion_pay.rb +305 -0
- data/lib/active_merchant/billing/gateways/shift4.rb +345 -0
- data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +450 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +274 -0
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +354 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +866 -0
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +602 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +151 -0
- data/lib/active_merchant/billing/gateways/telr.rb +273 -0
- data/lib/active_merchant/billing/gateways/tns.rb +23 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +240 -0
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +612 -0
- data/lib/active_merchant/billing/gateways/transact_pro.rb +222 -0
- data/lib/active_merchant/billing/gateways/transax.rb +21 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +9 -0
- data/lib/active_merchant/billing/gateways/trexle.rb +221 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +500 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +24 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1612 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +367 -0
- data/lib/active_merchant/billing/gateways/vanco.rb +303 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +224 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +171 -0
- data/lib/active_merchant/billing/gateways/visanet_peru.rb +250 -0
- data/lib/active_merchant/billing/gateways/vpos.rb +223 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +235 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +430 -0
- data/lib/active_merchant/billing/gateways/wompi.rb +197 -0
- data/lib/active_merchant/billing/gateways/world_net.rb +345 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +1050 -0
- data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +208 -0
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +221 -0
- data/lib/active_merchant/billing/gateways.rb +14 -0
- data/lib/active_merchant/billing/model.rb +30 -0
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +39 -0
- data/lib/active_merchant/billing/payment_token.rb +21 -0
- data/lib/active_merchant/billing/rails.rb +3 -0
- data/lib/active_merchant/billing/response.rb +121 -0
- data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
- data/lib/active_merchant/billing.rb +16 -0
- data/lib/active_merchant/connection.rb +194 -0
- data/lib/active_merchant/country.rb +338 -0
- data/lib/active_merchant/empty.rb +20 -0
- data/lib/active_merchant/errors.rb +38 -0
- data/lib/active_merchant/net_http_ssl_connection.rb +11 -0
- data/lib/active_merchant/network_connection_retries.rb +78 -0
- data/lib/active_merchant/post_data.rb +26 -0
- data/lib/active_merchant/posts_data.rb +92 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/active_merchant.rb +63 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/certs/cacert.pem +3214 -0
- data/lib/support/gateway_support.rb +69 -0
- data/lib/support/outbound_hosts.rb +28 -0
- data/lib/support/ssl_verify.rb +88 -0
- data/lib/support/ssl_version.rb +86 -0
- metadata +506 -0
@@ -0,0 +1,1050 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class WorldpayGateway < Gateway
|
6
|
+
self.test_url = 'https://secure-test.worldpay.com/jsp/merchant/xml/paymentService.jsp'
|
7
|
+
self.live_url = 'https://secure.worldpay.com/jsp/merchant/xml/paymentService.jsp'
|
8
|
+
|
9
|
+
self.default_currency = 'GBP'
|
10
|
+
self.money_format = :cents
|
11
|
+
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 BM BN BO BR BS BT BW
|
12
|
+
BY BZ CA CC CF CH CK CL CM CN CO CR CV CX CY CZ DE DJ DK DO DZ EC EE EG EH ES ET FI FJ FK
|
13
|
+
FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GT GU GW GY HK HM HN HR HT HU ID IE IL
|
14
|
+
IM IN IO IS IT JE JM JO JP KE KG KH KI KM KN KR KW KY KZ LA LC LI LK LS LT LU LV MA MC MD
|
15
|
+
ME MG MH MK ML MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ
|
16
|
+
OM PA PE PF PH PK PL PN PR PT PW PY QA RE RO RS RU RW SA SB SC SE SG SI SK SL SM SN ST SV
|
17
|
+
SZ TC TD TF TG TH TJ TK TM TO TR TT TV TW TZ UA UG US UY UZ VA VC VE VI VN VU WF WS YE YT
|
18
|
+
ZA ZM)
|
19
|
+
self.supported_cardtypes = %i[visa master american_express discover jcb maestro elo naranja cabal unionpay]
|
20
|
+
self.currencies_without_fractions = %w(HUF IDR JPY KRW BEF XOF XAF XPF GRD GNF ITL LUF MGA MGF PYG PTE RWF ESP TRL VND KMF)
|
21
|
+
self.currencies_with_three_decimal_places = %w(BHD KWD OMR TND LYD JOD IQD)
|
22
|
+
self.homepage_url = 'http://www.worldpay.com/'
|
23
|
+
self.display_name = 'Worldpay Global'
|
24
|
+
|
25
|
+
NETWORK_TOKEN_TYPE = {
|
26
|
+
apple_pay: 'APPLEPAY',
|
27
|
+
google_pay: 'GOOGLEPAY',
|
28
|
+
network_token: 'NETWORKTOKEN'
|
29
|
+
}
|
30
|
+
|
31
|
+
CARD_CODES = {
|
32
|
+
'visa' => 'VISA-SSL',
|
33
|
+
'master' => 'ECMC-SSL',
|
34
|
+
'discover' => 'DISCOVER-SSL',
|
35
|
+
'american_express' => 'AMEX-SSL',
|
36
|
+
'jcb' => 'JCB-SSL',
|
37
|
+
'maestro' => 'MAESTRO-SSL',
|
38
|
+
'diners_club' => 'DINERS-SSL',
|
39
|
+
'elo' => 'ELO-SSL',
|
40
|
+
'naranja' => 'NARANJA-SSL',
|
41
|
+
'cabal' => 'CABAL-SSL',
|
42
|
+
'unionpay' => 'CHINAUNIONPAY-SSL',
|
43
|
+
'unknown' => 'CARD-SSL'
|
44
|
+
}
|
45
|
+
|
46
|
+
AVS_CODE_MAP = {
|
47
|
+
'A' => 'M', # Match
|
48
|
+
'B' => 'P', # Postcode matches, address not verified
|
49
|
+
'C' => 'Z', # Postcode matches, address does not match
|
50
|
+
'D' => 'B', # Address matched; postcode not checked
|
51
|
+
'E' => 'I', # Address and postal code not checked
|
52
|
+
'F' => 'A', # Address matches, postcode does not match
|
53
|
+
'G' => 'C', # Address does not match, postcode not checked
|
54
|
+
'H' => 'I', # Address and postcode not provided
|
55
|
+
'I' => 'C', # Address not checked postcode does not match
|
56
|
+
'J' => 'C', # Address and postcode does not match
|
57
|
+
}
|
58
|
+
|
59
|
+
CVC_CODE_MAP = {
|
60
|
+
'A' => 'M', # CVV matches
|
61
|
+
'B' => 'P', # Not provided
|
62
|
+
'C' => 'P', # Not checked
|
63
|
+
'D' => 'N', # Does not match
|
64
|
+
}
|
65
|
+
|
66
|
+
def initialize(options = {})
|
67
|
+
requires!(options, :login, :password)
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
def purchase(money, payment_method, options = {})
|
72
|
+
MultiResponse.run do |r|
|
73
|
+
r.process { authorize(money, payment_method, options) }
|
74
|
+
r.process { capture(money, r.authorization, options.merge(authorization_validated: true)) } unless options[:skip_capture]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def authorize(money, payment_method, options = {})
|
79
|
+
requires!(options, :order_id)
|
80
|
+
payment_details = payment_details(payment_method)
|
81
|
+
authorize_request(money, payment_method, payment_details.merge(options))
|
82
|
+
end
|
83
|
+
|
84
|
+
def capture(money, authorization, options = {})
|
85
|
+
authorization = order_id_from_authorization(authorization.to_s)
|
86
|
+
MultiResponse.run do |r|
|
87
|
+
r.process { inquire_request(authorization, options, 'AUTHORISED', 'CAPTURED') } unless options[:authorization_validated]
|
88
|
+
if r.params
|
89
|
+
authorization_currency = r.params['amount_currency_code']
|
90
|
+
options = options.merge(currency: authorization_currency) if authorization_currency.present?
|
91
|
+
end
|
92
|
+
r.process { capture_request(money, authorization, options) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def void(authorization, options = {})
|
97
|
+
authorization = order_id_from_authorization(authorization.to_s)
|
98
|
+
MultiResponse.run do |r|
|
99
|
+
r.process { inquire_request(authorization, options, 'AUTHORISED') } unless options[:authorization_validated]
|
100
|
+
r.process { cancel_request(authorization, options) }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def refund(money, authorization, options = {})
|
105
|
+
authorization = order_id_from_authorization(authorization.to_s)
|
106
|
+
success_criteria = %w(CAPTURED SETTLED SETTLED_BY_MERCHANT SENT_FOR_REFUND)
|
107
|
+
success_criteria.push('AUTHORIZED') if options[:cancel_or_refund]
|
108
|
+
response = MultiResponse.run do |r|
|
109
|
+
r.process { inquire_request(authorization, options, *success_criteria) } unless options[:authorization_validated]
|
110
|
+
r.process { refund_request(money, authorization, options) }
|
111
|
+
end
|
112
|
+
|
113
|
+
if !response.success? && options[:force_full_refund_if_unsettled] &&
|
114
|
+
response.params['last_event'] == 'AUTHORISED'
|
115
|
+
void(authorization, options)
|
116
|
+
else
|
117
|
+
response
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Credits only function on a Merchant ID/login/profile flagged for Payouts
|
122
|
+
# aka Credit Fund Transfers (CFT), whereas normal purchases, refunds,
|
123
|
+
# and other transactions should be performed on a normal eCom-flagged
|
124
|
+
# merchant ID.
|
125
|
+
def credit(money, payment_method, options = {})
|
126
|
+
payment_details = payment_details(payment_method)
|
127
|
+
if options[:fast_fund_credit]
|
128
|
+
fast_fund_credit_request(money, payment_method, payment_details.merge(credit: true, **options))
|
129
|
+
else
|
130
|
+
credit_request(money, payment_method, payment_details.merge(credit: true, **options))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def verify(payment_method, options = {})
|
135
|
+
amount = (eligible_for_0_auth?(payment_method, options) ? 0 : 100)
|
136
|
+
MultiResponse.run(:use_first_response) do |r|
|
137
|
+
r.process { authorize(amount, payment_method, options) }
|
138
|
+
r.process(:ignore_result) { void(r.authorization, options.merge(authorization_validated: true)) }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def store(credit_card, options = {})
|
143
|
+
requires!(options, :customer)
|
144
|
+
store_request(credit_card, options)
|
145
|
+
end
|
146
|
+
|
147
|
+
def inquire(authorization, options = {})
|
148
|
+
order_id = order_id_from_authorization(authorization.to_s) || options[:order_id]
|
149
|
+
commit('direct_inquiry', build_order_inquiry_request(order_id, options), :ok, options)
|
150
|
+
end
|
151
|
+
|
152
|
+
def supports_scrubbing
|
153
|
+
true
|
154
|
+
end
|
155
|
+
|
156
|
+
def supports_network_tokenization?
|
157
|
+
true
|
158
|
+
end
|
159
|
+
|
160
|
+
def scrub(transcript)
|
161
|
+
transcript.
|
162
|
+
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
163
|
+
gsub(%r((<cardNumber>)\d+(</cardNumber>)), '\1[FILTERED]\2').
|
164
|
+
gsub(%r((<cvc>)[^<]+(</cvc>)), '\1[FILTERED]\2').
|
165
|
+
gsub(%r((<tokenNumber>)\d+(</tokenNumber>)), '\1[FILTERED]\2').
|
166
|
+
gsub(%r((<cryptogram>)[^<]+(</cryptogram>)), '\1[FILTERED]\2')
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
def authorize_request(money, payment_method, options)
|
172
|
+
commit('authorize', build_authorization_request(money, payment_method, options), 'AUTHORISED', 'CAPTURED', options)
|
173
|
+
end
|
174
|
+
|
175
|
+
def capture_request(money, authorization, options)
|
176
|
+
commit('capture', build_capture_request(money, authorization, options), 'CAPTURED', :ok, options)
|
177
|
+
end
|
178
|
+
|
179
|
+
def cancel_request(authorization, options)
|
180
|
+
commit('cancel', build_void_request(authorization, options), :ok, options)
|
181
|
+
end
|
182
|
+
|
183
|
+
def inquire_request(authorization, options, *success_criteria)
|
184
|
+
commit('inquiry', build_order_inquiry_request(authorization, options), *success_criteria, options)
|
185
|
+
end
|
186
|
+
|
187
|
+
def refund_request(money, authorization, options)
|
188
|
+
commit('refund', build_refund_request(money, authorization, options), :ok, 'SENT_FOR_REFUND', options)
|
189
|
+
end
|
190
|
+
|
191
|
+
def credit_request(money, payment_method, options)
|
192
|
+
commit('credit', build_authorization_request(money, payment_method, options), :ok, 'SENT_FOR_REFUND', options)
|
193
|
+
end
|
194
|
+
|
195
|
+
def fast_fund_credit_request(money, payment_method, options)
|
196
|
+
commit('fast_credit', build_fast_fund_credit_request(money, payment_method, options), :ok, 'PUSH_APPROVED', options)
|
197
|
+
end
|
198
|
+
|
199
|
+
def store_request(credit_card, options)
|
200
|
+
commit('store', build_store_request(credit_card, options), options)
|
201
|
+
end
|
202
|
+
|
203
|
+
def build_request
|
204
|
+
xml = Builder::XmlMarkup.new indent: 2
|
205
|
+
xml.instruct! :xml, encoding: 'UTF-8'
|
206
|
+
xml.declare! :DOCTYPE, :paymentService, :PUBLIC, '-//WorldPay//DTD WorldPay PaymentService v1//EN', 'http://dtd.worldpay.com/paymentService_v1.dtd'
|
207
|
+
xml.paymentService 'version' => '1.4', 'merchantCode' => @options[:login] do
|
208
|
+
yield xml
|
209
|
+
end
|
210
|
+
xml.target!
|
211
|
+
end
|
212
|
+
|
213
|
+
def build_order_modify_request(authorization)
|
214
|
+
build_request do |xml|
|
215
|
+
xml.modify do
|
216
|
+
xml.orderModification 'orderCode' => authorization do
|
217
|
+
yield xml
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def build_order_inquiry_request(authorization, options)
|
224
|
+
build_request do |xml|
|
225
|
+
xml.inquiry do
|
226
|
+
xml.orderInquiry 'orderCode' => authorization
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def build_authorization_request(money, payment_method, options)
|
232
|
+
build_request do |xml|
|
233
|
+
xml.submit do
|
234
|
+
xml.order order_tag_attributes(options) do
|
235
|
+
xml.description(options[:description].blank? ? 'Purchase' : options[:description])
|
236
|
+
add_amount(xml, money, options)
|
237
|
+
add_order_content(xml, options)
|
238
|
+
add_payment_method(xml, money, payment_method, options)
|
239
|
+
add_shopper(xml, options)
|
240
|
+
add_statement_narrative(xml, options)
|
241
|
+
add_risk_data(xml, options[:risk_data]) if options[:risk_data]
|
242
|
+
add_sub_merchant_data(xml, options[:sub_merchant_data]) if options[:sub_merchant_data]
|
243
|
+
add_hcg_additional_data(xml, options) if options[:hcg_additional_data]
|
244
|
+
add_instalments_data(xml, options) if options[:instalments]
|
245
|
+
add_additional_data(xml, money, options) if options[:level_2_data] || options[:level_3_data]
|
246
|
+
add_moto_flag(xml, options) if options.dig(:metadata, :manual_entry)
|
247
|
+
add_additional_3ds_data(xml, options) if options[:execute_threed] && options[:three_ds_version] && options[:three_ds_version] =~ /^2/
|
248
|
+
add_3ds_exemption(xml, options) if options[:exemption_type]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def add_additional_data(xml, amount, options)
|
255
|
+
level_two_data = options[:level_2_data] || {}
|
256
|
+
level_three_data = options[:level_3_data] || {}
|
257
|
+
level_two_and_three_data = level_two_data.merge(level_three_data).symbolize_keys
|
258
|
+
|
259
|
+
xml.branchSpecificExtension do
|
260
|
+
xml.purchase do
|
261
|
+
add_level_two_and_three_data(xml, amount, level_two_and_three_data)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def add_level_two_and_three_data(xml, amount, data)
|
267
|
+
xml.invoiceReferenceNumber data[:invoice_reference_number] if data.include?(:invoice_reference_number)
|
268
|
+
xml.customerReference data[:customer_reference] if data.include?(:customer_reference)
|
269
|
+
xml.cardAcceptorTaxId data[:card_acceptor_tax_id] if data.include?(:card_acceptor_tax_id)
|
270
|
+
|
271
|
+
{
|
272
|
+
sales_tax: 'salesTax',
|
273
|
+
discount_amount: 'discountAmount',
|
274
|
+
shipping_amount: 'shippingAmount',
|
275
|
+
duty_amount: 'dutyAmount'
|
276
|
+
}.each do |key, tag|
|
277
|
+
next unless data.include?(key)
|
278
|
+
|
279
|
+
xml.tag! tag do
|
280
|
+
data_amount = data[key].symbolize_keys
|
281
|
+
add_amount(xml, data_amount[:amount].to_i, data_amount)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
xml.discountName data[:discount_name] if data.include?(:discount_name)
|
286
|
+
xml.discountCode data[:discount_code] if data.include?(:discount_code)
|
287
|
+
|
288
|
+
add_date_element(xml, 'shippingDate', data[:shipping_date]) if data.include?(:shipping_date)
|
289
|
+
|
290
|
+
if data.include?(:shipping_courier)
|
291
|
+
xml.shippingCourier(
|
292
|
+
data[:shipping_courier][:priority],
|
293
|
+
data[:shipping_courier][:tracking_number],
|
294
|
+
data[:shipping_courier][:name]
|
295
|
+
)
|
296
|
+
end
|
297
|
+
|
298
|
+
add_optional_data_level_two_and_three(xml, data)
|
299
|
+
|
300
|
+
if data.include?(:item) && data[:item].kind_of?(Array)
|
301
|
+
data[:item].each { |item| add_items_into_level_three_data(xml, item.symbolize_keys) }
|
302
|
+
elsif data.include?(:item)
|
303
|
+
add_items_into_level_three_data(xml, data[:item].symbolize_keys)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def add_items_into_level_three_data(xml, item)
|
308
|
+
xml.item do
|
309
|
+
xml.description item[:description] if item[:description]
|
310
|
+
xml.productCode item[:product_code] if item[:product_code]
|
311
|
+
xml.commodityCode item[:commodity_code] if item[:commodity_code]
|
312
|
+
xml.quantity item[:quantity] if item[:quantity]
|
313
|
+
|
314
|
+
{
|
315
|
+
unit_cost: 'unitCost',
|
316
|
+
item_total: 'itemTotal',
|
317
|
+
item_total_with_tax: 'itemTotalWithTax',
|
318
|
+
item_discount_amount: 'itemDiscountAmount',
|
319
|
+
tax_amount: 'taxAmount'
|
320
|
+
}.each do |key, tag|
|
321
|
+
next unless item.include?(key)
|
322
|
+
|
323
|
+
xml.tag! tag do
|
324
|
+
data_amount = item[key].symbolize_keys
|
325
|
+
add_amount(xml, data_amount[:amount].to_i, data_amount)
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def add_optional_data_level_two_and_three(xml, data)
|
332
|
+
xml.shipFromPostalCode data[:ship_from_postal_code] if data.include?(:ship_from_postal_code)
|
333
|
+
xml.destinationPostalCode data[:destination_postal_code] if data.include?(:destination_postal_code)
|
334
|
+
xml.destinationCountryCode data[:destination_country_code] if data.include?(:destination_country_code)
|
335
|
+
add_date_element(xml, 'orderDate', data[:order_date].symbolize_keys) if data.include?(:order_date)
|
336
|
+
xml.taxExempt data[:tax_exempt] if data.include?(:tax_exempt)
|
337
|
+
end
|
338
|
+
|
339
|
+
def order_tag_attributes(options)
|
340
|
+
{ 'orderCode' => clean_order_id(options[:order_id]), 'installationId' => options[:inst_id] || @options[:inst_id] }.reject { |_, v| !v.present? }
|
341
|
+
end
|
342
|
+
|
343
|
+
def clean_order_id(order_id)
|
344
|
+
order_id.to_s.gsub(/(\s|\||<|>|'|")/, '')[0..64]
|
345
|
+
end
|
346
|
+
|
347
|
+
def add_order_content(xml, options)
|
348
|
+
return unless options[:order_content]
|
349
|
+
|
350
|
+
xml.orderContent do
|
351
|
+
xml.cdata! options[:order_content]
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
def build_capture_request(money, authorization, options)
|
356
|
+
build_order_modify_request(authorization) do |xml|
|
357
|
+
xml.capture do
|
358
|
+
time = Time.now
|
359
|
+
xml.date 'dayOfMonth' => time.day, 'month' => time.month, 'year' => time.year
|
360
|
+
add_amount(xml, money, options)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def build_void_request(authorization, options)
|
366
|
+
if options[:cancel_or_refund]
|
367
|
+
build_order_modify_request(authorization, &:cancelOrRefund)
|
368
|
+
else
|
369
|
+
build_order_modify_request(authorization, &:cancel)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
def build_refund_request(money, authorization, options)
|
374
|
+
build_order_modify_request(authorization) do |xml|
|
375
|
+
if options[:cancel_or_refund]
|
376
|
+
# Worldpay docs claim amount must be passed. This causes an error.
|
377
|
+
xml.cancelOrRefund # { add_amount(xml, money, options.merge(debit_credit_indicator: 'credit')) }
|
378
|
+
else
|
379
|
+
xml.refund do
|
380
|
+
add_amount(xml, money, options.merge(debit_credit_indicator: 'credit'))
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def build_store_request(credit_card, options)
|
387
|
+
build_request do |xml|
|
388
|
+
xml.submit do
|
389
|
+
xml.paymentTokenCreate do
|
390
|
+
add_authenticated_shopper_id(xml, options)
|
391
|
+
xml.createToken
|
392
|
+
xml.paymentInstrument do
|
393
|
+
xml.cardDetails do
|
394
|
+
add_card(xml, credit_card, options)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
add_transaction_identifier(xml, options) if network_transaction_id(options)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
def network_transaction_id(options)
|
404
|
+
options[:stored_credential_transaction_id] || options.dig(:stored_credential, :network_transaction_id)
|
405
|
+
end
|
406
|
+
|
407
|
+
def add_transaction_identifier(xml, options)
|
408
|
+
xml.storedCredentials 'usage' => 'FIRST' do
|
409
|
+
xml.schemeTransactionIdentifier network_transaction_id(options)
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
def build_fast_fund_credit_request(money, payment_method, options)
|
414
|
+
build_request do |xml|
|
415
|
+
xml.submit do
|
416
|
+
xml.order order_tag_attributes(options) do
|
417
|
+
xml.description(options[:description].blank? ? 'Fast Fund Credit' : options[:description])
|
418
|
+
add_amount(xml, money, options)
|
419
|
+
add_order_content(xml, options)
|
420
|
+
add_payment_details_for_ff_credit(xml, payment_method, options)
|
421
|
+
add_shopper_id(xml, options)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def add_payment_details_for_ff_credit(xml, payment_method, options)
|
428
|
+
xml.paymentDetails do
|
429
|
+
xml.tag! 'FF_DISBURSE-SSL' do
|
430
|
+
if payment_method.is_a?(CreditCard)
|
431
|
+
add_card_for_ff_credit(xml, payment_method, options)
|
432
|
+
else
|
433
|
+
add_token_for_ff_credit(xml, payment_method, options)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
def add_card_for_ff_credit(xml, payment_method, options)
|
440
|
+
xml.recipient do
|
441
|
+
xml.paymentInstrument do
|
442
|
+
xml.cardDetails do
|
443
|
+
add_card(xml, payment_method, options)
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def add_token_for_ff_credit(xml, payment_method, options)
|
450
|
+
return unless payment_method.is_a?(String)
|
451
|
+
|
452
|
+
token_details = token_details_from_authorization(payment_method)
|
453
|
+
|
454
|
+
xml.tag! 'recipient', 'tokenScope' => token_details[:token_scope] do
|
455
|
+
xml.paymentTokenID token_details[:token_id]
|
456
|
+
add_authenticated_shopper_id(xml, token_details)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def add_additional_3ds_data(xml, options)
|
461
|
+
additional_data = { 'dfReferenceId' => options[:session_id] }
|
462
|
+
additional_data['challengeWindowSize'] = options[:browser_size] if options[:browser_size]
|
463
|
+
|
464
|
+
xml.additional3DSData additional_data
|
465
|
+
end
|
466
|
+
|
467
|
+
def add_3ds_exemption(xml, options)
|
468
|
+
xml.exemption 'type' => options[:exemption_type], 'placement' => options[:exemption_placement] || 'AUTHORISATION'
|
469
|
+
end
|
470
|
+
|
471
|
+
def add_risk_data(xml, risk_data)
|
472
|
+
xml.riskData do
|
473
|
+
add_authentication_risk_data(xml, risk_data[:authentication_risk_data])
|
474
|
+
add_shopper_account_risk_data(xml, risk_data[:shopper_account_risk_data])
|
475
|
+
add_transaction_risk_data(xml, risk_data[:transaction_risk_data])
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def add_authentication_risk_data(xml, authentication_risk_data)
|
480
|
+
return unless authentication_risk_data
|
481
|
+
|
482
|
+
timestamp = authentication_risk_data.fetch(:authentication_date, {})
|
483
|
+
|
484
|
+
xml.authenticationRiskData('authenticationMethod' => authentication_risk_data[:authentication_method]) do
|
485
|
+
xml.authenticationTimestamp do
|
486
|
+
xml.date(
|
487
|
+
'dayOfMonth' => timestamp[:day_of_month],
|
488
|
+
'month' => timestamp[:month],
|
489
|
+
'year' => timestamp[:year],
|
490
|
+
'hour' => timestamp[:hour],
|
491
|
+
'minute' => timestamp[:minute],
|
492
|
+
'second' => timestamp[:second]
|
493
|
+
)
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
def add_sub_merchant_data(xml, options)
|
499
|
+
xml.subMerchantData do
|
500
|
+
xml.pfId options[:pf_id] if options[:pf_id]
|
501
|
+
xml.subName options[:sub_name] if options[:sub_name]
|
502
|
+
xml.subId options[:sub_id] if options[:sub_id]
|
503
|
+
xml.subStreet options[:sub_street] if options[:sub_street]
|
504
|
+
xml.subCity options[:sub_city] if options[:sub_city]
|
505
|
+
xml.subState options[:sub_state] if options[:sub_state]
|
506
|
+
xml.subCountryCode options[:sub_country_code] if options[:sub_country_code]
|
507
|
+
xml.subPostalCode options[:sub_postal_code] if options[:sub_postal_code]
|
508
|
+
xml.subTaxId options[:sub_tax_id] if options[:sub_tax_id]
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
def add_shopper_account_risk_data(xml, shopper_account_risk_data)
|
513
|
+
return unless shopper_account_risk_data
|
514
|
+
|
515
|
+
data = {
|
516
|
+
'transactionsAttemptedLastDay' => shopper_account_risk_data[:transactions_attempted_last_day],
|
517
|
+
'transactionsAttemptedLastYear' => shopper_account_risk_data[:transactions_attempted_last_year],
|
518
|
+
'purchasesCompletedLastSixMonths' => shopper_account_risk_data[:purchases_completed_last_six_months],
|
519
|
+
'addCardAttemptsLastDay' => shopper_account_risk_data[:add_card_attempts_last_day],
|
520
|
+
'previousSuspiciousActivity' => shopper_account_risk_data[:previous_suspicious_activity],
|
521
|
+
'shippingNameMatchesAccountName' => shopper_account_risk_data[:shipping_name_matches_account_name],
|
522
|
+
'shopperAccountAgeIndicator' => shopper_account_risk_data[:shopper_account_age_indicator],
|
523
|
+
'shopperAccountChangeIndicator' => shopper_account_risk_data[:shopper_account_change_indicator],
|
524
|
+
'shopperAccountPasswordChangeIndicator' => shopper_account_risk_data[:shopper_account_password_change_indicator],
|
525
|
+
'shopperAccountShippingAddressUsageIndicator' => shopper_account_risk_data[:shopper_account_shipping_address_usage_indicator],
|
526
|
+
'shopperAccountPaymentAccountIndicator' => shopper_account_risk_data[:shopper_account_payment_account_indicator]
|
527
|
+
}.reject { |_k, v| v.nil? }
|
528
|
+
|
529
|
+
xml.shopperAccountRiskData(data) do
|
530
|
+
add_date_element(xml, 'shopperAccountCreationDate', shopper_account_risk_data[:shopper_account_creation_date])
|
531
|
+
add_date_element(xml, 'shopperAccountModificationDate', shopper_account_risk_data[:shopper_account_modification_date])
|
532
|
+
add_date_element(xml, 'shopperAccountPasswordChangeDate', shopper_account_risk_data[:shopper_account_password_change_date])
|
533
|
+
add_date_element(xml, 'shopperAccountShippingAddressFirstUseDate', shopper_account_risk_data[:shopper_account_shipping_address_first_use_date])
|
534
|
+
add_date_element(xml, 'shopperAccountPaymentAccountFirstUseDate', shopper_account_risk_data[:shopper_account_payment_account_first_use_date])
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
def add_transaction_risk_data(xml, transaction_risk_data)
|
539
|
+
return unless transaction_risk_data
|
540
|
+
|
541
|
+
data = {
|
542
|
+
'shippingMethod' => transaction_risk_data[:shipping_method],
|
543
|
+
'deliveryTimeframe' => transaction_risk_data[:delivery_timeframe],
|
544
|
+
'deliveryEmailAddress' => transaction_risk_data[:delivery_email_address],
|
545
|
+
'reorderingPreviousPurchases' => transaction_risk_data[:reordering_previous_purchases],
|
546
|
+
'preOrderPurchase' => transaction_risk_data[:pre_order_purchase],
|
547
|
+
'giftCardCount' => transaction_risk_data[:gift_card_count]
|
548
|
+
}.reject { |_k, v| v.nil? }
|
549
|
+
|
550
|
+
xml.transactionRiskData(data) do
|
551
|
+
xml.transactionRiskDataGiftCardAmount do
|
552
|
+
amount_hash = {
|
553
|
+
'value' => transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :value),
|
554
|
+
'currencyCode' => transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :currency),
|
555
|
+
'exponent' => transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :exponent)
|
556
|
+
}
|
557
|
+
debit_credit_indicator = transaction_risk_data.dig(:transaction_risk_data_gift_card_amount, :debit_credit_indicator)
|
558
|
+
amount_hash['debitCreditIndicator'] = debit_credit_indicator if debit_credit_indicator
|
559
|
+
xml.amount(amount_hash)
|
560
|
+
end
|
561
|
+
add_date_element(xml, 'transactionRiskDataPreOrderDate', transaction_risk_data[:transaction_risk_data_pre_order_date])
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
def add_date_element(xml, name, date)
|
566
|
+
xml.tag! name do
|
567
|
+
xml.date('dayOfMonth' => date[:day_of_month], 'month' => date[:month], 'year' => date[:year])
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
def add_amount(xml, money, options)
|
572
|
+
currency = options[:currency] || currency(money)
|
573
|
+
|
574
|
+
amount_hash = {
|
575
|
+
:value => localized_amount(money, currency),
|
576
|
+
'currencyCode' => currency,
|
577
|
+
'exponent' => currency_exponent(currency)
|
578
|
+
}
|
579
|
+
|
580
|
+
amount_hash['debitCreditIndicator'] = options[:debit_credit_indicator] if options[:debit_credit_indicator]
|
581
|
+
|
582
|
+
xml.amount amount_hash
|
583
|
+
end
|
584
|
+
|
585
|
+
def add_payment_method(xml, amount, payment_method, options)
|
586
|
+
case options[:payment_type]
|
587
|
+
when :pay_as_order
|
588
|
+
add_amount_for_pay_as_order(xml, amount, payment_method, options)
|
589
|
+
when :network_token
|
590
|
+
add_network_tokenization_card(xml, payment_method)
|
591
|
+
else
|
592
|
+
add_card_or_token(xml, payment_method, options)
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
def add_amount_for_pay_as_order(xml, amount, payment_method, options)
|
597
|
+
if options[:merchant_code]
|
598
|
+
xml.payAsOrder 'orderCode' => payment_method, 'merchantCode' => options[:merchant_code] do
|
599
|
+
add_amount(xml, amount, options)
|
600
|
+
end
|
601
|
+
else
|
602
|
+
xml.payAsOrder 'orderCode' => payment_method do
|
603
|
+
add_amount(xml, amount, options)
|
604
|
+
end
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
def add_network_tokenization_card(xml, payment_method)
|
609
|
+
token_type = NETWORK_TOKEN_TYPE.fetch(payment_method.source, 'NETWORKTOKEN')
|
610
|
+
|
611
|
+
xml.paymentDetails do
|
612
|
+
xml.tag! 'EMVCO_TOKEN-SSL', 'type' => token_type do
|
613
|
+
xml.tokenNumber payment_method.number
|
614
|
+
xml.expiryDate do
|
615
|
+
xml.date(
|
616
|
+
'month' => format(payment_method.month, :two_digits),
|
617
|
+
'year' => format(payment_method.year, :four_digits_year)
|
618
|
+
)
|
619
|
+
end
|
620
|
+
name = card_holder_name(payment_method, options)
|
621
|
+
eci = format(payment_method.eci, :two_digits)
|
622
|
+
xml.cardHolderName name if name.present?
|
623
|
+
xml.cryptogram payment_method.payment_cryptogram
|
624
|
+
xml.eciIndicator eci.empty? ? '07' : eci
|
625
|
+
end
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
def add_card_or_token(xml, payment_method, options)
|
630
|
+
xml.paymentDetails credit_fund_transfer_attribute(options) do
|
631
|
+
if options[:payment_type] == :token
|
632
|
+
add_token_details(xml, options)
|
633
|
+
else
|
634
|
+
add_card_details(xml, payment_method, options)
|
635
|
+
end
|
636
|
+
add_stored_credential_options(xml, options)
|
637
|
+
add_shopper_id(xml, options)
|
638
|
+
add_three_d_secure(xml, options)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
def add_token_details(xml, options)
|
643
|
+
xml.tag! 'TOKEN-SSL', 'tokenScope' => options[:token_scope] do
|
644
|
+
xml.paymentTokenID options[:token_id]
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
def add_card_details(xml, payment_method, options)
|
649
|
+
xml.tag! card_code_for(payment_method) do
|
650
|
+
add_card(xml, payment_method, options)
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
def add_shopper_id(xml, options)
|
655
|
+
if options[:ip] && options[:session_id]
|
656
|
+
xml.session 'shopperIPAddress' => options[:ip], 'id' => options[:session_id]
|
657
|
+
else
|
658
|
+
xml.session 'shopperIPAddress' => options[:ip] if options[:ip]
|
659
|
+
xml.session 'id' => options[:session_id] if options[:session_id]
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
def add_three_d_secure(xml, options)
|
664
|
+
return unless three_d_secure = options[:three_d_secure]
|
665
|
+
|
666
|
+
xml.info3DSecure do
|
667
|
+
xml.threeDSVersion three_d_secure[:version]
|
668
|
+
if three_d_secure[:version] && three_d_secure[:ds_transaction_id]
|
669
|
+
xml.dsTransactionId three_d_secure[:ds_transaction_id]
|
670
|
+
else
|
671
|
+
xml.xid three_d_secure[:xid]
|
672
|
+
end
|
673
|
+
xml.cavv three_d_secure[:cavv]
|
674
|
+
xml.eci three_d_secure[:eci]
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
def add_card(xml, payment_method, options)
|
679
|
+
xml.cardNumber payment_method.number
|
680
|
+
xml.expiryDate do
|
681
|
+
xml.date(
|
682
|
+
'month' => format(payment_method.month, :two_digits),
|
683
|
+
'year' => format(payment_method.year, :four_digits_year)
|
684
|
+
)
|
685
|
+
end
|
686
|
+
name = card_holder_name(payment_method, options)
|
687
|
+
xml.cardHolderName name if name.present?
|
688
|
+
xml.cvc payment_method.verification_value
|
689
|
+
|
690
|
+
add_address(xml, (options[:billing_address] || options[:address]), options)
|
691
|
+
end
|
692
|
+
|
693
|
+
def add_stored_credential_options(xml, options = {})
|
694
|
+
if options[:stored_credential]
|
695
|
+
add_stored_credential_using_normalized_fields(xml, options)
|
696
|
+
else
|
697
|
+
add_stored_credential_using_gateway_specific_fields(xml, options)
|
698
|
+
end
|
699
|
+
end
|
700
|
+
|
701
|
+
def add_stored_credential_using_normalized_fields(xml, options)
|
702
|
+
if options[:stored_credential][:initial_transaction]
|
703
|
+
xml.storedCredentials 'usage' => 'FIRST'
|
704
|
+
else
|
705
|
+
reason = case options[:stored_credential][:reason_type]
|
706
|
+
when 'installment' then 'INSTALMENT'
|
707
|
+
when 'recurring' then 'RECURRING'
|
708
|
+
when 'unscheduled' then 'UNSCHEDULED'
|
709
|
+
end
|
710
|
+
|
711
|
+
xml.storedCredentials 'usage' => 'USED', 'merchantInitiatedReason' => reason do
|
712
|
+
xml.schemeTransactionIdentifier options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
def add_stored_credential_using_gateway_specific_fields(xml, options)
|
718
|
+
return unless options[:stored_credential_usage]
|
719
|
+
|
720
|
+
if options[:stored_credential_initiated_reason]
|
721
|
+
xml.storedCredentials 'usage' => options[:stored_credential_usage], 'merchantInitiatedReason' => options[:stored_credential_initiated_reason] do
|
722
|
+
xml.schemeTransactionIdentifier options[:stored_credential_transaction_id] if options[:stored_credential_transaction_id]
|
723
|
+
end
|
724
|
+
else
|
725
|
+
xml.storedCredentials 'usage' => options[:stored_credential_usage]
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
def add_shopper(xml, options)
|
730
|
+
return unless options[:execute_threed] || options[:email] || options[:customer]
|
731
|
+
|
732
|
+
xml.shopper do
|
733
|
+
xml.shopperEmailAddress options[:email] if options[:email]
|
734
|
+
add_authenticated_shopper_id(xml, options)
|
735
|
+
xml.browser do
|
736
|
+
xml.acceptHeader options[:accept_header]
|
737
|
+
xml.userAgentHeader options[:user_agent]
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
def add_statement_narrative(xml, options)
|
743
|
+
xml.statementNarrative truncate(options[:statement_narrative], 50) if options[:statement_narrative]
|
744
|
+
end
|
745
|
+
|
746
|
+
def add_authenticated_shopper_id(xml, options)
|
747
|
+
xml.authenticatedShopperID options[:customer] if options[:customer]
|
748
|
+
end
|
749
|
+
|
750
|
+
def add_address(xml, address, options)
|
751
|
+
return unless address
|
752
|
+
|
753
|
+
address = address_with_defaults(address)
|
754
|
+
|
755
|
+
xml.cardAddress do
|
756
|
+
xml.address do
|
757
|
+
if m = /^\s*([^\s]+)\s+(.+)$/.match(address[:name])
|
758
|
+
xml.firstName m[1]
|
759
|
+
xml.lastName m[2]
|
760
|
+
end
|
761
|
+
xml.address1 address[:address1]
|
762
|
+
xml.address2 address[:address2] if address[:address2]
|
763
|
+
xml.postalCode address[:zip]
|
764
|
+
xml.city address[:city]
|
765
|
+
xml.state address[:state] unless address[:country] != 'US' && options[:execute_threed]
|
766
|
+
xml.countryCode address[:country]
|
767
|
+
xml.telephoneNumber address[:phone] if address[:phone]
|
768
|
+
end
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
def add_hcg_additional_data(xml, options)
|
773
|
+
xml.hcgAdditionalData do
|
774
|
+
options[:hcg_additional_data].each do |k, v|
|
775
|
+
xml.param({ name: k.to_s }, v)
|
776
|
+
end
|
777
|
+
end
|
778
|
+
end
|
779
|
+
|
780
|
+
def add_instalments_data(xml, options)
|
781
|
+
xml.thirdPartyData do
|
782
|
+
xml.instalments options[:instalments]
|
783
|
+
xml.cpf options[:cpf] if options[:cpf]
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
def add_moto_flag(xml, options)
|
788
|
+
xml.dynamicInteractionType 'type' => 'MOTO'
|
789
|
+
end
|
790
|
+
|
791
|
+
def address_with_defaults(address)
|
792
|
+
address ||= {}
|
793
|
+
address.delete_if { |_, v| v.blank? }
|
794
|
+
address.reverse_merge!(default_address)
|
795
|
+
end
|
796
|
+
|
797
|
+
def default_address
|
798
|
+
{
|
799
|
+
zip: '0000',
|
800
|
+
country: 'US',
|
801
|
+
city: 'N/A',
|
802
|
+
address1: 'N/A'
|
803
|
+
}
|
804
|
+
end
|
805
|
+
|
806
|
+
def parse(action, xml)
|
807
|
+
xml = xml.strip.gsub(/\&/, '&')
|
808
|
+
doc = Nokogiri::XML(xml, &:strict)
|
809
|
+
doc.remove_namespaces!
|
810
|
+
resp_params = { action: action }
|
811
|
+
|
812
|
+
parse_elements(doc.root, resp_params)
|
813
|
+
extract_issuer_response(doc.root, resp_params)
|
814
|
+
|
815
|
+
resp_params
|
816
|
+
end
|
817
|
+
|
818
|
+
def extract_issuer_response(doc, response)
|
819
|
+
return unless issuer_response = doc.at_xpath('//paymentService//reply//orderStatus//payment//IssuerResponseCode')
|
820
|
+
|
821
|
+
response[:issuer_response_code] = issuer_response['code']
|
822
|
+
response[:issuer_response_description] = issuer_response['description']
|
823
|
+
end
|
824
|
+
|
825
|
+
def parse_elements(node, response)
|
826
|
+
node_name = node.name.underscore
|
827
|
+
node.attributes.each do |k, v|
|
828
|
+
response["#{node_name}_#{k.underscore}".to_sym] = v.value
|
829
|
+
end
|
830
|
+
if node.elements.empty?
|
831
|
+
response[node_name.to_sym] = node.text unless node.text.blank?
|
832
|
+
else
|
833
|
+
response[node_name.to_sym] = true unless node.name.blank?
|
834
|
+
node.elements.each do |childnode|
|
835
|
+
parse_elements(childnode, response)
|
836
|
+
end
|
837
|
+
end
|
838
|
+
end
|
839
|
+
|
840
|
+
def headers(options)
|
841
|
+
idempotency_key = options[:idempotency_key]
|
842
|
+
|
843
|
+
headers = {
|
844
|
+
'Content-Type' => 'text/xml',
|
845
|
+
'Authorization' => encoded_credentials
|
846
|
+
}
|
847
|
+
|
848
|
+
# ensure cookie included on follow-up '3ds' and 'capture_request' calls, using the cookie saved from the preceding response
|
849
|
+
# cookie should be present in options on the 3ds and capture calls, but also still saved in the instance var in case
|
850
|
+
cookie = options[:cookie] || @cookie || nil
|
851
|
+
headers['Cookie'] = cookie if cookie
|
852
|
+
|
853
|
+
headers['Idempotency-Key'] = idempotency_key if idempotency_key
|
854
|
+
headers
|
855
|
+
end
|
856
|
+
|
857
|
+
def commit(action, request, *success_criteria, options)
|
858
|
+
xml = ssl_post(url, request, headers(options))
|
859
|
+
raw = parse(action, xml)
|
860
|
+
|
861
|
+
if options[:execute_threed]
|
862
|
+
raw[:cookie] = @cookie if defined?(@cookie)
|
863
|
+
raw[:session_id] = options[:session_id]
|
864
|
+
raw[:is3DSOrder] = true
|
865
|
+
end
|
866
|
+
success = success_from(action, raw, success_criteria)
|
867
|
+
message = message_from(success, raw, success_criteria, action)
|
868
|
+
|
869
|
+
Response.new(
|
870
|
+
success,
|
871
|
+
message,
|
872
|
+
raw,
|
873
|
+
authorization: authorization_from(action, raw, options),
|
874
|
+
error_code: error_code_from(success, raw),
|
875
|
+
test: test?,
|
876
|
+
avs_result: AVSResult.new(code: AVS_CODE_MAP[raw[:avs_result_code_description]]),
|
877
|
+
cvv_result: CVVResult.new(CVC_CODE_MAP[raw[:cvc_result_code_description]])
|
878
|
+
)
|
879
|
+
rescue Nokogiri::SyntaxError
|
880
|
+
unparsable_response(xml)
|
881
|
+
rescue ActiveMerchant::ResponseError => e
|
882
|
+
if e.response.code.to_s == '401'
|
883
|
+
return Response.new(false, 'Invalid credentials', {}, test: test?)
|
884
|
+
else
|
885
|
+
raise e
|
886
|
+
end
|
887
|
+
end
|
888
|
+
|
889
|
+
def url
|
890
|
+
test? ? self.test_url : self.live_url
|
891
|
+
end
|
892
|
+
|
893
|
+
def unparsable_response(raw_response)
|
894
|
+
message = 'Unparsable response received from Worldpay. Please contact Worldpay if you continue to receive this message.'
|
895
|
+
message += " (The raw response returned by the API was: #{raw_response.inspect})"
|
896
|
+
return Response.new(false, message)
|
897
|
+
end
|
898
|
+
|
899
|
+
# Override the regular handle response so we can access the headers
|
900
|
+
# Set-Cookie value is needed for 3DS transactions
|
901
|
+
def handle_response(response)
|
902
|
+
case response.code.to_i
|
903
|
+
when 200...300
|
904
|
+
cookie = response.header['Set-Cookie']&.match('^[^;]*')
|
905
|
+
@cookie = cookie[0] if cookie
|
906
|
+
response.body
|
907
|
+
else
|
908
|
+
raise ResponseError.new(response)
|
909
|
+
end
|
910
|
+
end
|
911
|
+
|
912
|
+
def success_from(action, raw, success_criteria)
|
913
|
+
success_criteria_success?(raw, success_criteria) || action_success?(action, raw)
|
914
|
+
end
|
915
|
+
|
916
|
+
def message_from(success, raw, success_criteria, action)
|
917
|
+
return 'SUCCESS' if success
|
918
|
+
|
919
|
+
raw[:iso8583_return_code_description] || raw[:error] || required_status_message(raw, success_criteria, action) || raw[:issuer_response_description]
|
920
|
+
end
|
921
|
+
|
922
|
+
# success_criteria can be:
|
923
|
+
# - a string or an array of strings (if one of many responses)
|
924
|
+
# - An array of strings if one of many responses could be considered a
|
925
|
+
# success.
|
926
|
+
def success_criteria_success?(raw, success_criteria)
|
927
|
+
return if raw[:error]
|
928
|
+
|
929
|
+
raw[:ok].present? || (success_criteria.include?(raw[:last_event]) if raw[:last_event])
|
930
|
+
end
|
931
|
+
|
932
|
+
def action_success?(action, raw)
|
933
|
+
case action
|
934
|
+
when 'store'
|
935
|
+
raw[:token].present?
|
936
|
+
when 'direct_inquiry'
|
937
|
+
raw[:last_event].present?
|
938
|
+
else
|
939
|
+
false
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
943
|
+
def error_code_from(success, raw)
|
944
|
+
raw[:iso8583_return_code_code] || raw[:error_code] || nil unless success == 'SUCCESS'
|
945
|
+
end
|
946
|
+
|
947
|
+
def required_status_message(raw, success_criteria, action)
|
948
|
+
return if success_criteria.include?(raw[:last_event])
|
949
|
+
return unless %w[cancel refund inquiry credit fast_credit].include?(action)
|
950
|
+
|
951
|
+
"A transaction status of #{success_criteria.collect { |c| "'#{c}'" }.join(' or ')} is required."
|
952
|
+
end
|
953
|
+
|
954
|
+
def authorization_from(action, raw, options)
|
955
|
+
order_id = order_id_from(raw)
|
956
|
+
|
957
|
+
case action
|
958
|
+
when 'store'
|
959
|
+
authorization_from_token_details(
|
960
|
+
order_id: order_id,
|
961
|
+
token_id: raw[:payment_token_id],
|
962
|
+
token_scope: 'shopper',
|
963
|
+
customer: options[:customer]
|
964
|
+
)
|
965
|
+
else
|
966
|
+
order_id
|
967
|
+
end
|
968
|
+
end
|
969
|
+
|
970
|
+
def order_id_from(raw)
|
971
|
+
pair = raw.detect { |k, _v| k.to_s =~ /_order_code$/ }
|
972
|
+
(pair ? pair.last : nil)
|
973
|
+
end
|
974
|
+
|
975
|
+
def authorization_from_token_details(options = {})
|
976
|
+
[options[:order_id], options[:token_id], options[:token_scope], options[:customer]].join('|')
|
977
|
+
end
|
978
|
+
|
979
|
+
def order_id_from_authorization(authorization)
|
980
|
+
token_details_from_authorization(authorization)[:order_id]
|
981
|
+
end
|
982
|
+
|
983
|
+
def token_details_from_authorization(authorization)
|
984
|
+
order_id, token_id, token_scope, customer = authorization.split('|')
|
985
|
+
|
986
|
+
token_details = {}
|
987
|
+
token_details[:order_id] = order_id if order_id.present?
|
988
|
+
token_details[:token_id] = token_id if token_id.present?
|
989
|
+
token_details[:token_scope] = token_scope if token_scope.present?
|
990
|
+
token_details[:customer] = customer if customer.present?
|
991
|
+
|
992
|
+
token_details
|
993
|
+
end
|
994
|
+
|
995
|
+
def payment_details(payment_method)
|
996
|
+
case payment_method
|
997
|
+
when String
|
998
|
+
token_type_and_details(payment_method)
|
999
|
+
else
|
1000
|
+
type = network_token?(payment_method) ? :network_token : :credit
|
1001
|
+
|
1002
|
+
{ payment_type: type }
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
def network_token?(payment_method)
|
1007
|
+
payment_method.respond_to?(:source) &&
|
1008
|
+
payment_method.respond_to?(:payment_cryptogram) &&
|
1009
|
+
payment_method.respond_to?(:eci)
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
def token_type_and_details(token)
|
1013
|
+
token_details = token_details_from_authorization(token)
|
1014
|
+
token_details[:payment_type] = token_details.has_key?(:token_id) ? :token : :pay_as_order
|
1015
|
+
|
1016
|
+
token_details
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
def credit_fund_transfer_attribute(options)
|
1020
|
+
return unless options[:credit]
|
1021
|
+
|
1022
|
+
{ 'action' => 'REFUND' }
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def encoded_credentials
|
1026
|
+
credentials = "#{@options[:login]}:#{@options[:password]}"
|
1027
|
+
"Basic #{[credentials].pack('m').strip}"
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
def currency_exponent(currency)
|
1031
|
+
return 0 if non_fractional_currency?(currency)
|
1032
|
+
return 3 if three_decimal_currency?(currency)
|
1033
|
+
|
1034
|
+
return 2
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def card_code_for(payment_method)
|
1038
|
+
CARD_CODES[card_brand(payment_method)] || CARD_CODES['unknown']
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
def eligible_for_0_auth?(payment_method, options = {})
|
1042
|
+
payment_method.is_a?(CreditCard) && %w(visa master).include?(payment_method.brand) && options[:zero_dollar_auth]
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
def card_holder_name(payment_method, options)
|
1046
|
+
test? && options[:execute_threed] && !options[:three_ds_version]&.start_with?('2') ? '3D' : payment_method.name
|
1047
|
+
end
|
1048
|
+
end
|
1049
|
+
end
|
1050
|
+
end
|