aktivemerchant 2.0.0
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 +1596 -0
- data/CONTRIBUTORS +511 -0
- data/MIT-LICENSE +20 -0
- data/README.md +18 -0
- data/lib/active_merchant.rb +108 -0
- data/lib/active_merchant/billing.rb +13 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +72 -0
- data/lib/active_merchant/billing/check.rb +76 -0
- data/lib/active_merchant/billing/compatibility.rb +120 -0
- data/lib/active_merchant/billing/credit_card.rb +352 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/gateway.rb +268 -0
- data/lib/active_merchant/billing/gateways.rb +17 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
- data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
- data/lib/active_merchant/billing/gateways/app55.rb +176 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
- data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -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.rb +188 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
- data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
- data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
- data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
- data/lib/active_merchant/billing/gateways/epay.rb +275 -0
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- data/lib/active_merchant/billing/gateways/eway.rb +214 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
- data/lib/active_merchant/billing/gateways/exact.rb +218 -0
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
- data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
- data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
- data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
- data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
- data/lib/active_merchant/billing/gateways/hps.rb +288 -0
- data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
- data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
- data/lib/active_merchant/billing/gateways/litle.rb +346 -0
- data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
- data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
- data/lib/active_merchant/billing/gateways/migs.rb +265 -0
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
- data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
- data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
- data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
- data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
- data/lib/active_merchant/billing/gateways/payex.rb +412 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -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 +264 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
- data/lib/active_merchant/billing/gateways/payway.rb +207 -0
- data/lib/active_merchant/billing/gateways/pin.rb +197 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
- data/lib/active_merchant/billing/gateways/realex.rb +298 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
- data/lib/active_merchant/billing/gateways/sage.rb +175 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
- data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
- data/lib/active_merchant/billing/gateways/tns.rb +227 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
- data/lib/active_merchant/billing/gateways/transax.rb +23 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
- data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
- data/lib/active_merchant/billing/model.rb +30 -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 +91 -0
- data/lib/active_merchant/country.rb +332 -0
- data/lib/active_merchant/empty.rb +20 -0
- data/lib/active_merchant/errors.rb +29 -0
- data/lib/active_merchant/offsite_payments_shim.rb +19 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/support/gateway_support.rb +71 -0
- data/lib/support/outbound_hosts.rb +25 -0
- data/lib/support/ssl_verify.rb +93 -0
- metadata +400 -0
@@ -0,0 +1,291 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
|
6
|
+
# To learn more about the Moneris (US) gateway, please contact
|
7
|
+
# ussales@moneris.com for a copy of their integration guide. For
|
8
|
+
# information on remote testing, please see "Test Environment Penny Value
|
9
|
+
# Response Table", and "Test Environment eFraud (AVS and CVD) Penny
|
10
|
+
# Response Values", available at Moneris' {eSelect Plus Documentation
|
11
|
+
# Centre}[https://www3.moneris.com/connect/en/documents/index.html].
|
12
|
+
class MonerisUsGateway < Gateway
|
13
|
+
self.test_url = 'https://esplusqa.moneris.com/gateway_us/servlet/MpgRequest'
|
14
|
+
self.live_url = 'https://esplus.moneris.com/gateway_us/servlet/MpgRequest'
|
15
|
+
|
16
|
+
self.supported_countries = ['US']
|
17
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover]
|
18
|
+
self.homepage_url = 'http://www.monerisusa.com/'
|
19
|
+
self.display_name = 'Moneris (US)'
|
20
|
+
|
21
|
+
# Initialize the Gateway
|
22
|
+
#
|
23
|
+
# The gateway requires that a valid login and password be passed
|
24
|
+
# in the +options+ hash.
|
25
|
+
#
|
26
|
+
# ==== Options
|
27
|
+
#
|
28
|
+
# * <tt>:login</tt> -- Your Store ID
|
29
|
+
# * <tt>:password</tt> -- Your API Token
|
30
|
+
# * <tt>:cvv_enabled</tt> -- Specify that you would like the CVV passed to the gateway.
|
31
|
+
# Only particular account types at Moneris will allow this.
|
32
|
+
# Defaults to false. (optional)
|
33
|
+
def initialize(options = {})
|
34
|
+
requires!(options, :login, :password)
|
35
|
+
@cvv_enabled = options[:cvv_enabled]
|
36
|
+
@avs_enabled = options[:avs_enabled]
|
37
|
+
options = { :crypt_type => 7 }.merge(options)
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
# Referred to as "PreAuth" in the Moneris integration guide, this action
|
42
|
+
# verifies and locks funds on a customer's card, which then must be
|
43
|
+
# captured at a later date.
|
44
|
+
#
|
45
|
+
# Pass in +order_id+ and optionally a +customer+ parameter.
|
46
|
+
def authorize(money, creditcard_or_datakey, options = {})
|
47
|
+
requires!(options, :order_id)
|
48
|
+
post = {}
|
49
|
+
add_payment_source(post, creditcard_or_datakey, options)
|
50
|
+
post[:amount] = amount(money)
|
51
|
+
post[:order_id] = options[:order_id]
|
52
|
+
post[:address] = options[:billing_address] || options[:address]
|
53
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
54
|
+
action = (post[:data_key].blank?) ? 'us_preauth' : 'us_res_preauth_cc'
|
55
|
+
commit(action, post)
|
56
|
+
end
|
57
|
+
|
58
|
+
# This action verifies funding on a customer's card and readies them for
|
59
|
+
# deposit in a merchant's account.
|
60
|
+
#
|
61
|
+
# Pass in <tt>order_id</tt> and optionally a <tt>customer</tt> parameter
|
62
|
+
def purchase(money, creditcard_or_datakey, options = {})
|
63
|
+
requires!(options, :order_id)
|
64
|
+
post = {}
|
65
|
+
add_payment_source(post, creditcard_or_datakey, options)
|
66
|
+
post[:amount] = amount(money)
|
67
|
+
post[:order_id] = options[:order_id]
|
68
|
+
post[:address] = options[:billing_address] || options[:address]
|
69
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
70
|
+
action = (post[:data_key].blank?) ? 'us_purchase' : 'us_res_purchase_cc'
|
71
|
+
commit(action, post)
|
72
|
+
end
|
73
|
+
|
74
|
+
# This method retrieves locked funds from a customer's account (from a
|
75
|
+
# PreAuth) and prepares them for deposit in a merchant's account.
|
76
|
+
#
|
77
|
+
# Note: Moneris requires both the order_id and the transaction number of
|
78
|
+
# the original authorization. To maintain the same interface as the other
|
79
|
+
# gateways the two numbers are concatenated together with a ; separator as
|
80
|
+
# the authorization number returned by authorization
|
81
|
+
def capture(money, authorization, options = {})
|
82
|
+
commit 'us_completion', crediting_params(authorization, :comp_amount => amount(money))
|
83
|
+
end
|
84
|
+
|
85
|
+
# Voiding requires the original transaction ID and order ID of some open
|
86
|
+
# transaction. Closed transactions must be refunded. Note that the only
|
87
|
+
# methods which may be voided are +capture+ and +purchase+.
|
88
|
+
#
|
89
|
+
# Concatenate your transaction number and order_id by using a semicolon
|
90
|
+
# (';'). This is to keep the Moneris interface consistent with other
|
91
|
+
# gateways. (See +capture+ for details.)
|
92
|
+
def void(authorization, options = {})
|
93
|
+
commit 'us_purchasecorrection', crediting_params(authorization)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Performs a refund. This method requires that the original transaction
|
97
|
+
# number and order number be included. Concatenate your transaction
|
98
|
+
# number and order_id by using a semicolon (';'). This is to keep the
|
99
|
+
# Moneris interface consistent with other gateways. (See +capture+ for
|
100
|
+
# details.)
|
101
|
+
def credit(money, authorization, options = {})
|
102
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
103
|
+
refund(money, authorization, options)
|
104
|
+
end
|
105
|
+
|
106
|
+
def refund(money, authorization, options = {})
|
107
|
+
commit 'us_refund', crediting_params(authorization, :amount => amount(money))
|
108
|
+
end
|
109
|
+
|
110
|
+
def store(credit_card, options = {})
|
111
|
+
post = {}
|
112
|
+
post[:pan] = credit_card.number
|
113
|
+
post[:expdate] = expdate(credit_card)
|
114
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
115
|
+
commit('us_res_add_cc', post)
|
116
|
+
end
|
117
|
+
|
118
|
+
def unstore(data_key, options = {})
|
119
|
+
post = {}
|
120
|
+
post[:data_key] = data_key
|
121
|
+
commit('us_res_delete', post)
|
122
|
+
end
|
123
|
+
|
124
|
+
def update(data_key, credit_card, options = {})
|
125
|
+
post = {}
|
126
|
+
post[:pan] = credit_card.number
|
127
|
+
post[:expdate] = expdate(credit_card)
|
128
|
+
post[:data_key] = data_key
|
129
|
+
post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
|
130
|
+
commit('us_res_update_cc', post)
|
131
|
+
end
|
132
|
+
|
133
|
+
private # :nodoc: all
|
134
|
+
|
135
|
+
def expdate(creditcard)
|
136
|
+
sprintf("%.4i", creditcard.year)[-2..-1] + sprintf("%.2i", creditcard.month)
|
137
|
+
end
|
138
|
+
|
139
|
+
def add_payment_source(post, source, options)
|
140
|
+
if source.is_a?(String)
|
141
|
+
post[:data_key] = source
|
142
|
+
post[:cust_id] = options[:customer]
|
143
|
+
else
|
144
|
+
post[:pan] = source.number
|
145
|
+
post[:expdate] = expdate(source)
|
146
|
+
post[:cvd_value] = source.verification_value if source.verification_value?
|
147
|
+
post[:cust_id] = options[:customer] || source.name
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Common params used amongst the +credit+, +void+ and +capture+ methods
|
152
|
+
def crediting_params(authorization, options = {})
|
153
|
+
{
|
154
|
+
:txn_number => split_authorization(authorization).first,
|
155
|
+
:order_id => split_authorization(authorization).last,
|
156
|
+
:crypt_type => options[:crypt_type] || @options[:crypt_type]
|
157
|
+
}.merge(options)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Splits an +authorization+ param and retrieves the order id and
|
161
|
+
# transaction number in that order.
|
162
|
+
def split_authorization(authorization)
|
163
|
+
if authorization.nil? || authorization.empty? || authorization !~ /;/
|
164
|
+
raise ArgumentError, 'You must include a valid authorization code (e.g. "1234;567")'
|
165
|
+
else
|
166
|
+
authorization.split(';')
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def commit(action, parameters = {})
|
171
|
+
data = post_data(action, parameters)
|
172
|
+
url = test? ? self.test_url : self.live_url
|
173
|
+
raw = ssl_post(url, data)
|
174
|
+
response = parse(raw)
|
175
|
+
|
176
|
+
Response.new(successful?(response), message_from(response[:message]), response,
|
177
|
+
:test => test?,
|
178
|
+
:avs_result => { :code => response[:avs_result_code] },
|
179
|
+
:cvv_result => response[:cvd_result_code] && response[:cvd_result_code][-1,1],
|
180
|
+
:authorization => authorization_from(response)
|
181
|
+
)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Generates a Moneris authorization string of the form 'trans_id;receipt_id'.
|
185
|
+
def authorization_from(response = {})
|
186
|
+
if response[:trans_id] && response[:receipt_id]
|
187
|
+
"#{response[:trans_id]};#{response[:receipt_id]}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# Tests for a successful response from Moneris' servers
|
192
|
+
def successful?(response)
|
193
|
+
response[:response_code] &&
|
194
|
+
response[:complete] &&
|
195
|
+
(0..49).include?(response[:response_code].to_i)
|
196
|
+
end
|
197
|
+
|
198
|
+
def parse(xml)
|
199
|
+
response = { :message => "Global Error Receipt", :complete => false }
|
200
|
+
hashify_xml!(xml, response)
|
201
|
+
response
|
202
|
+
end
|
203
|
+
|
204
|
+
def hashify_xml!(xml, response)
|
205
|
+
xml = REXML::Document.new(xml)
|
206
|
+
return if xml.root.nil?
|
207
|
+
xml.elements.each('//receipt/*') do |node|
|
208
|
+
response[node.name.underscore.to_sym] = normalize(node.text)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def post_data(action, parameters = {})
|
213
|
+
xml = REXML::Document.new
|
214
|
+
root = xml.add_element("request")
|
215
|
+
root.add_element("store_id").text = options[:login]
|
216
|
+
root.add_element("api_token").text = options[:password]
|
217
|
+
root.add_element(transaction_element(action, parameters))
|
218
|
+
|
219
|
+
xml.to_s
|
220
|
+
end
|
221
|
+
|
222
|
+
def transaction_element(action, parameters)
|
223
|
+
transaction = REXML::Element.new(action)
|
224
|
+
|
225
|
+
# Must add the elements in the correct order
|
226
|
+
actions[action].each do |key|
|
227
|
+
case key
|
228
|
+
when :avs_info
|
229
|
+
transaction.add_element(avs_element(parameters[:address])) if @avs_enabled && parameters[:address]
|
230
|
+
when :cvd_info
|
231
|
+
transaction.add_element(cvd_element(parameters[:cvd_value])) if @cvv_enabled
|
232
|
+
else
|
233
|
+
transaction.add_element(key.to_s).text = parameters[key] unless parameters[key].blank?
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
transaction
|
238
|
+
end
|
239
|
+
|
240
|
+
def avs_element(address)
|
241
|
+
full_address = "#{address[:address1]} #{address[:address2]}"
|
242
|
+
tokens = full_address.split(/\s+/)
|
243
|
+
|
244
|
+
element = REXML::Element.new('avs_info')
|
245
|
+
element.add_element('avs_street_number').text = tokens.select{|x| x =~ /\d/}.join(' ')
|
246
|
+
element.add_element('avs_street_name').text = tokens.reject{|x| x =~ /\d/}.join(' ')
|
247
|
+
element.add_element('avs_zipcode').text = address[:zip]
|
248
|
+
element
|
249
|
+
end
|
250
|
+
|
251
|
+
def cvd_element(cvd_value)
|
252
|
+
element = REXML::Element.new('cvd_info')
|
253
|
+
if cvd_value
|
254
|
+
element.add_element('cvd_indicator').text = "1"
|
255
|
+
element.add_element('cvd_value').text = cvd_value
|
256
|
+
else
|
257
|
+
element.add_element('cvd_indicator').text = "0"
|
258
|
+
end
|
259
|
+
element
|
260
|
+
end
|
261
|
+
|
262
|
+
def message_from(message)
|
263
|
+
return 'Unspecified error' if message.blank?
|
264
|
+
message.gsub(/[^\w]/, ' ').split.join(" ").capitalize
|
265
|
+
end
|
266
|
+
|
267
|
+
def actions
|
268
|
+
{
|
269
|
+
"us_purchase" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info],
|
270
|
+
"us_preauth" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type, :avs_info, :cvd_info],
|
271
|
+
"us_command" => [:order_id],
|
272
|
+
"us_refund" => [:order_id, :amount, :txn_number, :crypt_type],
|
273
|
+
"us_indrefund" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
274
|
+
"us_completion" => [:order_id, :comp_amount, :txn_number, :crypt_type],
|
275
|
+
"us_purchasecorrection" => [:order_id, :txn_number, :crypt_type],
|
276
|
+
"us_cavvpurcha" => [:order_id, :cust_id, :amount, :pan, :expdate, :cav],
|
277
|
+
"us_cavvpreaut" => [:order_id, :cust_id, :amount, :pan, :expdate, :cavv],
|
278
|
+
"us_transact" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
279
|
+
"us_Batchcloseall" => [],
|
280
|
+
"us_opentotals" => [:ecr_number],
|
281
|
+
"us_batchclose" => [:ecr_number],
|
282
|
+
"us_res_add_cc" => [:pan, :expdate, :crypt_type],
|
283
|
+
"us_res_delete" => [:data_key],
|
284
|
+
"us_res_update_cc" => [:data_key, :pan, :expdate, :crypt_type],
|
285
|
+
"us_res_purchase_cc" => [:data_key, :order_id, :cust_id, :amount, :crypt_type],
|
286
|
+
"us_res_preauth_cc" => [:data_key, :order_id, :cust_id, :amount, :crypt_type]
|
287
|
+
}
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class MoneyMoversGateway < Gateway
|
4
|
+
self.live_url = self.test_url = 'https://secure.mmoagateway.com/api/transact.php'
|
5
|
+
|
6
|
+
APPROVED, DECLINED, ERROR = 1, 2, 3
|
7
|
+
|
8
|
+
self.homepage_url = 'http://mmoa.us/'
|
9
|
+
self.display_name = 'MoneyMovers'
|
10
|
+
self.supported_countries = ['US']
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
requires!(options, :login, :password)
|
15
|
+
@options = options
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def purchase(money, creditcard, options = {})
|
20
|
+
post = {}
|
21
|
+
add_invoice(post, options)
|
22
|
+
add_creditcard(post, creditcard)
|
23
|
+
add_address(post, options)
|
24
|
+
add_customer_data(post, options)
|
25
|
+
commit('sale', money, post)
|
26
|
+
end
|
27
|
+
|
28
|
+
def authorize(money, creditcard, options = {})
|
29
|
+
post = {}
|
30
|
+
add_invoice(post, options)
|
31
|
+
add_creditcard(post, creditcard)
|
32
|
+
add_address(post, options)
|
33
|
+
add_customer_data(post, options)
|
34
|
+
commit('auth', money, post)
|
35
|
+
end
|
36
|
+
|
37
|
+
def capture(money, authorization, options = {})
|
38
|
+
options[:transactionid] = authorization
|
39
|
+
commit('capture', money, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def void(authorization, options = {})
|
43
|
+
options[:transactionid] = authorization
|
44
|
+
commit('void', nil, options)
|
45
|
+
end
|
46
|
+
|
47
|
+
def refund(money, authorization, options = {})
|
48
|
+
commit('refund', money, options.merge(:transactionid => authorization))
|
49
|
+
end
|
50
|
+
|
51
|
+
def credit(money, authorization, options = {})
|
52
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
53
|
+
refund(money, authorization, options)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def add_customer_data(post, options)
|
59
|
+
post[:firstname] = options[:first_name]
|
60
|
+
post[:lastname] = options[:last_name]
|
61
|
+
|
62
|
+
post[:email] = options[:email]
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_address(post, options)
|
66
|
+
if address = (options[:billing_address] || options[:address])
|
67
|
+
post[:company] = address[:company]
|
68
|
+
post[:address1] = address[:address1]
|
69
|
+
post[:address2] = address[:address2]
|
70
|
+
post[:city] = address[:city]
|
71
|
+
post[:state] = address[:state]
|
72
|
+
post[:zip] = address[:zip]
|
73
|
+
post[:country] = address[:country]
|
74
|
+
post[:phone] = address[:phone]
|
75
|
+
end
|
76
|
+
if address = options[:shipping_address]
|
77
|
+
post[:shipping_firstname] = address[:first_name]
|
78
|
+
post[:shipping_lastname] = address[:last_name]
|
79
|
+
post[:shipping_company] = address[:company]
|
80
|
+
post[:shipping_address1] = address[:address1]
|
81
|
+
post[:shipping_address2] = address[:address2]
|
82
|
+
post[:shipping_city] = address[:city]
|
83
|
+
post[:shipping_state] = address[:state]
|
84
|
+
post[:shipping_zip] = address[:zip]
|
85
|
+
post[:shipping_country] = address[:country]
|
86
|
+
post[:shipping_email] = address[:email]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def add_invoice(post, options)
|
91
|
+
post[:orderid] = options[:order_id]
|
92
|
+
post[:orderdescription] = options[:description]
|
93
|
+
end
|
94
|
+
|
95
|
+
def add_creditcard(post, creditcard)
|
96
|
+
post[:ccnumber] = creditcard.number
|
97
|
+
post[:ccexp] = expdate(creditcard)
|
98
|
+
post[:cvv] = creditcard.verification_value
|
99
|
+
end
|
100
|
+
|
101
|
+
def parse(body)
|
102
|
+
body.split('&').inject({}) do |memo, x|
|
103
|
+
k, v = x.split('=')
|
104
|
+
memo[k] = v
|
105
|
+
memo
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def commit(action, money, parameters)
|
110
|
+
parameters[:amount] = amount(money)
|
111
|
+
|
112
|
+
data = ssl_post(self.live_url, post_data(action, parameters))
|
113
|
+
response = parse(data)
|
114
|
+
message = message_from(response)
|
115
|
+
|
116
|
+
Response.new(success?(response), message, response,
|
117
|
+
:test => test?,
|
118
|
+
:authorization => response['transactionid'],
|
119
|
+
:avs_result => {:code => response['avsresponse']},
|
120
|
+
:cvv_result => response['cvvresponse']
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
def success?(response)
|
125
|
+
response['response'] == '1'
|
126
|
+
end
|
127
|
+
|
128
|
+
def test?
|
129
|
+
(@options[:login].eql?('demo')) && (@options[:password].eql?('password'))
|
130
|
+
end
|
131
|
+
|
132
|
+
def message_from(response)
|
133
|
+
case response['response'].to_i
|
134
|
+
when APPROVED
|
135
|
+
"Transaction Approved"
|
136
|
+
when DECLINED
|
137
|
+
"Transaction Declined"
|
138
|
+
else
|
139
|
+
"Error in transaction data or system error"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def post_data(action, parameters = {})
|
144
|
+
parameters[:type] = action
|
145
|
+
parameters[:username] = @options[:login]
|
146
|
+
parameters[:password] = @options[:password]
|
147
|
+
parameters.map{|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
@@ -0,0 +1,280 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# The National Australia Bank provide a payment gateway that seems to
|
6
|
+
# be a rebadged Securepay Australia service, though some differences exist.
|
7
|
+
class NabTransactGateway < Gateway
|
8
|
+
API_VERSION = 'xml-4.2'
|
9
|
+
PERIODIC_API_VERSION = "spxml-4.2"
|
10
|
+
|
11
|
+
class_attribute :test_periodic_url, :live_periodic_url
|
12
|
+
|
13
|
+
self.test_url = 'https://transact.nab.com.au/test/xmlapi/payment'
|
14
|
+
self.live_url = 'https://transact.nab.com.au/live/xmlapi/payment'
|
15
|
+
self.test_periodic_url = 'https://transact.nab.com.au/xmlapidemo/periodic'
|
16
|
+
self.live_periodic_url = 'https://transact.nab.com.au/xmlapi/periodic'
|
17
|
+
|
18
|
+
self.supported_countries = ['AU']
|
19
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb]
|
20
|
+
|
21
|
+
self.homepage_url = 'http://transact.nab.com.au'
|
22
|
+
self.display_name = 'NAB Transact'
|
23
|
+
self.money_format = :cents
|
24
|
+
self.default_currency = 'AUD'
|
25
|
+
|
26
|
+
#Transactions currently accepted by NAB Transact XML API
|
27
|
+
TRANSACTIONS = {
|
28
|
+
:purchase => 0, #Standard Payment
|
29
|
+
:refund => 4, #Refund
|
30
|
+
:void => 6, #Client Reversal (Void)
|
31
|
+
:unmatched_refund => 666, #Unmatched Refund
|
32
|
+
:authorization => 10, #Preauthorise
|
33
|
+
:capture => 11 #Preauthorise Complete (Advice)
|
34
|
+
}
|
35
|
+
|
36
|
+
PERIODIC_TYPES = {
|
37
|
+
:addcrn => 5,
|
38
|
+
:editcrn => 5,
|
39
|
+
:deletecrn => 5,
|
40
|
+
:trigger => 8
|
41
|
+
}
|
42
|
+
|
43
|
+
SUCCESS_CODES = [ '00', '08', '11', '16', '77' ]
|
44
|
+
|
45
|
+
|
46
|
+
def initialize(options = {})
|
47
|
+
requires!(options, :login, :password)
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
51
|
+
def purchase(money, credit_card_or_stored_id, options = {})
|
52
|
+
if credit_card_or_stored_id.respond_to?(:number)
|
53
|
+
#Credit card for instant payment
|
54
|
+
commit :purchase, build_purchase_request(money, credit_card_or_stored_id, options)
|
55
|
+
else
|
56
|
+
#Triggered payment for an existing stored credit card
|
57
|
+
options[:billing_id] = credit_card_or_stored_id.to_s
|
58
|
+
commit_periodic build_periodic_item(:trigger, money, nil, options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def credit(money, credit_card, options = {})
|
63
|
+
commit :unmatched_refund, build_purchase_request(money, credit_card, options)
|
64
|
+
end
|
65
|
+
|
66
|
+
def refund(money, authorization, options = {})
|
67
|
+
commit :refund, build_reference_request(money, authorization, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def authorize(money, credit_card, options = {})
|
71
|
+
commit :authorization, build_purchase_request(money, credit_card, options)
|
72
|
+
end
|
73
|
+
|
74
|
+
def capture(money, authorization, options = {})
|
75
|
+
commit :capture, build_reference_request(money, authorization, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def store(creditcard, options = {})
|
79
|
+
requires!(options, :billing_id, :amount)
|
80
|
+
commit_periodic(build_periodic_item(:addcrn, options[:amount], creditcard, options))
|
81
|
+
end
|
82
|
+
|
83
|
+
def unstore(identification, options = {})
|
84
|
+
options[:billing_id] = identification
|
85
|
+
commit_periodic(build_periodic_item(:deletecrn, options[:amount], nil, options))
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def add_metadata(xml, options)
|
91
|
+
if options[:merchant_name] || options[:merchant_location]
|
92
|
+
xml.tag! 'metadata' do
|
93
|
+
xml.tag! 'meta', :name => 'ca_name', :value => options[:merchant_name] if options[:merchant_name]
|
94
|
+
xml.tag! 'meta', :name => 'ca_location', :value => options[:merchant_location] if options[:merchant_location]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def build_purchase_request(money, credit_card, options)
|
100
|
+
xml = Builder::XmlMarkup.new
|
101
|
+
xml.tag! 'amount', amount(money)
|
102
|
+
xml.tag! 'currency', options[:currency] || currency(money)
|
103
|
+
xml.tag! 'purchaseOrderNo', options[:order_id].to_s.gsub(/[ ']/, '')
|
104
|
+
|
105
|
+
xml.tag! 'CreditCardInfo' do
|
106
|
+
xml.tag! 'cardNumber', credit_card.number
|
107
|
+
xml.tag! 'expiryDate', expdate(credit_card)
|
108
|
+
xml.tag! 'cvv', credit_card.verification_value if credit_card.verification_value?
|
109
|
+
end
|
110
|
+
|
111
|
+
add_metadata(xml, options)
|
112
|
+
|
113
|
+
xml.target!
|
114
|
+
end
|
115
|
+
|
116
|
+
def build_reference_request(money, reference, options)
|
117
|
+
xml = Builder::XmlMarkup.new
|
118
|
+
|
119
|
+
transaction_id, order_id, preauth_id, original_amount = reference.split('*')
|
120
|
+
|
121
|
+
xml.tag! 'amount', (money ? amount(money) : original_amount)
|
122
|
+
xml.tag! 'currency', options[:currency] || currency(money)
|
123
|
+
xml.tag! 'txnID', transaction_id
|
124
|
+
xml.tag! 'purchaseOrderNo', order_id
|
125
|
+
xml.tag! 'preauthID', preauth_id
|
126
|
+
|
127
|
+
add_metadata(xml, options)
|
128
|
+
|
129
|
+
xml.target!
|
130
|
+
end
|
131
|
+
|
132
|
+
#Generate payment request XML
|
133
|
+
# - API is set to allow multiple Txn's but currently only allows one
|
134
|
+
# - txnSource = 23 - (XML)
|
135
|
+
def build_request(action, body)
|
136
|
+
xml = Builder::XmlMarkup.new
|
137
|
+
xml.instruct!
|
138
|
+
xml.tag! 'NABTransactMessage' do
|
139
|
+
xml.tag! 'MessageInfo' do
|
140
|
+
xml.tag! 'messageID', SecureRandom.hex(15)
|
141
|
+
xml.tag! 'messageTimestamp', generate_timestamp
|
142
|
+
xml.tag! 'timeoutValue', request_timeout
|
143
|
+
xml.tag! 'apiVersion', API_VERSION
|
144
|
+
end
|
145
|
+
|
146
|
+
xml.tag! 'MerchantInfo' do
|
147
|
+
xml.tag! 'merchantID', @options[:login]
|
148
|
+
xml.tag! 'password', @options[:password]
|
149
|
+
end
|
150
|
+
|
151
|
+
xml.tag! 'RequestType', 'Payment'
|
152
|
+
xml.tag! 'Payment' do
|
153
|
+
xml.tag! 'TxnList', "count" => 1 do
|
154
|
+
xml.tag! 'Txn', "ID" => 1 do
|
155
|
+
xml.tag! 'txnType', TRANSACTIONS[action]
|
156
|
+
xml.tag! 'txnSource', 23
|
157
|
+
xml << body
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
xml.target!
|
164
|
+
end
|
165
|
+
|
166
|
+
def build_periodic_item(action, money, credit_card, options)
|
167
|
+
xml = Builder::XmlMarkup.new
|
168
|
+
|
169
|
+
xml.tag! 'actionType', action.to_s
|
170
|
+
xml.tag! 'periodicType', PERIODIC_TYPES[action] if PERIODIC_TYPES[action]
|
171
|
+
xml.tag! 'currency', options[:currency] || currency(money)
|
172
|
+
xml.tag! 'crn', options[:billing_id]
|
173
|
+
|
174
|
+
if credit_card
|
175
|
+
xml.tag! 'CreditCardInfo' do
|
176
|
+
xml.tag! 'cardNumber', credit_card.number
|
177
|
+
xml.tag! 'expiryDate', expdate(credit_card)
|
178
|
+
xml.tag! 'cvv', credit_card.verification_value if credit_card.verification_value?
|
179
|
+
end
|
180
|
+
end
|
181
|
+
xml.tag! 'amount', amount(money)
|
182
|
+
|
183
|
+
xml.target!
|
184
|
+
end
|
185
|
+
|
186
|
+
def build_periodic_request(body)
|
187
|
+
xml = Builder::XmlMarkup.new
|
188
|
+
xml.instruct!
|
189
|
+
xml.tag! 'NABTransactMessage' do
|
190
|
+
xml.tag! 'MessageInfo' do
|
191
|
+
xml.tag! 'messageID', SecureRandom.hex(15)
|
192
|
+
xml.tag! 'messageTimestamp', generate_timestamp
|
193
|
+
xml.tag! 'timeoutValue', request_timeout
|
194
|
+
xml.tag! 'apiVersion', PERIODIC_API_VERSION
|
195
|
+
end
|
196
|
+
|
197
|
+
xml.tag! 'MerchantInfo' do
|
198
|
+
xml.tag! 'merchantID', @options[:login]
|
199
|
+
xml.tag! 'password', @options[:password]
|
200
|
+
end
|
201
|
+
|
202
|
+
xml.tag! 'RequestType', 'Periodic'
|
203
|
+
xml.tag! 'Periodic' do
|
204
|
+
xml.tag! 'PeriodicList', "count" => 1 do
|
205
|
+
xml.tag! 'PeriodicItem', "ID" => 1 do
|
206
|
+
xml << body
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
xml.target!
|
213
|
+
end
|
214
|
+
|
215
|
+
def commit(action, request)
|
216
|
+
response = parse(ssl_post(test? ? self.test_url : self.live_url, build_request(action, request)))
|
217
|
+
|
218
|
+
Response.new(success?(response), message_from(response), response,
|
219
|
+
:test => test?,
|
220
|
+
:authorization => authorization_from(response)
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
def commit_periodic(request)
|
225
|
+
response = parse(ssl_post(test? ? self.test_periodic_url : self.live_periodic_url, build_periodic_request(request)))
|
226
|
+
Response.new(success?(response), message_from(response), response,
|
227
|
+
:test => test?,
|
228
|
+
:authorization => authorization_from(response)
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
def success?(response)
|
233
|
+
SUCCESS_CODES.include?(response[:response_code])
|
234
|
+
end
|
235
|
+
|
236
|
+
def authorization_from(response)
|
237
|
+
[response[:txn_id], response[:purchase_order_no], response[:preauth_id], response[:amount]].join('*')
|
238
|
+
end
|
239
|
+
|
240
|
+
def message_from(response)
|
241
|
+
response[:response_text] || response[:status_description]
|
242
|
+
end
|
243
|
+
|
244
|
+
def expdate(credit_card)
|
245
|
+
"#{format(credit_card.month, :two_digits)}/#{format(credit_card.year, :two_digits)}"
|
246
|
+
end
|
247
|
+
|
248
|
+
def parse(body)
|
249
|
+
xml = REXML::Document.new(body)
|
250
|
+
|
251
|
+
response = {}
|
252
|
+
|
253
|
+
xml.root.elements.to_a.each do |node|
|
254
|
+
parse_element(response, node)
|
255
|
+
end
|
256
|
+
|
257
|
+
response
|
258
|
+
end
|
259
|
+
|
260
|
+
def parse_element(response, node)
|
261
|
+
if node.has_elements?
|
262
|
+
node.elements.each{|element| parse_element(response, element) }
|
263
|
+
else
|
264
|
+
response[node.name.underscore.to_sym] = node.text
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# YYYYDDMMHHNNSSKKK000sOOO
|
269
|
+
def generate_timestamp
|
270
|
+
time = Time.now.utc
|
271
|
+
time.strftime("%Y%d%m%H%M%S#{time.usec}+000")
|
272
|
+
end
|
273
|
+
|
274
|
+
def request_timeout
|
275
|
+
@options[:request_timeout] || 60
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|