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,274 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
# ActiveMerchant Implementation for Quantum Gateway XML Requester Service
|
4
|
+
# Based on API Doc from 8/6/2009
|
5
|
+
#
|
6
|
+
# Important Notes
|
7
|
+
# * Support is included for a customer id via the :customer option, invoice number via :invoice option, invoice description via :merchant option and memo via :description option
|
8
|
+
# * You can force email of receipt with :email_receipt => true
|
9
|
+
# * You can force email of merchant receipt with :merchant_receipt => true
|
10
|
+
# * You can exclude CVV with :ignore_cvv => true
|
11
|
+
# * All transactions use dollar values.
|
12
|
+
class QuantumGateway < Gateway
|
13
|
+
self.live_url = self.test_url = 'https://secure.quantumgateway.com/cgi/xml_requester.php'
|
14
|
+
|
15
|
+
# visa, master, american_express, discover
|
16
|
+
self.supported_cardtypes = %i[visa master american_express discover]
|
17
|
+
self.supported_countries = ['US']
|
18
|
+
self.default_currency = 'USD'
|
19
|
+
self.money_format = :dollars
|
20
|
+
self.homepage_url = 'http://www.quantumgateway.com'
|
21
|
+
self.display_name = 'Quantum Gateway'
|
22
|
+
|
23
|
+
# These are the options that can be used when creating a new Quantum Gateway object.
|
24
|
+
#
|
25
|
+
# :login => Your Quantum Gateway Gateway ID
|
26
|
+
#
|
27
|
+
# :password => Your Quantum Gateway Vault Key or Restrict Key
|
28
|
+
#
|
29
|
+
# NOTE: For testing supply your test GatewayLogin and GatewayKey
|
30
|
+
#
|
31
|
+
# :email_receipt => true if you want a receipt sent to the customer (false be default)
|
32
|
+
#
|
33
|
+
# :merchant_receipt => true if you want to override receiving the merchant receipt
|
34
|
+
#
|
35
|
+
# :ignore_avs => true ignore both AVS and CVV verification
|
36
|
+
# :ignore_cvv => true don't want to use CVV so continue processing even if CVV would have failed
|
37
|
+
#
|
38
|
+
def initialize(options = {})
|
39
|
+
requires!(options, :login, :password)
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
# Request an authorization for an amount from CyberSource
|
44
|
+
#
|
45
|
+
def authorize(money, creditcard, options = {})
|
46
|
+
setup_address_hash(options)
|
47
|
+
commit(build_auth_request(money, creditcard, options), options)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Capture an authorization that has previously been requested
|
51
|
+
def capture(money, authorization, options = {})
|
52
|
+
setup_address_hash(options)
|
53
|
+
commit(build_capture_request(money, authorization, options), options)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Purchase is an auth followed by a capture
|
57
|
+
# You must supply an order_id in the options hash
|
58
|
+
def purchase(money, creditcard, options = {})
|
59
|
+
setup_address_hash(options)
|
60
|
+
commit(build_purchase_request(money, creditcard, options), options)
|
61
|
+
end
|
62
|
+
|
63
|
+
def void(identification, options = {})
|
64
|
+
commit(build_void_request(identification, options), options)
|
65
|
+
end
|
66
|
+
|
67
|
+
def refund(money, identification, options = {})
|
68
|
+
commit(build_credit_request(money, identification, options), options)
|
69
|
+
end
|
70
|
+
|
71
|
+
def credit(money, identification, options = {})
|
72
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
73
|
+
refund(money, identification, options)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def setup_address_hash(options)
|
79
|
+
options[:billing_address] = options[:billing_address] || options[:address] || {}
|
80
|
+
end
|
81
|
+
|
82
|
+
def build_auth_request(money, creditcard, options)
|
83
|
+
xml = Builder::XmlMarkup.new
|
84
|
+
add_common_credit_card_info(xml, 'AUTH_ONLY')
|
85
|
+
add_purchase_data(xml, money)
|
86
|
+
add_creditcard(xml, creditcard)
|
87
|
+
add_address(xml, creditcard, options[:billing_address], options)
|
88
|
+
add_invoice_details(xml, options)
|
89
|
+
add_customer_details(xml, options)
|
90
|
+
add_memo(xml, options)
|
91
|
+
add_business_rules_data(xml)
|
92
|
+
xml.target!
|
93
|
+
end
|
94
|
+
|
95
|
+
def build_capture_request(money, authorization, options)
|
96
|
+
xml = Builder::XmlMarkup.new
|
97
|
+
add_common_credit_card_info(xml, 'PREVIOUS_SALE')
|
98
|
+
transaction_id, = authorization_parts_from(authorization)
|
99
|
+
add_transaction_id(xml, transaction_id)
|
100
|
+
xml.target!
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_purchase_request(money, creditcard, options)
|
104
|
+
xml = Builder::XmlMarkup.new
|
105
|
+
add_common_credit_card_info(xml, @options[:ignore_avs] || @options[:ignore_cvv] ? 'SALES' : 'AUTH_CAPTURE')
|
106
|
+
add_address(xml, creditcard, options[:billing_address], options)
|
107
|
+
add_purchase_data(xml, money)
|
108
|
+
add_creditcard(xml, creditcard)
|
109
|
+
add_invoice_details(xml, options)
|
110
|
+
add_customer_details(xml, options)
|
111
|
+
add_memo(xml, options)
|
112
|
+
add_business_rules_data(xml)
|
113
|
+
xml.target!
|
114
|
+
end
|
115
|
+
|
116
|
+
def build_void_request(authorization, options)
|
117
|
+
xml = Builder::XmlMarkup.new
|
118
|
+
add_common_credit_card_info(xml, 'VOID')
|
119
|
+
transaction_id, = authorization_parts_from(authorization)
|
120
|
+
add_transaction_id(xml, transaction_id)
|
121
|
+
xml.target!
|
122
|
+
end
|
123
|
+
|
124
|
+
def build_credit_request(money, authorization, options)
|
125
|
+
xml = Builder::XmlMarkup.new
|
126
|
+
add_common_credit_card_info(xml, 'RETURN')
|
127
|
+
add_purchase_data(xml, money)
|
128
|
+
transaction_id, cc = authorization_parts_from(authorization)
|
129
|
+
add_transaction_id(xml, transaction_id)
|
130
|
+
xml.tag! 'CreditCardNumber', cc
|
131
|
+
xml.target!
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_common_credit_card_info(xml, process_type)
|
135
|
+
xml.tag! 'RequestType', 'ProcessSingleTransaction'
|
136
|
+
xml.tag! 'TransactionType', 'CREDIT'
|
137
|
+
xml.tag! 'PaymentType', 'CC'
|
138
|
+
xml.tag! 'ProcessType', process_type
|
139
|
+
end
|
140
|
+
|
141
|
+
def add_business_rules_data(xml)
|
142
|
+
xml.tag!('CustomerEmail', @options[:email_receipt] ? 'Y' : 'N')
|
143
|
+
xml.tag!('MerchantEmail', @options[:merchant_receipt] ? 'Y' : 'N')
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_invoice_details(xml, options)
|
147
|
+
xml.tag! 'InvoiceNumber', options[:invoice]
|
148
|
+
xml.tag! 'InvoiceDescription', options[:merchant]
|
149
|
+
end
|
150
|
+
|
151
|
+
def add_customer_details(xml, options)
|
152
|
+
xml.tag! 'CustomerID', options[:customer]
|
153
|
+
end
|
154
|
+
|
155
|
+
def add_transaction_id(xml, transaction_id)
|
156
|
+
xml.tag! 'TransactionID', transaction_id
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_memo(xml, options)
|
160
|
+
xml.tag! 'Memo', options[:description]
|
161
|
+
end
|
162
|
+
|
163
|
+
def add_purchase_data(xml, money = 0)
|
164
|
+
xml.tag! 'Amount', amount(money)
|
165
|
+
xml.tag! 'TransactionDate', Time.now
|
166
|
+
end
|
167
|
+
|
168
|
+
def add_address(xml, creditcard, address, options, shipTo = false)
|
169
|
+
xml.tag! 'FirstName', creditcard.first_name
|
170
|
+
xml.tag! 'LastName', creditcard.last_name
|
171
|
+
xml.tag! 'Address', address[:address1] # => there is no support for address2 in quantum
|
172
|
+
xml.tag! 'City', address[:city]
|
173
|
+
xml.tag! 'State', address[:state]
|
174
|
+
xml.tag! 'ZipCode', address[:zip]
|
175
|
+
xml.tag! 'Country', address[:country]
|
176
|
+
xml.tag! 'EmailAddress', options[:email]
|
177
|
+
xml.tag! 'IPAddress', options[:ip]
|
178
|
+
end
|
179
|
+
|
180
|
+
def add_creditcard(xml, creditcard)
|
181
|
+
xml.tag! 'PaymentType', 'CC'
|
182
|
+
xml.tag! 'CreditCardNumber', creditcard.number
|
183
|
+
xml.tag! 'ExpireMonth', format(creditcard.month, :two_digits)
|
184
|
+
xml.tag! 'ExpireYear', format(creditcard.year, :four_digits)
|
185
|
+
xml.tag!('CVV2', creditcard.verification_value) unless @options[:ignore_cvv] || creditcard.verification_value.blank?
|
186
|
+
end
|
187
|
+
|
188
|
+
# Where we actually build the full SOAP request using builder
|
189
|
+
def build_request(body, options)
|
190
|
+
xml = Builder::XmlMarkup.new
|
191
|
+
xml.instruct!
|
192
|
+
xml.tag! 'QGWRequest' do
|
193
|
+
xml.tag! 'Authentication' do
|
194
|
+
xml.tag! 'GatewayLogin', @options[:login]
|
195
|
+
xml.tag! 'GatewayKey', @options[:password]
|
196
|
+
end
|
197
|
+
xml.tag! 'Request' do
|
198
|
+
xml << body
|
199
|
+
end
|
200
|
+
end
|
201
|
+
xml.target!
|
202
|
+
end
|
203
|
+
|
204
|
+
# Contact CyberSource, make the SOAP request, and parse the reply into a Response object
|
205
|
+
def commit(request, options)
|
206
|
+
headers = { 'Content-Type' => 'text/xml' }
|
207
|
+
response = parse(ssl_post(self.live_url, build_request(request, options), headers))
|
208
|
+
|
209
|
+
success = response[:request_status] == 'Success'
|
210
|
+
message = response[:request_message]
|
211
|
+
|
212
|
+
if success # => checking for connectivity success first
|
213
|
+
success = %w(APPROVED FORCED VOIDED).include?(response[:Status])
|
214
|
+
message = response[:StatusDescription]
|
215
|
+
authorization = success ? authorization_for(response) : nil
|
216
|
+
end
|
217
|
+
|
218
|
+
Response.new(success, message, response,
|
219
|
+
test: test?,
|
220
|
+
authorization: authorization,
|
221
|
+
avs_result: { code: response[:AVSResponseCode] },
|
222
|
+
cvv_result: response[:CVV2ResponseCode])
|
223
|
+
end
|
224
|
+
|
225
|
+
# Parse the SOAP response
|
226
|
+
# Technique inspired by the Paypal Gateway
|
227
|
+
def parse(xml)
|
228
|
+
reply = {}
|
229
|
+
|
230
|
+
begin
|
231
|
+
xml = REXML::Document.new(xml)
|
232
|
+
|
233
|
+
root = REXML::XPath.first(xml, '//QGWRequest/ResponseSummary')
|
234
|
+
parse_element(reply, root)
|
235
|
+
reply[:request_status] = reply[:Status]
|
236
|
+
reply[:request_message] = "#{reply[:Status]}: #{reply[:StatusDescription]}"
|
237
|
+
|
238
|
+
if root = REXML::XPath.first(xml, '//QGWRequest/Result')
|
239
|
+
root.elements.to_a.each do |node|
|
240
|
+
parse_element(reply, node)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
rescue Exception
|
244
|
+
reply[:request_status] = 'Failure'
|
245
|
+
reply[:request_message] = 'Failure: There was a problem parsing the response XML'
|
246
|
+
end
|
247
|
+
|
248
|
+
return reply
|
249
|
+
end
|
250
|
+
|
251
|
+
def parse_element(reply, node)
|
252
|
+
if node.has_elements?
|
253
|
+
node.elements.each { |e| parse_element(reply, e) }
|
254
|
+
else
|
255
|
+
if /item/.match?(node.parent.name)
|
256
|
+
parent = node.parent.name + (node.parent.attributes['id'] ? '_' + node.parent.attributes['id'] : '')
|
257
|
+
reply[(parent + '_' + node.name).to_sym] = node.text
|
258
|
+
else
|
259
|
+
reply[node.name.to_sym] = node.text
|
260
|
+
end
|
261
|
+
end
|
262
|
+
return reply
|
263
|
+
end
|
264
|
+
|
265
|
+
def authorization_for(reply)
|
266
|
+
"#{reply[:TransactionID]};#{reply[:CreditCardNumber]}"
|
267
|
+
end
|
268
|
+
|
269
|
+
def authorization_parts_from(authorization)
|
270
|
+
authorization.split(/;/)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
@@ -0,0 +1,377 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class QuickbooksGateway < Gateway
|
4
|
+
self.test_url = 'https://sandbox.api.intuit.com'
|
5
|
+
self.live_url = 'https://api.intuit.com'
|
6
|
+
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.default_currency = 'USD'
|
9
|
+
self.supported_cardtypes = %i[visa master american_express discover diners]
|
10
|
+
|
11
|
+
self.homepage_url = 'http://payments.intuit.com'
|
12
|
+
self.display_name = 'QuickBooks Payments'
|
13
|
+
BASE = '/quickbooks/v4/payments'
|
14
|
+
ENDPOINT = "#{BASE}/charges"
|
15
|
+
VOID_ENDPOINT = "#{BASE}/txn-requests"
|
16
|
+
REFRESH_URI = 'https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer'
|
17
|
+
|
18
|
+
# https://developer.intuit.com/docs/0150_payments/0300_developer_guides/error_handling
|
19
|
+
|
20
|
+
STANDARD_ERROR_CODE_MAPPING = {
|
21
|
+
# Fraud Warnings
|
22
|
+
'PMT-1000' => STANDARD_ERROR_CODE[:processing_error], # payment was accepted, but refund was unsuccessful
|
23
|
+
'PMT-1001' => STANDARD_ERROR_CODE[:invalid_cvc], # payment processed, but cvc was invalid
|
24
|
+
'PMT-1002' => STANDARD_ERROR_CODE[:incorrect_address], # payment processed, incorrect address info
|
25
|
+
'PMT-1003' => STANDARD_ERROR_CODE[:processing_error], # payment processed, address info couldn't be validated
|
26
|
+
|
27
|
+
# Fraud Errors
|
28
|
+
'PMT-2000' => STANDARD_ERROR_CODE[:incorrect_cvc], # Incorrect CVC
|
29
|
+
'PMT-2001' => STANDARD_ERROR_CODE[:invalid_cvc], # CVC check unavaliable
|
30
|
+
'PMT-2002' => STANDARD_ERROR_CODE[:incorrect_address], # Incorrect address
|
31
|
+
'PMT-2003' => STANDARD_ERROR_CODE[:incorrect_address], # Address info unavailable
|
32
|
+
|
33
|
+
'PMT-3000' => STANDARD_ERROR_CODE[:processing_error], # Merchant account could not be validated
|
34
|
+
|
35
|
+
# Invalid Request
|
36
|
+
'PMT-4000' => STANDARD_ERROR_CODE[:processing_error], # Object is invalid
|
37
|
+
'PMT-4001' => STANDARD_ERROR_CODE[:processing_error], # Object not found
|
38
|
+
'PMT-4002' => STANDARD_ERROR_CODE[:processing_error], # Object is required
|
39
|
+
|
40
|
+
# Transaction Declined
|
41
|
+
'PMT-5000' => STANDARD_ERROR_CODE[:card_declined], # Request was declined
|
42
|
+
'PMT-5001' => STANDARD_ERROR_CODE[:card_declined], # Merchant does not support given payment method
|
43
|
+
|
44
|
+
# System Error
|
45
|
+
'PMT-6000' => STANDARD_ERROR_CODE[:processing_error], # A temporary Issue prevented this request from being processed.
|
46
|
+
}
|
47
|
+
|
48
|
+
FRAUD_WARNING_CODES = ['PMT-1000', 'PMT-1001', 'PMT-1002', 'PMT-1003']
|
49
|
+
|
50
|
+
def initialize(options = {})
|
51
|
+
# Quickbooks is deprecating OAuth 1.0 on December 17, 2019.
|
52
|
+
# OAuth 2.0 requires a client_id, client_secret, access_token, and refresh_token
|
53
|
+
# To maintain backwards compatibility, check for the presence of a refresh_token (only specified for OAuth 2.0)
|
54
|
+
# When present, validate that all OAuth 2.0 options are present
|
55
|
+
if options[:refresh_token]
|
56
|
+
requires!(options, :client_id, :client_secret, :access_token, :refresh_token)
|
57
|
+
else
|
58
|
+
requires!(options, :consumer_key, :consumer_secret, :access_token, :token_secret, :realm)
|
59
|
+
end
|
60
|
+
@options = options
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
def purchase(money, payment, options = {})
|
65
|
+
post = {}
|
66
|
+
add_amount(post, money, options)
|
67
|
+
add_charge_data(post, payment, options)
|
68
|
+
post[:capture] = 'true'
|
69
|
+
|
70
|
+
response = commit(ENDPOINT, post)
|
71
|
+
check_token_response(response, ENDPOINT, post, options)
|
72
|
+
end
|
73
|
+
|
74
|
+
def authorize(money, payment, options = {})
|
75
|
+
post = {}
|
76
|
+
add_amount(post, money, options)
|
77
|
+
add_charge_data(post, payment, options)
|
78
|
+
post[:capture] = 'false'
|
79
|
+
|
80
|
+
response = commit(ENDPOINT, post)
|
81
|
+
check_token_response(response, ENDPOINT, post, options)
|
82
|
+
end
|
83
|
+
|
84
|
+
def capture(money, authorization, options = {})
|
85
|
+
post = {}
|
86
|
+
authorization, = split_authorization(authorization)
|
87
|
+
post[:amount] = localized_amount(money, currency(money))
|
88
|
+
add_context(post, options)
|
89
|
+
|
90
|
+
response = commit(capture_uri(authorization), post)
|
91
|
+
check_token_response(response, capture_uri(authorization), post, options)
|
92
|
+
end
|
93
|
+
|
94
|
+
def refund(money, authorization, options = {})
|
95
|
+
post = {}
|
96
|
+
post[:amount] = localized_amount(money, currency(money))
|
97
|
+
add_context(post, options)
|
98
|
+
authorization, = split_authorization(authorization)
|
99
|
+
|
100
|
+
response = commit(refund_uri(authorization), post)
|
101
|
+
check_token_response(response, refund_uri(authorization), post, options)
|
102
|
+
end
|
103
|
+
|
104
|
+
def void(authorization, options = {})
|
105
|
+
_, request_id = split_authorization(authorization)
|
106
|
+
|
107
|
+
response = commit(void_uri(request_id))
|
108
|
+
check_token_response(response, void_uri(request_id), {}, options)
|
109
|
+
end
|
110
|
+
|
111
|
+
def verify(credit_card, options = {})
|
112
|
+
authorize(1.00, credit_card, options)
|
113
|
+
end
|
114
|
+
|
115
|
+
def refresh
|
116
|
+
response = refresh_access_token
|
117
|
+
response_object(response)
|
118
|
+
end
|
119
|
+
|
120
|
+
def supports_scrubbing?
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
def scrub(transcript)
|
125
|
+
transcript.
|
126
|
+
gsub(%r((realm=\")\w+), '\1[FILTERED]').
|
127
|
+
gsub(%r((oauth_consumer_key=\")\w+), '\1[FILTERED]').
|
128
|
+
gsub(%r((oauth_nonce=\")\w+), '\1[FILTERED]').
|
129
|
+
gsub(%r((oauth_signature=\")[a-zA-Z%0-9]+), '\1[FILTERED]').
|
130
|
+
gsub(%r((oauth_token=\")\w+), '\1[FILTERED]').
|
131
|
+
gsub(%r((number\D+)\d{16}), '\1[FILTERED]').
|
132
|
+
gsub(%r((cvc\D+)\d{3}), '\1[FILTERED]').
|
133
|
+
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
134
|
+
gsub(%r((access_token\\?":\\?")[\w\-\.]+)i, '\1[FILTERED]').
|
135
|
+
gsub(%r((refresh_token\\?":\\?")\w+), '\1[FILTERED]').
|
136
|
+
gsub(%r((refresh_token=)\w+), '\1[FILTERED]').
|
137
|
+
gsub(%r((Authorization: Bearer )[\w\-\.]+)i, '\1[FILTERED]\2')
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def add_charge_data(post, payment, options = {})
|
143
|
+
add_payment(post, payment, options)
|
144
|
+
add_address(post, options)
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_address(post, options)
|
148
|
+
return unless post[:card]&.kind_of?(Hash)
|
149
|
+
|
150
|
+
card_address = {}
|
151
|
+
if address = options[:billing_address] || options[:address]
|
152
|
+
card_address[:streetAddress] = address[:address1]
|
153
|
+
card_address[:city] = address[:city]
|
154
|
+
region = address[:state] || address[:region]
|
155
|
+
card_address[:region] = region if region.present?
|
156
|
+
card_address[:country] = address[:country] if address[:country].present?
|
157
|
+
card_address[:postalCode] = address[:zip] if address[:zip]
|
158
|
+
end
|
159
|
+
post[:card][:address] = card_address
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_amount(post, money, options = {})
|
163
|
+
currency = options[:currency] || currency(money)
|
164
|
+
post[:amount] = localized_amount(money, currency)
|
165
|
+
post[:currency] = currency.upcase
|
166
|
+
end
|
167
|
+
|
168
|
+
def add_payment(post, payment, options = {})
|
169
|
+
add_creditcard(post, payment, options)
|
170
|
+
add_context(post, options)
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_creditcard(post, creditcard, options = {})
|
174
|
+
card = {}
|
175
|
+
card[:number] = creditcard.number
|
176
|
+
card[:expMonth] = '%02d' % creditcard.month
|
177
|
+
card[:expYear] = creditcard.year
|
178
|
+
card[:cvc] = creditcard.verification_value if creditcard.verification_value?
|
179
|
+
card[:name] = creditcard.name if creditcard.name
|
180
|
+
card[:commercialCardCode] = options[:card_code] if options[:card_code]
|
181
|
+
|
182
|
+
post[:card] = card
|
183
|
+
end
|
184
|
+
|
185
|
+
def add_context(post, options = {})
|
186
|
+
post[:context] = {
|
187
|
+
mobile: options.fetch(:mobile, false),
|
188
|
+
isEcommerce: options.fetch(:ecommerce, true)
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
def parse(body)
|
193
|
+
JSON.parse(body)
|
194
|
+
end
|
195
|
+
|
196
|
+
def commit(uri, body = {}, method = :post)
|
197
|
+
endpoint = gateway_url + uri
|
198
|
+
# The QuickBooks API returns HTTP 4xx on failed transactions, which causes a
|
199
|
+
# ResponseError raise, so we have to inspect the response and discern between
|
200
|
+
# a legitimate HTTP error and an actual gateway transactional error.
|
201
|
+
headers = {}
|
202
|
+
response =
|
203
|
+
begin
|
204
|
+
headers = headers(method, endpoint)
|
205
|
+
method == :post ? ssl_post(endpoint, post_data(body), headers) : ssl_request(:get, endpoint, nil, headers)
|
206
|
+
rescue ResponseError => e
|
207
|
+
extract_response_body_or_raise(e)
|
208
|
+
end
|
209
|
+
|
210
|
+
response_object(response, headers)
|
211
|
+
end
|
212
|
+
|
213
|
+
def response_object(raw_response, headers = {})
|
214
|
+
parsed_response = parse(raw_response)
|
215
|
+
|
216
|
+
# Include access_token and refresh_token in params for OAuth 2.0
|
217
|
+
parsed_response['access_token'] = @options[:access_token] if @options[:refresh_token]
|
218
|
+
parsed_response['refresh_token'] = @options[:refresh_token] if @options[:refresh_token]
|
219
|
+
|
220
|
+
Response.new(
|
221
|
+
success?(parsed_response),
|
222
|
+
message_from(parsed_response),
|
223
|
+
parsed_response,
|
224
|
+
authorization: authorization_from(parsed_response, headers),
|
225
|
+
test: test?,
|
226
|
+
cvv_result: cvv_code_from(parsed_response),
|
227
|
+
error_code: errors_from(parsed_response),
|
228
|
+
fraud_review: fraud_review_status_from(parsed_response)
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
def gateway_url
|
233
|
+
test? ? test_url : live_url
|
234
|
+
end
|
235
|
+
|
236
|
+
def post_data(data = {})
|
237
|
+
data.to_json
|
238
|
+
end
|
239
|
+
|
240
|
+
def headers(method, uri)
|
241
|
+
return oauth_v2_headers if @options[:refresh_token]
|
242
|
+
|
243
|
+
raise ArgumentError, "Invalid HTTP method: #{method}. Valid methods are :post and :get" unless %i[post get].include?(method)
|
244
|
+
|
245
|
+
request_uri = URI.parse(uri)
|
246
|
+
|
247
|
+
# Following the guidelines from http://nouncer.com/oauth/authentication.html
|
248
|
+
oauth_parameters = {
|
249
|
+
oauth_nonce: generate_unique_id,
|
250
|
+
oauth_timestamp: Time.now.to_i.to_s,
|
251
|
+
oauth_signature_method: 'HMAC-SHA1',
|
252
|
+
oauth_version: '1.0',
|
253
|
+
oauth_consumer_key: @options[:consumer_key],
|
254
|
+
oauth_token: @options[:access_token]
|
255
|
+
}
|
256
|
+
|
257
|
+
# prepare components for signature
|
258
|
+
oauth_signature_base_string = [method.to_s.upcase, request_uri.to_s, oauth_parameters.to_param].map { |v| CGI.escape(v) }.join('&')
|
259
|
+
oauth_signing_key = [@options[:consumer_secret], @options[:token_secret]].map { |v| CGI.escape(v) }.join('&')
|
260
|
+
hmac_signature = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), oauth_signing_key, oauth_signature_base_string)
|
261
|
+
|
262
|
+
# append signature to required OAuth parameters
|
263
|
+
oauth_parameters[:oauth_signature] = CGI.escape(Base64.encode64(hmac_signature).chomp.delete("\n"))
|
264
|
+
|
265
|
+
# prepare Authorization header string
|
266
|
+
oauth_parameters = Hash[oauth_parameters.sort_by { |k, _| k }]
|
267
|
+
oauth_headers = ["OAuth realm=\"#{@options[:realm]}\""]
|
268
|
+
oauth_headers += oauth_parameters.map { |k, v| "#{k}=\"#{v}\"" }
|
269
|
+
|
270
|
+
{
|
271
|
+
'Content-type' => 'application/json',
|
272
|
+
'Request-Id' => generate_unique_id,
|
273
|
+
'Authorization' => oauth_headers.join(', ')
|
274
|
+
}
|
275
|
+
end
|
276
|
+
|
277
|
+
def oauth_v2_headers
|
278
|
+
{
|
279
|
+
'Content-Type' => 'application/json',
|
280
|
+
'Request-Id' => generate_unique_id,
|
281
|
+
'Accept' => 'application/json',
|
282
|
+
'Authorization' => "Bearer #{@options[:access_token]}"
|
283
|
+
}
|
284
|
+
end
|
285
|
+
|
286
|
+
def check_token_response(response, endpoint, body = {}, options = {})
|
287
|
+
return response unless @options[:refresh_token]
|
288
|
+
return response unless options[:allow_refresh]
|
289
|
+
return response unless response.params['code'] == 'AuthenticationFailed'
|
290
|
+
|
291
|
+
refresh_access_token
|
292
|
+
commit(endpoint, body)
|
293
|
+
end
|
294
|
+
|
295
|
+
def refresh_access_token
|
296
|
+
post = {}
|
297
|
+
post[:grant_type] = 'refresh_token'
|
298
|
+
post[:refresh_token] = @options[:refresh_token]
|
299
|
+
data = post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
|
300
|
+
|
301
|
+
basic_auth = Base64.strict_encode64("#{@options[:client_id]}:#{@options[:client_secret]}")
|
302
|
+
headers = {
|
303
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
304
|
+
'Accept' => 'application/json',
|
305
|
+
'Authorization' => "Basic #{basic_auth}"
|
306
|
+
}
|
307
|
+
|
308
|
+
response = ssl_post(REFRESH_URI, data, headers)
|
309
|
+
json_response = JSON.parse(response)
|
310
|
+
|
311
|
+
@options[:access_token] = json_response['access_token'] if json_response['access_token']
|
312
|
+
@options[:refresh_token] = json_response['refresh_token'] if json_response['refresh_token']
|
313
|
+
response
|
314
|
+
end
|
315
|
+
|
316
|
+
def cvv_code_from(response)
|
317
|
+
if response['errors'].present?
|
318
|
+
FRAUD_WARNING_CODES.include?(response['errors'].first['code']) ? 'I' : ''
|
319
|
+
else
|
320
|
+
success?(response) ? 'M' : ''
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def success?(response)
|
325
|
+
return FRAUD_WARNING_CODES.concat(['0']).include?(response['errors'].first['code']) if response['errors']
|
326
|
+
|
327
|
+
!%w[DECLINED CANCELLED].include?(response['status']) && !%w[AuthenticationFailed AuthorizationFailed].include?(response['code'])
|
328
|
+
end
|
329
|
+
|
330
|
+
def message_from(response)
|
331
|
+
response['errors'].present? ? response['errors'].map { |error_hash| error_hash['message'] }.join(' ') : response['status']
|
332
|
+
end
|
333
|
+
|
334
|
+
def errors_from(response)
|
335
|
+
if %w[AuthenticationFailed AuthorizationFailed].include?(response['code'])
|
336
|
+
response['code']
|
337
|
+
else
|
338
|
+
response['errors'].present? ? STANDARD_ERROR_CODE_MAPPING[response['errors'].first['code']] : ''
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
def authorization_from(response, headers = {})
|
343
|
+
[response['id'], headers['Request-Id']].join('|')
|
344
|
+
end
|
345
|
+
|
346
|
+
def split_authorization(authorization)
|
347
|
+
authorization, request_id = authorization.split('|')
|
348
|
+
[authorization, request_id]
|
349
|
+
end
|
350
|
+
|
351
|
+
def fraud_review_status_from(response)
|
352
|
+
response['errors'] && FRAUD_WARNING_CODES.include?(response['errors'].first['code'])
|
353
|
+
end
|
354
|
+
|
355
|
+
def extract_response_body_or_raise(response_error)
|
356
|
+
begin
|
357
|
+
parse(response_error.response.body)
|
358
|
+
rescue JSON::ParserError
|
359
|
+
raise response_error
|
360
|
+
end
|
361
|
+
response_error.response.body
|
362
|
+
end
|
363
|
+
|
364
|
+
def refund_uri(authorization)
|
365
|
+
"#{ENDPOINT}/#{CGI.escape(authorization.to_s)}/refunds"
|
366
|
+
end
|
367
|
+
|
368
|
+
def capture_uri(authorization)
|
369
|
+
"#{ENDPOINT}/#{CGI.escape(authorization.to_s)}/capture"
|
370
|
+
end
|
371
|
+
|
372
|
+
def void_uri(request_id)
|
373
|
+
"#{VOID_ENDPOINT}/#{CGI.escape(request_id.to_s)}/void"
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|