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,409 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
class PayexGateway < Gateway
|
6
|
+
class_attribute :live_external_url, :test_external_url, :live_confined_url, :test_confined_url
|
7
|
+
|
8
|
+
self.live_external_url = 'https://external.payex.com/'
|
9
|
+
self.test_external_url = 'https://test-external.payex.com/'
|
10
|
+
|
11
|
+
self.live_confined_url = 'https://confined.payex.com/'
|
12
|
+
self.test_confined_url = 'https://test-confined.payex.com/'
|
13
|
+
|
14
|
+
self.money_format = :cents
|
15
|
+
self.supported_countries = %w[DK FI NO SE]
|
16
|
+
self.supported_cardtypes = %i[visa master american_express discover]
|
17
|
+
self.homepage_url = 'http://payex.com/'
|
18
|
+
self.display_name = 'Payex'
|
19
|
+
self.default_currency = 'EUR'
|
20
|
+
|
21
|
+
TRANSACTION_STATUS = {
|
22
|
+
sale: '0',
|
23
|
+
initialize: '1',
|
24
|
+
credit: '2',
|
25
|
+
authorize: '3',
|
26
|
+
cancel: '4',
|
27
|
+
failure: '5',
|
28
|
+
capture: '6'
|
29
|
+
}
|
30
|
+
|
31
|
+
SOAP_ACTIONS = {
|
32
|
+
initialize: { name: 'Initialize8', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
33
|
+
purchasecc: { name: 'PurchaseCC', url: 'pxconfined/pxorder.asmx', xmlns: 'http://confined.payex.com/PxOrder/', confined: true },
|
34
|
+
cancel: { name: 'Cancel2', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
35
|
+
capture: { name: 'Capture5', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
36
|
+
credit: { name: 'Credit5', url: 'pxorder/pxorder.asmx', xmlns: 'http://external.payex.com/PxOrder/' },
|
37
|
+
create_agreement: { name: 'CreateAgreement3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' },
|
38
|
+
delete_agreement: { name: 'DeleteAgreement', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' },
|
39
|
+
autopay: { name: 'AutoPay3', url: 'pxagreement/pxagreement.asmx', xmlns: 'http://external.payex.com/PxAgreement/' }
|
40
|
+
}
|
41
|
+
|
42
|
+
def initialize(options = {})
|
43
|
+
requires!(options, :account, :encryption_key)
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
# Public: Send an authorize Payex request
|
48
|
+
#
|
49
|
+
# amount - The monetary amount of the transaction in cents.
|
50
|
+
# payment_method - The Active Merchant payment method or the +store+ authorization for stored transactions.
|
51
|
+
# options - A standard ActiveMerchant options hash:
|
52
|
+
# :currency - Three letter currency code for the transaction (default: "EUR")
|
53
|
+
# :order_id - The unique order ID for this transaction (required).
|
54
|
+
# :product_number - The merchant product number (default: '1').
|
55
|
+
# :description - The merchant description for this product (default: The :order_id).
|
56
|
+
# :ip - The client IP address (default: '127.0.0.1').
|
57
|
+
# :vat - The vat amount (optional).
|
58
|
+
#
|
59
|
+
# Returns an ActiveMerchant::Billing::Response object
|
60
|
+
def authorize(amount, payment_method, options = {})
|
61
|
+
requires!(options, :order_id)
|
62
|
+
amount = amount(amount)
|
63
|
+
if payment_method.respond_to?(:number)
|
64
|
+
# credit card authorization
|
65
|
+
MultiResponse.new.tap do |r|
|
66
|
+
r.process { send_initialize(amount, true, options) }
|
67
|
+
r.process { send_purchasecc(payment_method, r.params['orderref']) }
|
68
|
+
end
|
69
|
+
else
|
70
|
+
# stored authorization
|
71
|
+
send_autopay(amount, payment_method, true, options)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Public: Send a purchase Payex request
|
76
|
+
#
|
77
|
+
# amount - The monetary amount of the transaction in cents.
|
78
|
+
# payment_method - The Active Merchant payment method or the +store+ authorization for stored transactions.
|
79
|
+
# options - A standard ActiveMerchant options hash:
|
80
|
+
# :currency - Three letter currency code for the transaction (default: "EUR")
|
81
|
+
# :order_id - The unique order ID for this transaction (required).
|
82
|
+
# :product_number - The merchant product number (default: '1').
|
83
|
+
# :description - The merchant description for this product (default: The :order_id).
|
84
|
+
# :ip - The client IP address (default: '127.0.0.1').
|
85
|
+
# :vat - The vat amount (optional).
|
86
|
+
#
|
87
|
+
# Returns an ActiveMerchant::Billing::Response object
|
88
|
+
def purchase(amount, payment_method, options = {})
|
89
|
+
requires!(options, :order_id)
|
90
|
+
amount = amount(amount)
|
91
|
+
if payment_method.respond_to?(:number)
|
92
|
+
# credit card purchase
|
93
|
+
MultiResponse.new.tap do |r|
|
94
|
+
r.process { send_initialize(amount, false, options) }
|
95
|
+
r.process { send_purchasecc(payment_method, r.params['orderref']) }
|
96
|
+
end
|
97
|
+
else
|
98
|
+
# stored purchase
|
99
|
+
send_autopay(amount, payment_method, false, options)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Public: Capture money from a previously authorized transaction
|
104
|
+
#
|
105
|
+
# money - The amount to capture
|
106
|
+
# authorization - The authorization token from the authorization request
|
107
|
+
#
|
108
|
+
# Returns an ActiveMerchant::Billing::Response object
|
109
|
+
def capture(money, authorization, options = {})
|
110
|
+
amount = amount(money)
|
111
|
+
send_capture(amount, authorization)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Public: Voids an authorize transaction
|
115
|
+
#
|
116
|
+
# authorization - The authorization returned from the successful authorize transaction.
|
117
|
+
# options - A standard ActiveMerchant options hash
|
118
|
+
#
|
119
|
+
# Returns an ActiveMerchant::Billing::Response object
|
120
|
+
def void(authorization, options = {})
|
121
|
+
send_cancel(authorization)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Public: Refunds a purchase transaction
|
125
|
+
#
|
126
|
+
# money - The amount to refund
|
127
|
+
# authorization - The authorization token from the purchase request.
|
128
|
+
# options - A standard ActiveMerchant options hash:
|
129
|
+
# :order_id - The unique order ID for this transaction (required).
|
130
|
+
# :vat_amount - The vat amount (optional).
|
131
|
+
#
|
132
|
+
# Returns an ActiveMerchant::Billing::Response object
|
133
|
+
def refund(money, authorization, options = {})
|
134
|
+
requires!(options, :order_id)
|
135
|
+
amount = amount(money)
|
136
|
+
send_credit(authorization, amount, options)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Public: Stores a credit card and creates a Payex agreement with a customer
|
140
|
+
#
|
141
|
+
# creditcard - The credit card to store.
|
142
|
+
# options - A standard ActiveMerchant options hash:
|
143
|
+
# :order_id - The unique order ID for this transaction (required).
|
144
|
+
# :merchant_ref - A reference that links this agreement to something the merchant takes money for (default: '1')
|
145
|
+
# :currency - Three letter currency code for the transaction (default: "EUR")
|
146
|
+
# :product_number - The merchant product number (default: '1').
|
147
|
+
# :description - The merchant description for this product (default: The :order_id).
|
148
|
+
# :ip - The client IP address (default: '127.0.0.1').
|
149
|
+
# :max_amount - The maximum amount to allow to be charged (default: 100000).
|
150
|
+
# :vat - The vat amount (optional).
|
151
|
+
#
|
152
|
+
# Returns an ActiveMerchant::Billing::Response object where the authorization is set to the agreement_ref which is used for stored payments.
|
153
|
+
def store(creditcard, options = {})
|
154
|
+
requires!(options, :order_id)
|
155
|
+
amount = amount(1) # 1 cent for authorization
|
156
|
+
MultiResponse.run(:first) do |r|
|
157
|
+
r.process { send_create_agreement(options) }
|
158
|
+
r.process { send_initialize(amount, true, options.merge({ agreement_ref: r.authorization })) }
|
159
|
+
order_ref = r.params['orderref']
|
160
|
+
r.process { send_purchasecc(creditcard, order_ref) }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Public: Unstores a customer's credit card and deletes their Payex agreement.
|
165
|
+
#
|
166
|
+
# authorization - The authorization token from the store request.
|
167
|
+
#
|
168
|
+
# Returns an ActiveMerchant::Billing::Response object
|
169
|
+
def unstore(authorization, options = {})
|
170
|
+
send_delete_agreement(authorization)
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def send_initialize(amount, is_auth, options = {})
|
176
|
+
properties = {
|
177
|
+
accountNumber: @options[:account],
|
178
|
+
purchaseOperation: is_auth ? 'AUTHORIZATION' : 'SALE',
|
179
|
+
price: amount,
|
180
|
+
priceArgList: nil,
|
181
|
+
currency: (options[:currency] || default_currency),
|
182
|
+
vat: options[:vat] || 0,
|
183
|
+
orderID: options[:order_id],
|
184
|
+
productNumber: options[:product_number] || '1',
|
185
|
+
description: options[:description] || options[:order_id],
|
186
|
+
clientIPAddress: options[:client_ip_address] || '127.0.0.1',
|
187
|
+
clientIdentifier: nil,
|
188
|
+
additionalValues: nil,
|
189
|
+
externalID: nil,
|
190
|
+
returnUrl: 'http://example.net', # set to dummy value since this is not used but is required
|
191
|
+
view: 'CREDITCARD',
|
192
|
+
agreementRef: options[:agreement_ref], # this is used to attach a stored agreement to a transaction as part of the store card
|
193
|
+
cancelUrl: nil,
|
194
|
+
clientLanguage: nil
|
195
|
+
}
|
196
|
+
hash_fields = %i[accountNumber purchaseOperation price priceArgList currency vat orderID
|
197
|
+
productNumber description clientIPAddress clientIdentifier additionalValues
|
198
|
+
externalID returnUrl view agreementRef cancelUrl clientLanguage]
|
199
|
+
add_request_hash(properties, hash_fields)
|
200
|
+
soap_action = SOAP_ACTIONS[:initialize]
|
201
|
+
request = build_xml_request(soap_action, properties)
|
202
|
+
commit(soap_action, request)
|
203
|
+
end
|
204
|
+
|
205
|
+
def send_purchasecc(payment_method, order_ref)
|
206
|
+
properties = {
|
207
|
+
accountNumber: @options[:account],
|
208
|
+
orderRef: order_ref,
|
209
|
+
transactionType: 1, # online payment
|
210
|
+
cardNumber: payment_method.number,
|
211
|
+
cardNumberExpireMonth: format(payment_method.month, :two_digits),
|
212
|
+
cardNumberExpireYear: format(payment_method.year, :two_digits),
|
213
|
+
cardHolderName: payment_method.name,
|
214
|
+
cardNumberCVC: payment_method.verification_value
|
215
|
+
}
|
216
|
+
hash_fields = %i[accountNumber orderRef transactionType cardNumber cardNumberExpireMonth
|
217
|
+
cardNumberExpireYear cardNumberCVC cardHolderName]
|
218
|
+
add_request_hash(properties, hash_fields)
|
219
|
+
|
220
|
+
soap_action = SOAP_ACTIONS[:purchasecc]
|
221
|
+
request = build_xml_request(soap_action, properties)
|
222
|
+
commit(soap_action, request)
|
223
|
+
end
|
224
|
+
|
225
|
+
def send_autopay(amount, authorization, is_auth, options = {})
|
226
|
+
properties = {
|
227
|
+
accountNumber: @options[:account],
|
228
|
+
agreementRef: authorization,
|
229
|
+
price: amount,
|
230
|
+
productNumber: options[:product_number] || '1',
|
231
|
+
description: options[:description] || options[:order_id],
|
232
|
+
orderId: options[:order_id],
|
233
|
+
purchaseOperation: is_auth ? 'AUTHORIZATION' : 'SALE',
|
234
|
+
currency: (options[:currency] || default_currency)
|
235
|
+
}
|
236
|
+
hash_fields = %i[accountNumber agreementRef price productNumber description orderId purchaseOperation currency]
|
237
|
+
add_request_hash(properties, hash_fields)
|
238
|
+
|
239
|
+
soap_action = SOAP_ACTIONS[:autopay]
|
240
|
+
request = build_xml_request(soap_action, properties)
|
241
|
+
commit(soap_action, request)
|
242
|
+
end
|
243
|
+
|
244
|
+
def send_capture(amount, transaction_number, options = {})
|
245
|
+
properties = {
|
246
|
+
accountNumber: @options[:account],
|
247
|
+
transactionNumber: transaction_number,
|
248
|
+
amount: amount,
|
249
|
+
orderId: options[:order_id] || '',
|
250
|
+
vatAmount: options[:vat_amount] || 0,
|
251
|
+
additionalValues: ''
|
252
|
+
}
|
253
|
+
hash_fields = %i[accountNumber transactionNumber amount orderId vatAmount additionalValues]
|
254
|
+
add_request_hash(properties, hash_fields)
|
255
|
+
|
256
|
+
soap_action = SOAP_ACTIONS[:capture]
|
257
|
+
request = build_xml_request(soap_action, properties)
|
258
|
+
commit(soap_action, request)
|
259
|
+
end
|
260
|
+
|
261
|
+
def send_credit(transaction_number, amount, options = {})
|
262
|
+
properties = {
|
263
|
+
accountNumber: @options[:account],
|
264
|
+
transactionNumber: transaction_number,
|
265
|
+
amount: amount,
|
266
|
+
orderId: options[:order_id],
|
267
|
+
vatAmount: options[:vat_amount] || 0,
|
268
|
+
additionalValues: ''
|
269
|
+
}
|
270
|
+
hash_fields = %i[accountNumber transactionNumber amount orderId vatAmount additionalValues]
|
271
|
+
add_request_hash(properties, hash_fields)
|
272
|
+
|
273
|
+
soap_action = SOAP_ACTIONS[:credit]
|
274
|
+
request = build_xml_request(soap_action, properties)
|
275
|
+
commit(soap_action, request)
|
276
|
+
end
|
277
|
+
|
278
|
+
def send_cancel(transaction_number)
|
279
|
+
properties = {
|
280
|
+
accountNumber: @options[:account],
|
281
|
+
transactionNumber: transaction_number
|
282
|
+
}
|
283
|
+
hash_fields = %i[accountNumber transactionNumber]
|
284
|
+
add_request_hash(properties, hash_fields)
|
285
|
+
|
286
|
+
soap_action = SOAP_ACTIONS[:cancel]
|
287
|
+
request = build_xml_request(soap_action, properties)
|
288
|
+
commit(soap_action, request)
|
289
|
+
end
|
290
|
+
|
291
|
+
def send_create_agreement(options)
|
292
|
+
properties = {
|
293
|
+
accountNumber: @options[:account],
|
294
|
+
merchantRef: options[:merchant_ref] || '1',
|
295
|
+
description: options[:description] || options[:order_id],
|
296
|
+
purchaseOperation: 'SALE',
|
297
|
+
maxAmount: options[:max_amount] || 100000, # default to 1,000
|
298
|
+
notifyUrl: '',
|
299
|
+
startDate: options[:startDate] || '',
|
300
|
+
stopDate: options[:stopDate] || ''
|
301
|
+
}
|
302
|
+
hash_fields = %i[accountNumber merchantRef description purchaseOperation maxAmount notifyUrl startDate stopDate]
|
303
|
+
add_request_hash(properties, hash_fields)
|
304
|
+
|
305
|
+
soap_action = SOAP_ACTIONS[:create_agreement]
|
306
|
+
request = build_xml_request(soap_action, properties)
|
307
|
+
commit(soap_action, request)
|
308
|
+
end
|
309
|
+
|
310
|
+
def send_delete_agreement(authorization)
|
311
|
+
properties = {
|
312
|
+
accountNumber: @options[:account],
|
313
|
+
agreementRef: authorization
|
314
|
+
}
|
315
|
+
hash_fields = %i[accountNumber agreementRef]
|
316
|
+
add_request_hash(properties, hash_fields)
|
317
|
+
|
318
|
+
soap_action = SOAP_ACTIONS[:delete_agreement]
|
319
|
+
request = build_xml_request(soap_action, properties)
|
320
|
+
commit(soap_action, request)
|
321
|
+
end
|
322
|
+
|
323
|
+
def url_for(soap_action)
|
324
|
+
File.join(base_url(soap_action), soap_action[:url])
|
325
|
+
end
|
326
|
+
|
327
|
+
def base_url(soap_action)
|
328
|
+
if soap_action[:confined]
|
329
|
+
test? ? test_confined_url : live_confined_url
|
330
|
+
else
|
331
|
+
test? ? test_external_url : live_external_url
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# this will add a hash to the passed in properties as required by Payex requests
|
336
|
+
def add_request_hash(properties, fields)
|
337
|
+
data = fields.map { |e| properties[e] }
|
338
|
+
data << @options[:encryption_key]
|
339
|
+
properties['hash_'] = Digest::MD5.hexdigest(data.join(''))
|
340
|
+
end
|
341
|
+
|
342
|
+
def build_xml_request(soap_action, properties)
|
343
|
+
builder = Nokogiri::XML::Builder.new
|
344
|
+
builder.__send__('soap12:Envelope', { 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
|
345
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
346
|
+
'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope' }) do |root|
|
347
|
+
root.__send__('soap12:Body') do |body|
|
348
|
+
body.__send__(soap_action[:name], xmlns: soap_action[:xmlns]) do |doc|
|
349
|
+
properties.each do |key, val|
|
350
|
+
doc.send(key, val)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
builder.to_xml
|
356
|
+
end
|
357
|
+
|
358
|
+
def parse(xml)
|
359
|
+
response = {}
|
360
|
+
|
361
|
+
xmldoc = Nokogiri::XML(xml)
|
362
|
+
body = xmldoc.xpath('//soap:Body/*[1]')[0].inner_text
|
363
|
+
|
364
|
+
doc = Nokogiri::XML(body)
|
365
|
+
|
366
|
+
doc.root&.xpath('*')&.each do |node|
|
367
|
+
if node.elements.size == 0
|
368
|
+
response[node.name.downcase.to_sym] = node.text
|
369
|
+
else
|
370
|
+
node.elements.each do |childnode|
|
371
|
+
name = "#{node.name.downcase}_#{childnode.name.downcase}"
|
372
|
+
response[name.to_sym] = childnode.text
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
response
|
378
|
+
end
|
379
|
+
|
380
|
+
# Commits all requests to the Payex soap endpoint
|
381
|
+
def commit(soap_action, request)
|
382
|
+
url = url_for(soap_action)
|
383
|
+
headers = {
|
384
|
+
'Content-Type' => 'application/soap+xml; charset=utf-8',
|
385
|
+
'Content-Length' => request.size.to_s
|
386
|
+
}
|
387
|
+
response = parse(ssl_post(url, request, headers))
|
388
|
+
Response.new(success?(response),
|
389
|
+
message_from(response),
|
390
|
+
response,
|
391
|
+
test: test?,
|
392
|
+
authorization: build_authorization(response))
|
393
|
+
end
|
394
|
+
|
395
|
+
def build_authorization(response)
|
396
|
+
# agreementref is for the store transaction, everything else gets transactionnumber
|
397
|
+
response[:transactionnumber] || response[:agreementref]
|
398
|
+
end
|
399
|
+
|
400
|
+
def success?(response)
|
401
|
+
response[:status_errorcode] == 'OK' && response[:transactionstatus] != TRANSACTION_STATUS[:failure]
|
402
|
+
end
|
403
|
+
|
404
|
+
def message_from(response)
|
405
|
+
response[:status_description]
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
module ActiveMerchant #:nodoc:
|
3
|
+
module Billing #:nodoc:
|
4
|
+
module PayflowCommonAPI
|
5
|
+
def self.included(base)
|
6
|
+
base.default_currency = 'USD'
|
7
|
+
|
8
|
+
base.class_attribute :partner
|
9
|
+
|
10
|
+
# Set the default partner to PayPal
|
11
|
+
base.partner = 'PayPal'
|
12
|
+
|
13
|
+
base.supported_countries = %w[US CA NZ AU]
|
14
|
+
|
15
|
+
base.class_attribute :timeout
|
16
|
+
base.timeout = 60
|
17
|
+
|
18
|
+
base.test_url = 'https://pilot-payflowpro.paypal.com'
|
19
|
+
base.live_url = 'https://payflowpro.paypal.com'
|
20
|
+
|
21
|
+
# Enable safe retry of failed connections
|
22
|
+
# Payflow is safe to retry because retried transactions use the same
|
23
|
+
# X-VPS-Request-ID header. If a transaction is detected as a duplicate
|
24
|
+
# only the original transaction data will be used by Payflow, and the
|
25
|
+
# subsequent Responses will have a :duplicate parameter set in the params
|
26
|
+
# hash.
|
27
|
+
base.retry_safe = true
|
28
|
+
|
29
|
+
# Send Payflow requests to PayPal directly by activating the NVP protocol.
|
30
|
+
# Valid XMLPay documents may have issues being parsed correctly by
|
31
|
+
# Payflow but will be accepted by PayPal if a PAYPAL-NVP request header
|
32
|
+
# is declared.
|
33
|
+
base.class_attribute :use_paypal_nvp
|
34
|
+
base.use_paypal_nvp = false
|
35
|
+
end
|
36
|
+
|
37
|
+
XMLNS = 'http://www.paypal.com/XMLPay'
|
38
|
+
|
39
|
+
CARD_MAPPING = {
|
40
|
+
visa: 'Visa',
|
41
|
+
master: 'MasterCard',
|
42
|
+
discover: 'Discover',
|
43
|
+
american_express: 'Amex',
|
44
|
+
jcb: 'JCB',
|
45
|
+
diners_club: 'DinersClub'
|
46
|
+
}
|
47
|
+
|
48
|
+
TRANSACTIONS = {
|
49
|
+
purchase: 'Sale',
|
50
|
+
authorization: 'Authorization',
|
51
|
+
capture: 'Capture',
|
52
|
+
void: 'Void',
|
53
|
+
credit: 'Credit'
|
54
|
+
}
|
55
|
+
|
56
|
+
CVV_CODE = {
|
57
|
+
'Match' => 'M',
|
58
|
+
'No Match' => 'N',
|
59
|
+
'Service Not Available' => 'U',
|
60
|
+
'Service not Requested' => 'P'
|
61
|
+
}
|
62
|
+
|
63
|
+
def initialize(options = {})
|
64
|
+
requires!(options, :login, :password)
|
65
|
+
|
66
|
+
options[:partner] = partner if options[:partner].blank?
|
67
|
+
super
|
68
|
+
end
|
69
|
+
|
70
|
+
def capture(money, authorization, options = {})
|
71
|
+
request = build_reference_request(:capture, money, authorization, options)
|
72
|
+
commit(request, options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def void(authorization, options = {})
|
76
|
+
request = build_reference_request(:void, nil, authorization, options)
|
77
|
+
commit(request, options)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def build_request(body, options = {})
|
83
|
+
xml = Builder::XmlMarkup.new
|
84
|
+
xml.instruct!
|
85
|
+
xml.tag! 'XMLPayRequest', 'Timeout' => timeout.to_s, 'version' => '2.1', 'xmlns' => XMLNS do
|
86
|
+
xml.tag! 'RequestData' do
|
87
|
+
xml.tag! 'Vendor', @options[:login]
|
88
|
+
xml.tag! 'Partner', @options[:partner]
|
89
|
+
if options[:request_type] == :recurring
|
90
|
+
xml << body
|
91
|
+
else
|
92
|
+
xml.tag! 'Transactions' do
|
93
|
+
xml.tag! 'Transaction', 'CustRef' => options[:customer] do
|
94
|
+
xml.tag! 'Verbosity', @options[:verbosity] || 'MEDIUM'
|
95
|
+
xml << body
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
xml.tag! 'RequestAuth' do
|
101
|
+
xml.tag! 'UserPass' do
|
102
|
+
xml.tag! 'User', !@options[:user].blank? ? @options[:user] : @options[:login]
|
103
|
+
xml.tag! 'Password', @options[:password]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
xml.target!
|
108
|
+
end
|
109
|
+
|
110
|
+
def build_reference_request(action, money, authorization, options)
|
111
|
+
xml = Builder::XmlMarkup.new
|
112
|
+
xml.tag! TRANSACTIONS[action] do
|
113
|
+
xml.tag! 'PNRef', authorization
|
114
|
+
|
115
|
+
unless money.nil?
|
116
|
+
xml.tag! 'Invoice' do
|
117
|
+
xml.tag!('TotalAmt', amount(money), 'Currency' => options[:currency] || currency(money))
|
118
|
+
xml.tag!('Description', options[:description]) unless options[:description].blank?
|
119
|
+
xml.tag!('Comment', options[:comment]) unless options[:comment].blank?
|
120
|
+
xml.tag!('ExtData', 'Name' => 'COMMENT2', 'Value' => options[:comment2]) unless options[:comment2].blank?
|
121
|
+
xml.tag!('MerchDescr', options[:merch_descr]) unless options[:merch_descr].blank?
|
122
|
+
xml.tag!(
|
123
|
+
'ExtData',
|
124
|
+
'Name' => 'CAPTURECOMPLETE',
|
125
|
+
'Value' => options[:capture_complete]
|
126
|
+
) unless options[:capture_complete].blank?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
xml.target!
|
132
|
+
end
|
133
|
+
|
134
|
+
def add_address(xml, tag, address, options)
|
135
|
+
return if address.nil?
|
136
|
+
|
137
|
+
xml.tag! tag do
|
138
|
+
xml.tag! 'Name', address[:name] unless address[:name].blank?
|
139
|
+
xml.tag! 'EMail', options[:email] unless options[:email].blank?
|
140
|
+
xml.tag! 'Phone', address[:phone] unless address[:phone].blank?
|
141
|
+
xml.tag! 'CustCode', options[:customer] if !options[:customer].blank? && tag == 'BillTo'
|
142
|
+
xml.tag! 'PONum', options[:po_number] if !options[:po_number].blank? && tag == 'BillTo'
|
143
|
+
|
144
|
+
xml.tag! 'Address' do
|
145
|
+
xml.tag! 'Street', address[:address1] unless address[:address1].blank?
|
146
|
+
xml.tag! 'Street2', address[:address2] unless address[:address2].blank?
|
147
|
+
xml.tag! 'City', address[:city] unless address[:city].blank?
|
148
|
+
xml.tag! 'State', address[:state].blank? ? 'N/A' : address[:state]
|
149
|
+
xml.tag! 'Country', address[:country] unless address[:country].blank?
|
150
|
+
xml.tag! 'Zip', address[:zip] unless address[:zip].blank?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def parse(data)
|
156
|
+
response = {}
|
157
|
+
xml = Nokogiri::XML(data)
|
158
|
+
xml.remove_namespaces!
|
159
|
+
root = xml.xpath('//ResponseData')
|
160
|
+
|
161
|
+
# REXML::XPath in Ruby 1.8.6 is now unable to match nodes based on their attributes
|
162
|
+
tx_result = root.xpath('.//TransactionResult').first
|
163
|
+
|
164
|
+
response[:duplicate] = true if tx_result && tx_result.attributes['Duplicate'].to_s == 'true'
|
165
|
+
|
166
|
+
root.xpath('.//*').each do |node|
|
167
|
+
parse_element(response, node)
|
168
|
+
end
|
169
|
+
|
170
|
+
response
|
171
|
+
end
|
172
|
+
|
173
|
+
def parse_element(response, node)
|
174
|
+
node_name = node.name.underscore.to_sym
|
175
|
+
case
|
176
|
+
when node_name == :rp_payment_result
|
177
|
+
# Since we'll have multiple history items, we can't just flatten everything
|
178
|
+
# down as we do everywhere else. RPPaymentResult elements are not contained
|
179
|
+
# in an RPPaymentResults element so we'll come here multiple times
|
180
|
+
response[node_name] ||= []
|
181
|
+
response[node_name] << (payment_result_response = {})
|
182
|
+
node.xpath('.//*').each { |e| parse_element(payment_result_response, e) }
|
183
|
+
when node.xpath('.//*').to_a.any?
|
184
|
+
node.xpath('.//*').each { |e| parse_element(response, e) }
|
185
|
+
when /amt$/.match?(node_name.to_s)
|
186
|
+
# *Amt elements don't put the value in the #text - instead they use a Currency attribute
|
187
|
+
response[node_name] = node.attributes['Currency'].to_s
|
188
|
+
when node_name == :ext_data
|
189
|
+
response[node.attributes['Name'].to_s.underscore.to_sym] = node.attributes['Value'].to_s
|
190
|
+
else
|
191
|
+
response[node_name] = node.text
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def build_headers(content_length)
|
196
|
+
headers = {
|
197
|
+
'Content-Type' => 'text/xml',
|
198
|
+
'Content-Length' => content_length.to_s,
|
199
|
+
'X-VPS-Client-Timeout' => timeout.to_s,
|
200
|
+
'X-VPS-VIT-Integration-Product' => 'ActiveMerchant',
|
201
|
+
'X-VPS-VIT-Runtime-Version' => RUBY_VERSION,
|
202
|
+
'X-VPS-Request-ID' => SecureRandom.hex(16)
|
203
|
+
}
|
204
|
+
|
205
|
+
headers['PAYPAL-NVP'] = 'Y' if self.use_paypal_nvp
|
206
|
+
headers
|
207
|
+
end
|
208
|
+
|
209
|
+
def commit(request_body, options = {})
|
210
|
+
request = build_request(request_body, options)
|
211
|
+
headers = build_headers(request.size)
|
212
|
+
|
213
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, request, headers))
|
214
|
+
|
215
|
+
build_response(
|
216
|
+
success_for(response),
|
217
|
+
response[:message], response,
|
218
|
+
test: test?,
|
219
|
+
authorization: response[:pn_ref] || response[:rp_ref],
|
220
|
+
cvv_result: CVV_CODE[response[:cv_result]],
|
221
|
+
avs_result: { code: response[:avs_result] },
|
222
|
+
fraud_review: under_fraud_review?(response)
|
223
|
+
)
|
224
|
+
end
|
225
|
+
|
226
|
+
def success_for(response)
|
227
|
+
%w(0 126).include?(response[:result])
|
228
|
+
end
|
229
|
+
|
230
|
+
def under_fraud_review?(response)
|
231
|
+
(response[:result] == '126')
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class PayflowExpressResponse < Response
|
4
|
+
def email
|
5
|
+
@params['e_mail']
|
6
|
+
end
|
7
|
+
|
8
|
+
def full_name
|
9
|
+
"#{@params['name']} #{@params['lastname']}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def token
|
13
|
+
@params['token']
|
14
|
+
end
|
15
|
+
|
16
|
+
def payer_id
|
17
|
+
@params['payer_id']
|
18
|
+
end
|
19
|
+
|
20
|
+
# Really the shipping country, but it is all the information provided
|
21
|
+
def payer_country
|
22
|
+
address['country']
|
23
|
+
end
|
24
|
+
|
25
|
+
def phone
|
26
|
+
@params['phone']
|
27
|
+
end
|
28
|
+
|
29
|
+
def address
|
30
|
+
{ 'name' => @params['shiptoname'] || full_name,
|
31
|
+
'company' => nil,
|
32
|
+
'address1' => @params['street'],
|
33
|
+
'address2' => @params['shiptostreet2'] || @params['street2'],
|
34
|
+
'city' => @params['city'],
|
35
|
+
'state' => @params['state'],
|
36
|
+
'country' => @params['country'],
|
37
|
+
'zip' => @params['zip'],
|
38
|
+
'phone' => phone }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|