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,430 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class WirecardGateway < Gateway
|
6
|
+
self.test_url = 'https://c3-test.wirecard.com/secure/ssl-gateway'
|
7
|
+
self.live_url = 'https://c3.wirecard.com/secure/ssl-gateway'
|
8
|
+
|
9
|
+
# The Namespaces are not really needed, because it just tells the System, that there's actually no namespace used.
|
10
|
+
# It's just specified here for completeness.
|
11
|
+
ENVELOPE_NAMESPACES = {
|
12
|
+
'xmlns:xsi' => 'http://www.w3.org/1999/XMLSchema-instance',
|
13
|
+
'xsi:noNamespaceSchemaLocation' => 'wirecard.xsd'
|
14
|
+
}
|
15
|
+
|
16
|
+
PERMITTED_TRANSACTIONS = %w[PREAUTHORIZATION CAPTURE PURCHASE]
|
17
|
+
|
18
|
+
RETURN_CODES = %w[ACK NOK]
|
19
|
+
|
20
|
+
# Wirecard only allows phone numbers with a format like this: +xxx(yyy)zzz-zzzz-ppp, where:
|
21
|
+
# xxx = Country code
|
22
|
+
# yyy = Area or city code
|
23
|
+
# zzz-zzzz = Local number
|
24
|
+
# ppp = PBX extension
|
25
|
+
# For example, a typical U.S. or Canadian number would be "+1(202)555-1234-739" indicating PBX extension 739 at phone
|
26
|
+
# number 5551234 within area code 202 (country code 1).
|
27
|
+
VALID_PHONE_FORMAT = /\+\d{1,3}(\(?\d{3}\)?)?\d{3}-\d{4}-\d{3}/
|
28
|
+
|
29
|
+
self.supported_cardtypes = %i[visa master american_express diners_club jcb]
|
30
|
+
self.supported_countries = %w(AD CY GI IM MT RO CH AT DK GR IT MC SM TR BE EE HU LV NL SK GB BG FI IS LI NO SI VA FR IL LT PL ES CZ DE IE LU PT SE)
|
31
|
+
self.homepage_url = 'http://www.wirecard.com'
|
32
|
+
self.display_name = 'Wirecard'
|
33
|
+
self.default_currency = 'EUR'
|
34
|
+
self.money_format = :cents
|
35
|
+
|
36
|
+
# Public: Create a new Wirecard gateway.
|
37
|
+
#
|
38
|
+
# options - A hash of options:
|
39
|
+
# :login - The username
|
40
|
+
# :password - The password
|
41
|
+
# :signature - The BusinessCaseSignature
|
42
|
+
def initialize(options = {})
|
43
|
+
requires!(options, :login, :password, :signature)
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
# Authorization - the second parameter may be a CreditCard or
|
48
|
+
# a String which represents a GuWID reference to an earlier
|
49
|
+
# transaction. If a GuWID is given, rather than a CreditCard,
|
50
|
+
# then then the :recurring option will be forced to "Repeated"
|
51
|
+
def authorize(money, payment_method, options = {})
|
52
|
+
if payment_method.respond_to?(:number)
|
53
|
+
options[:credit_card] = payment_method
|
54
|
+
else
|
55
|
+
options[:preauthorization] = payment_method
|
56
|
+
end
|
57
|
+
commit(:preauthorization, money, options)
|
58
|
+
end
|
59
|
+
|
60
|
+
def capture(money, authorization, options = {})
|
61
|
+
options[:preauthorization] = authorization
|
62
|
+
commit(:capture, money, options)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Purchase - the second parameter may be a CreditCard or
|
66
|
+
# a String which represents a GuWID reference to an earlier
|
67
|
+
# transaction. If a GuWID is given, rather than a CreditCard,
|
68
|
+
# then then the :recurring option will be forced to "Repeated"
|
69
|
+
def purchase(money, payment_method, options = {})
|
70
|
+
if payment_method.respond_to?(:number)
|
71
|
+
options[:credit_card] = payment_method
|
72
|
+
else
|
73
|
+
options[:preauthorization] = payment_method
|
74
|
+
end
|
75
|
+
commit(:purchase, money, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def void(identification, options = {})
|
79
|
+
options[:preauthorization] = identification
|
80
|
+
commit(:reversal, nil, options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def refund(money, identification, options = {})
|
84
|
+
options[:preauthorization] = identification
|
85
|
+
commit(:bookback, money, options)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Store card - Wirecard supports the notion of "Recurring
|
89
|
+
# Transactions" by allowing the merchant to provide a reference
|
90
|
+
# to an earlier transaction (the GuWID) rather than a credit
|
91
|
+
# card. A reusable reference (GuWID) can be obtained by sending
|
92
|
+
# a purchase or authorization transaction with the element
|
93
|
+
# "RECURRING_TRANSACTION/Type" set to "Initial". Subsequent
|
94
|
+
# transactions can then use the GuWID in place of a credit
|
95
|
+
# card by setting "RECURRING_TRANSACTION/Type" to "Repeated".
|
96
|
+
#
|
97
|
+
# This implementation of card store utilizes a Wirecard
|
98
|
+
# "Authorization Check" (a Preauthorization that is automatically
|
99
|
+
# reversed). It defaults to a check amount of "100" (i.e.
|
100
|
+
# $1.00) but this can be overriden (see below).
|
101
|
+
#
|
102
|
+
# IMPORTANT: In order to reuse the stored reference, the
|
103
|
+
# +authorization+ from the response should be saved by
|
104
|
+
# your application code.
|
105
|
+
#
|
106
|
+
# ==== Options specific to +store+
|
107
|
+
#
|
108
|
+
# * <tt>:amount</tt> -- The amount, in cents, that should be
|
109
|
+
# "validated" by the Authorization Check. This amount will
|
110
|
+
# be reserved and then reversed. Default is 100.
|
111
|
+
#
|
112
|
+
# Note: This is not the only way to achieve a card store
|
113
|
+
# operation at Wirecard. Any +purchase+ or +authorize+
|
114
|
+
# can be sent with +options[:recurring] = 'Initial'+ to make
|
115
|
+
# the returned authorization/GuWID usable in later transactions
|
116
|
+
# with +options[:recurring] = 'Repeated'+.
|
117
|
+
def store(creditcard, options = {})
|
118
|
+
options[:credit_card] = creditcard
|
119
|
+
options[:recurring] = 'Initial'
|
120
|
+
money = options.delete(:amount) || 100
|
121
|
+
# Amex does not support authorization_check
|
122
|
+
if creditcard.brand == 'american_express'
|
123
|
+
commit(:preauthorization, money, options)
|
124
|
+
else
|
125
|
+
commit(:authorization_check, money, options)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def supports_scrubbing
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
def scrub(transcript)
|
134
|
+
transcript.
|
135
|
+
gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
|
136
|
+
gsub(%r((<CreditCardNumber>)\d+(</CreditCardNumber>)), '\1[FILTERED]\2').
|
137
|
+
gsub(%r((<CVC2>)[^<]+(</CVC2>)), '\1[FILTERED]\2')
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def clean_description(description)
|
143
|
+
description.to_s.slice(0, 32).encode('US-ASCII', invalid: :replace, undef: :replace, replace: '?')
|
144
|
+
end
|
145
|
+
|
146
|
+
def prepare_options_hash(options)
|
147
|
+
result = @options.merge(options)
|
148
|
+
setup_address_hash!(result)
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
152
|
+
# Create all address hash key value pairs so that
|
153
|
+
# it still works if only provided with one or two of them
|
154
|
+
def setup_address_hash!(options)
|
155
|
+
options[:billing_address] = options[:billing_address] || options[:address] || {}
|
156
|
+
options[:shipping_address] = options[:shipping_address] || {}
|
157
|
+
# Include Email in address-hash from options-hash
|
158
|
+
options[:billing_address][:email] = options[:email] if options[:email]
|
159
|
+
end
|
160
|
+
|
161
|
+
# If a GuWID (string-based reference) is passed rather than a
|
162
|
+
# credit card, then the :recurring type needs to be forced to
|
163
|
+
# "Repeated"
|
164
|
+
def setup_recurring_flag(options)
|
165
|
+
options[:recurring] = 'Repeated' if options[:preauthorization].present?
|
166
|
+
end
|
167
|
+
|
168
|
+
# Contact WireCard, make the XML request, and parse the
|
169
|
+
# reply into a Response object
|
170
|
+
def commit(action, money, options)
|
171
|
+
request = build_request(action, money, options)
|
172
|
+
|
173
|
+
headers = { 'Content-Type' => 'text/xml',
|
174
|
+
'Authorization' => encoded_credentials }
|
175
|
+
|
176
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, request, headers))
|
177
|
+
# Pending Status also means Acknowledged (as stated in their specification)
|
178
|
+
success = response[:FunctionResult] == 'ACK' || response[:FunctionResult] == 'PENDING'
|
179
|
+
message = response[:Message]
|
180
|
+
authorization = response[:GuWID]
|
181
|
+
|
182
|
+
Response.new(success, message, response,
|
183
|
+
test: test?,
|
184
|
+
authorization: authorization,
|
185
|
+
avs_result: { code: avs_code(response, options) },
|
186
|
+
cvv_result: response[:CVCResponseCode])
|
187
|
+
rescue ResponseError => e
|
188
|
+
if e.response.code == '401'
|
189
|
+
return Response.new(false, 'Invalid Login')
|
190
|
+
else
|
191
|
+
raise
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
# Generates the complete xml-message, that gets sent to the gateway
|
196
|
+
def build_request(action, money, options)
|
197
|
+
options = prepare_options_hash(options)
|
198
|
+
options[:action] = action
|
199
|
+
xml = Builder::XmlMarkup.new indent: 2
|
200
|
+
xml.instruct!
|
201
|
+
xml.tag! 'WIRECARD_BXML' do
|
202
|
+
xml.tag! 'W_REQUEST' do
|
203
|
+
xml.tag! 'W_JOB' do
|
204
|
+
xml.tag! 'JobID', ''
|
205
|
+
# UserID for this transaction
|
206
|
+
xml.tag! 'BusinessCaseSignature', options[:signature] || options[:login]
|
207
|
+
# Create the whole rest of the message
|
208
|
+
add_transaction_data(xml, money, options)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
xml.target!
|
213
|
+
end
|
214
|
+
|
215
|
+
# Includes the whole transaction data (payment, creditcard, address)
|
216
|
+
def add_transaction_data(xml, money, options)
|
217
|
+
options[:order_id] ||= generate_unique_id
|
218
|
+
|
219
|
+
xml.tag! "FNC_CC_#{options[:action].to_s.upcase}" do
|
220
|
+
xml.tag! 'FunctionID', clean_description(options[:description])
|
221
|
+
xml.tag! 'CC_TRANSACTION' do
|
222
|
+
xml.tag! 'TransactionID', options[:order_id]
|
223
|
+
xml.tag! 'CommerceType', options[:commerce_type] if options[:commerce_type]
|
224
|
+
case options[:action]
|
225
|
+
when :preauthorization, :purchase, :authorization_check
|
226
|
+
setup_recurring_flag(options)
|
227
|
+
add_invoice(xml, money, options)
|
228
|
+
|
229
|
+
if options[:credit_card]
|
230
|
+
add_creditcard(xml, options[:credit_card])
|
231
|
+
else
|
232
|
+
xml.tag! 'GuWID', options[:preauthorization]
|
233
|
+
end
|
234
|
+
|
235
|
+
add_address(xml, options[:billing_address])
|
236
|
+
when :capture, :bookback
|
237
|
+
xml.tag! 'GuWID', options[:preauthorization]
|
238
|
+
add_amount(xml, money, options)
|
239
|
+
when :reversal
|
240
|
+
xml.tag! 'GuWID', options[:preauthorization]
|
241
|
+
end
|
242
|
+
add_customer_data(xml, options)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Includes the payment (amount, currency, country) to the transaction-xml
|
248
|
+
def add_invoice(xml, money, options)
|
249
|
+
add_amount(xml, money, options)
|
250
|
+
xml.tag! 'Currency', options[:currency] || currency(money)
|
251
|
+
xml.tag! 'CountryCode', options[:billing_address][:country]
|
252
|
+
xml.tag! 'RECURRING_TRANSACTION' do
|
253
|
+
xml.tag! 'Type', options[:recurring] || 'Single'
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Include the amount in the transaction-xml
|
258
|
+
def add_amount(xml, money, options)
|
259
|
+
xml.tag! 'Amount', localized_amount(money, options[:currency] || currency(money))
|
260
|
+
end
|
261
|
+
|
262
|
+
# Includes the credit-card data to the transaction-xml
|
263
|
+
def add_creditcard(xml, creditcard)
|
264
|
+
raise 'Creditcard must be supplied!' if creditcard.nil?
|
265
|
+
|
266
|
+
xml.tag! 'CREDIT_CARD_DATA' do
|
267
|
+
xml.tag! 'CreditCardNumber', creditcard.number
|
268
|
+
xml.tag! 'CVC2', creditcard.verification_value
|
269
|
+
xml.tag! 'ExpirationYear', creditcard.year
|
270
|
+
xml.tag! 'ExpirationMonth', format(creditcard.month, :two_digits)
|
271
|
+
xml.tag! 'CardHolderName', [creditcard.first_name, creditcard.last_name].join(' ')
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# Includes the IP address of the customer to the transaction-xml
|
276
|
+
def add_customer_data(xml, options)
|
277
|
+
return unless options[:ip]
|
278
|
+
|
279
|
+
xml.tag! 'CONTACT_DATA' do
|
280
|
+
xml.tag! 'IPAddress', options[:ip]
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
# Includes the address to the transaction-xml
|
285
|
+
def add_address(xml, address)
|
286
|
+
return if address.nil?
|
287
|
+
|
288
|
+
xml.tag! 'CORPTRUSTCENTER_DATA' do
|
289
|
+
xml.tag! 'ADDRESS' do
|
290
|
+
xml.tag! 'Address1', address[:address1]
|
291
|
+
xml.tag! 'Address2', address[:address2] if address[:address2]
|
292
|
+
xml.tag! 'City', address[:city]
|
293
|
+
xml.tag! 'ZipCode', address[:zip]
|
294
|
+
|
295
|
+
xml.tag! 'State', address[:state].upcase if address[:state] =~ /[A-Za-z]{2}/ && address[:country] =~ /^(us|ca)$/i
|
296
|
+
|
297
|
+
xml.tag! 'Country', address[:country]
|
298
|
+
xml.tag! 'Phone', address[:phone] if address[:phone] =~ VALID_PHONE_FORMAT
|
299
|
+
xml.tag! 'Email', address[:email]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# Read the XML message from the gateway and check if it was successful,
|
305
|
+
# and also extract required return values from the response.
|
306
|
+
def parse(xml)
|
307
|
+
basepath = '/WIRECARD_BXML/W_RESPONSE'
|
308
|
+
response = {}
|
309
|
+
|
310
|
+
xml = REXML::Document.new(xml)
|
311
|
+
if root = REXML::XPath.first(xml, "#{basepath}/W_JOB")
|
312
|
+
parse_response(response, root)
|
313
|
+
elsif root = REXML::XPath.first(xml, '//ERROR')
|
314
|
+
parse_error_only_response(response, root)
|
315
|
+
else
|
316
|
+
response[:Message] = "No valid XML response message received. \
|
317
|
+
Propably wrong credentials supplied with HTTP header."
|
318
|
+
end
|
319
|
+
|
320
|
+
response
|
321
|
+
end
|
322
|
+
|
323
|
+
def parse_error_only_response(response, root)
|
324
|
+
error_code = REXML::XPath.first(root, 'Number')
|
325
|
+
response[:ErrorCode] = error_code.text if error_code
|
326
|
+
response[:Message] = parse_error(root)
|
327
|
+
end
|
328
|
+
|
329
|
+
# Parse the <ProcessingStatus> Element which contains all important information
|
330
|
+
def parse_response(response, root)
|
331
|
+
status = nil
|
332
|
+
|
333
|
+
root.elements.to_a.each do |node|
|
334
|
+
status = REXML::XPath.first(node, 'CC_TRANSACTION/PROCESSING_STATUS') if node.name =~ /FNC_CC_/
|
335
|
+
end
|
336
|
+
|
337
|
+
message = ''
|
338
|
+
if status
|
339
|
+
if info = status.elements['Info']
|
340
|
+
message << info.text
|
341
|
+
end
|
342
|
+
|
343
|
+
status.elements.to_a.each do |node|
|
344
|
+
if node.elements.size == 0
|
345
|
+
response[node.name.to_sym] = (node.text || '').strip
|
346
|
+
else
|
347
|
+
node.elements.each do |childnode|
|
348
|
+
name = "#{node.name}_#{childnode.name}"
|
349
|
+
response[name.to_sym] = (childnode.text || '').strip
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
error_code = REXML::XPath.first(status, 'ERROR/Number')
|
355
|
+
response['ErrorCode'] = error_code.text if error_code
|
356
|
+
end
|
357
|
+
|
358
|
+
parse_error(root, message)
|
359
|
+
response[:Message] = message
|
360
|
+
end
|
361
|
+
|
362
|
+
# Parse a generic error response from the gateway
|
363
|
+
def parse_error(root, message = '')
|
364
|
+
# Get errors if available and append them to the message
|
365
|
+
errors = errors_to_string(root)
|
366
|
+
unless errors.strip.blank?
|
367
|
+
message << ' - ' unless message.strip.blank?
|
368
|
+
message << errors
|
369
|
+
end
|
370
|
+
message
|
371
|
+
end
|
372
|
+
|
373
|
+
# Parses all <ERROR> elements in the response and converts the information
|
374
|
+
# to a single string
|
375
|
+
def errors_to_string(root)
|
376
|
+
# Get context error messages (can be 0..*)
|
377
|
+
errors = []
|
378
|
+
REXML::XPath.each(root, '//ERROR') do |error_elem|
|
379
|
+
error = {}
|
380
|
+
error[:Advice] = []
|
381
|
+
error[:Message] = error_elem.elements['Message'].text
|
382
|
+
error_elem.elements.each('Advice') do |advice|
|
383
|
+
error[:Advice] << advice.text
|
384
|
+
end
|
385
|
+
errors << error
|
386
|
+
end
|
387
|
+
# Convert all messages to a single string
|
388
|
+
string = ''
|
389
|
+
errors.each do |error|
|
390
|
+
string << error[:Message] if error[:Message]
|
391
|
+
error[:Advice].each_with_index do |advice, index|
|
392
|
+
string << ' (' if index == 0
|
393
|
+
string << "#{index + 1}. #{advice}"
|
394
|
+
string << ' and ' if index < error[:Advice].size - 1
|
395
|
+
string << ')' if index == error[:Advice].size - 1
|
396
|
+
end
|
397
|
+
end
|
398
|
+
string
|
399
|
+
end
|
400
|
+
|
401
|
+
# Amex have different AVS response codes
|
402
|
+
AMEX_TRANSLATED_AVS_CODES = {
|
403
|
+
'A' => 'B', # CSC and Address Matched
|
404
|
+
'F' => 'D', # All Data Matched
|
405
|
+
'N' => 'I', # CSC Match
|
406
|
+
'U' => 'U', # Data Not Checked
|
407
|
+
'Y' => 'D', # All Data Matched
|
408
|
+
'Z' => 'P', # CSC and Postcode Matched
|
409
|
+
}
|
410
|
+
|
411
|
+
# Amex have different AVS response codes to visa etc
|
412
|
+
def avs_code(response, options)
|
413
|
+
if response.has_key?(:AVS_ProviderResultCode)
|
414
|
+
if options[:credit_card].present? && ActiveMerchant::Billing::CreditCard.brand?(options[:credit_card].number) == 'american_express'
|
415
|
+
AMEX_TRANSLATED_AVS_CODES[response[:AVS_ProviderResultCode]]
|
416
|
+
else
|
417
|
+
response[:AVS_ProviderResultCode]
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
# Encode login and password in Base64 to supply as HTTP header
|
423
|
+
# (for http basic authentication)
|
424
|
+
def encoded_credentials
|
425
|
+
credentials = [@options[:login], @options[:password]].join(':')
|
426
|
+
'Basic ' << Base64.encode64(credentials).strip
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class WompiGateway < Gateway
|
4
|
+
self.test_url = 'https://sync.sandbox.wompi.co/v1'
|
5
|
+
self.live_url = 'https://sync.production.wompi.co/v1'
|
6
|
+
|
7
|
+
self.supported_countries = ['CO']
|
8
|
+
self.default_currency = 'COP'
|
9
|
+
self.supported_cardtypes = %i[visa master american_express]
|
10
|
+
|
11
|
+
self.homepage_url = 'https://wompi.co/'
|
12
|
+
self.display_name = 'Wompi'
|
13
|
+
|
14
|
+
self.money_format = :cents
|
15
|
+
|
16
|
+
def initialize(options = {})
|
17
|
+
## Sandbox keys have prefix pub_test_ and prv_test_
|
18
|
+
## Production keys have prefix pub_prod_ and prv_prod_
|
19
|
+
begin
|
20
|
+
requires!(options, :prod_private_key, :prod_public_key)
|
21
|
+
rescue ArgumentError
|
22
|
+
begin
|
23
|
+
requires!(options, :test_private_key, :test_public_key)
|
24
|
+
rescue ArgumentError
|
25
|
+
raise ArgumentError, 'Gateway requires both test_private_key and test_public_key, or both prod_private_key and prod_public_key'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def purchase(money, payment, options = {})
|
32
|
+
post = {
|
33
|
+
reference: options[:reference] || generate_reference,
|
34
|
+
public_key: public_key
|
35
|
+
}
|
36
|
+
add_invoice(post, money, options)
|
37
|
+
add_card(post, payment, options)
|
38
|
+
|
39
|
+
commit('sale', post, '/transactions_sync')
|
40
|
+
end
|
41
|
+
|
42
|
+
def authorize(money, payment, options = {})
|
43
|
+
post = {
|
44
|
+
public_key: public_key,
|
45
|
+
type: 'CARD',
|
46
|
+
financial_operation: 'PREAUTHORIZATION'
|
47
|
+
}
|
48
|
+
add_auth_params(post, money, payment, options)
|
49
|
+
|
50
|
+
commit('authorize', post, '/payment_sources_sync')
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture(money, authorization, options = {})
|
54
|
+
post = {
|
55
|
+
reference: options[:reference] || generate_reference,
|
56
|
+
public_key: public_key,
|
57
|
+
payment_source_id: authorization.to_i
|
58
|
+
}
|
59
|
+
add_invoice(post, money, options)
|
60
|
+
commit('capture', post, '/transactions_sync')
|
61
|
+
end
|
62
|
+
|
63
|
+
def refund(money, authorization, options = {})
|
64
|
+
# post = { amount_in_cents: amount(money).to_i, transaction_id: authorization.to_s }
|
65
|
+
# commit('refund', post, '/refunds_sync')
|
66
|
+
|
67
|
+
# All refunds will instead be voided. This is temporary.
|
68
|
+
void(authorization, options, money)
|
69
|
+
end
|
70
|
+
|
71
|
+
def void(authorization, options = {}, money = nil)
|
72
|
+
post = money ? { amount_in_cents: amount(money).to_i } : {}
|
73
|
+
commit('void', post, "/transactions/#{authorization}/void_sync")
|
74
|
+
end
|
75
|
+
|
76
|
+
def supports_scrubbing?
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def scrub(transcript)
|
81
|
+
transcript.gsub(/(Bearer )\w+/, '\1[REDACTED]').
|
82
|
+
gsub(/(\\\"number\\\":\\\")\d+/, '\1[REDACTED]').
|
83
|
+
gsub(/(\\\"cvc\\\":\\\")\d+/, '\1[REDACTED]').
|
84
|
+
gsub(/(\\\"phone_number\\\":\\\")\+?\d+/, '\1[REDACTED]').
|
85
|
+
gsub(/(\\\"email\\\":\\\")\S+\\\",/, '\1[REDACTED]\",').
|
86
|
+
gsub(/(\\\"legal_id\\\":\\\")\d+/, '\1[REDACTED]')
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def headers
|
92
|
+
{
|
93
|
+
'Authorization' => "Bearer #{private_key}",
|
94
|
+
'Content-Type' => 'application/json'
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def generate_reference
|
99
|
+
SecureRandom.alphanumeric(12)
|
100
|
+
end
|
101
|
+
|
102
|
+
def private_key
|
103
|
+
test? ? options[:test_private_key] : options[:prod_private_key]
|
104
|
+
end
|
105
|
+
|
106
|
+
def public_key
|
107
|
+
test? ? options[:test_public_key] : options[:prod_public_key]
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_invoice(post, money, options)
|
111
|
+
post[:amount_in_cents] = amount(money).to_i
|
112
|
+
post[:currency] = (options[:currency] || currency(money))
|
113
|
+
end
|
114
|
+
|
115
|
+
def add_card(post, card, options)
|
116
|
+
payment_method = {
|
117
|
+
type: 'CARD'
|
118
|
+
}
|
119
|
+
add_basic_card_info(payment_method, card, options)
|
120
|
+
post[:payment_method] = payment_method
|
121
|
+
end
|
122
|
+
|
123
|
+
def add_auth_params(post, money, card, options)
|
124
|
+
data = {
|
125
|
+
amount_in_cents: amount(money).to_i,
|
126
|
+
currency: (options[:currency] || currency(money))
|
127
|
+
}
|
128
|
+
add_basic_card_info(data, card, options)
|
129
|
+
post[:data] = data
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_basic_card_info(post, card, options)
|
133
|
+
installments = options[:installments] ? options[:installments].to_i : 1
|
134
|
+
cvc = card.verification_value || nil
|
135
|
+
|
136
|
+
post[:number] = card.number
|
137
|
+
post[:exp_month] = card.month.to_s.rjust(2, '0')
|
138
|
+
post[:exp_year] = card.year.to_s[2..3]
|
139
|
+
post[:installments] = installments
|
140
|
+
post[:card_holder] = card.name
|
141
|
+
post[:cvc] = cvc if cvc && !cvc.empty?
|
142
|
+
end
|
143
|
+
|
144
|
+
def parse(body)
|
145
|
+
JSON.parse(body)
|
146
|
+
end
|
147
|
+
|
148
|
+
def commit(action, parameters, endpoint)
|
149
|
+
url = (test? ? test_url : live_url) + endpoint
|
150
|
+
response = parse(ssl_post(url, post_data(action, parameters), headers))
|
151
|
+
Response.new(
|
152
|
+
success_from(response),
|
153
|
+
message_from(response),
|
154
|
+
response,
|
155
|
+
authorization: authorization_from(response),
|
156
|
+
avs_result: nil,
|
157
|
+
cvv_result: nil,
|
158
|
+
test: test?,
|
159
|
+
error_code: error_code_from(response)
|
160
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
def handle_response(response)
|
164
|
+
case response.code.to_i
|
165
|
+
when 200...300, 401, 404, 422
|
166
|
+
response.body
|
167
|
+
else
|
168
|
+
raise ResponseError.new(response)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def success_from(response)
|
173
|
+
success_statuses.include? response.dig('data', 'status')
|
174
|
+
end
|
175
|
+
|
176
|
+
def success_statuses
|
177
|
+
%w(APPROVED AVAILABLE)
|
178
|
+
end
|
179
|
+
|
180
|
+
def message_from(response)
|
181
|
+
response.dig('data', 'status_message') || response.dig('error', 'reason') || response.dig('error', 'messages').to_json
|
182
|
+
end
|
183
|
+
|
184
|
+
def authorization_from(response)
|
185
|
+
response.dig('data', 'transaction_id') || response.dig('data', 'id') || response.dig('data', 'transaction', 'id')
|
186
|
+
end
|
187
|
+
|
188
|
+
def post_data(action, parameters = {})
|
189
|
+
parameters.to_json
|
190
|
+
end
|
191
|
+
|
192
|
+
def error_code_from(response)
|
193
|
+
response.dig('error', 'type') unless success_from(response)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|