fishman-activemerchant 1.18.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.
- data/CHANGELOG +733 -0
- data/CONTRIBUTORS +257 -0
- data/MIT-LICENSE +20 -0
- data/gem-public_cert.pem +20 -0
- data/lib/active_merchant.rb +47 -0
- data/lib/active_merchant/billing.rb +9 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +57 -0
- data/lib/active_merchant/billing/check.rb +68 -0
- data/lib/active_merchant/billing/credit_card.rb +260 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/expiry_date.rb +34 -0
- data/lib/active_merchant/billing/gateway.rb +170 -0
- data/lib/active_merchant/billing/gateways.rb +18 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +693 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +303 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
- data/lib/active_merchant/billing/gateways/epay.rb +274 -0
- data/lib/active_merchant/billing/gateways/eway.rb +277 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +264 -0
- data/lib/active_merchant/billing/gateways/exact.rb +222 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -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 +55 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +274 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -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 +222 -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 +235 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +354 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +184 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
- data/lib/active_merchant/billing/gateways/paypal_express_de.rb +14 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +297 -0
- data/lib/active_merchant/billing/gateways/realex.rb +311 -0
- data/lib/active_merchant/billing/gateways/sage.rb +146 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
- data/lib/active_merchant/billing/gateways/transax.rb +25 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
- data/lib/active_merchant/billing/integrations.rb +17 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
- data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
- data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
- data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
- data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
- data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
- data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
- data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
- data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
- data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
- data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
- data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +28 -0
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +50 -0
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
- data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
- data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
- data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
- data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/helper.rb +96 -0
- data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
- data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
- data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
- data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
- data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
- data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/notification.rb +62 -0
- data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
- data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
- data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
- data/lib/active_merchant/billing/integrations/return.rb +42 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
- data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
- data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
- data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
- data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
- data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
- data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
- data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
- data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
- data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
- data/lib/active_merchant/billing/response.rb +32 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/support/gateway_support.rb +58 -0
- data/lib/support/outbound_hosts.rb +25 -0
- metadata +335 -0
@@ -0,0 +1,282 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
# ActiveMerchant Implementation for Quantum Gateway XML Requester Service
|
4
|
+
# Based on API Doc from 8/6/2009
|
5
|
+
#
|
6
|
+
# Important Notes
|
7
|
+
# * Support is included for a customer id via the :customer option, invoice number via :invoice option, invoice description via :merchant option and memo via :description option
|
8
|
+
# * You can force email of receipt with :email_receipt => true
|
9
|
+
# * You can force email of merchant receipt with :merchant_receipt => true
|
10
|
+
# * You can exclude CVV with :ignore_cvv => true
|
11
|
+
# * All transactions use dollar values.
|
12
|
+
class QuantumGateway < Gateway
|
13
|
+
LIVE_URL = 'https://secure.quantumgateway.com/cgi/xml_requester.php'
|
14
|
+
|
15
|
+
# visa, master, american_express, discover
|
16
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
17
|
+
self.supported_countries = ['US']
|
18
|
+
self.default_currency = 'USD'
|
19
|
+
self.money_format = :dollars
|
20
|
+
self.homepage_url = 'http://www.quantumgateway.com'
|
21
|
+
self.display_name = 'Quantum Gateway'
|
22
|
+
|
23
|
+
# These are the options that can be used when creating a new Quantum Gateway object.
|
24
|
+
#
|
25
|
+
# :login => Your Quantum Gateway Gateway ID
|
26
|
+
#
|
27
|
+
# :password => Your Quantum Gateway Vault Key or Restrict Key
|
28
|
+
#
|
29
|
+
# NOTE: For testing supply your test GatewayLogin and GatewayKey
|
30
|
+
#
|
31
|
+
# :email_receipt => true if you want a receipt sent to the customer (false be default)
|
32
|
+
#
|
33
|
+
# :merchant_receipt => true if you want to override receiving the merchant receipt
|
34
|
+
#
|
35
|
+
# :ignore_avs => true ignore both AVS and CVV verification
|
36
|
+
# :ignore_cvv => true don't want to use CVV so continue processing even if CVV would have failed
|
37
|
+
#
|
38
|
+
def initialize(options = {})
|
39
|
+
requires!(options, :login, :password)
|
40
|
+
@options = options
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
# Should run against the test servers or not?
|
45
|
+
def test?
|
46
|
+
@options[:test] || Base.gateway_mode == :test
|
47
|
+
end
|
48
|
+
|
49
|
+
# Request an authorization for an amount from CyberSource
|
50
|
+
#
|
51
|
+
def authorize(money, creditcard, options = {})
|
52
|
+
setup_address_hash(options)
|
53
|
+
commit(build_auth_request(money, creditcard, options), options )
|
54
|
+
end
|
55
|
+
|
56
|
+
# Capture an authorization that has previously been requested
|
57
|
+
def capture(money, authorization, options = {})
|
58
|
+
setup_address_hash(options)
|
59
|
+
commit(build_capture_request(money, authorization, options), options)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Purchase is an auth followed by a capture
|
63
|
+
# You must supply an order_id in the options hash
|
64
|
+
def purchase(money, creditcard, options = {})
|
65
|
+
setup_address_hash(options)
|
66
|
+
commit(build_purchase_request(money, creditcard, options), options)
|
67
|
+
end
|
68
|
+
|
69
|
+
def void(identification, options = {})
|
70
|
+
commit(build_void_request(identification, options), options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def refund(money, identification, options = {})
|
74
|
+
commit(build_credit_request(money, identification, options), options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def credit(money, identification, options = {})
|
78
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
79
|
+
refund(money, identification, options)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def setup_address_hash(options)
|
85
|
+
options[:billing_address] = options[:billing_address] || options[:address] || {}
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_auth_request(money, creditcard, options)
|
89
|
+
xml = Builder::XmlMarkup.new
|
90
|
+
add_common_credit_card_info(xml,'AUTH_ONLY')
|
91
|
+
add_purchase_data(xml, money)
|
92
|
+
add_creditcard(xml, creditcard)
|
93
|
+
add_address(xml, creditcard, options[:billing_address], options)
|
94
|
+
add_invoice_details(xml, options)
|
95
|
+
add_customer_details(xml, options)
|
96
|
+
add_memo(xml, options)
|
97
|
+
add_business_rules_data(xml)
|
98
|
+
xml.target!
|
99
|
+
end
|
100
|
+
|
101
|
+
def build_capture_request(money, authorization, options)
|
102
|
+
xml = Builder::XmlMarkup.new
|
103
|
+
add_common_credit_card_info(xml,'PREVIOUS_SALE')
|
104
|
+
transaction_id, _ = authorization_parts_from(authorization)
|
105
|
+
add_transaction_id(xml, transaction_id)
|
106
|
+
xml.target!
|
107
|
+
end
|
108
|
+
|
109
|
+
def build_purchase_request(money, creditcard, options)
|
110
|
+
xml = Builder::XmlMarkup.new
|
111
|
+
add_common_credit_card_info(xml, @options[:ignore_avs] || @options[:ignore_cvv] ? 'SALES' : 'AUTH_CAPTURE')
|
112
|
+
add_address(xml, creditcard, options[:billing_address], options)
|
113
|
+
add_purchase_data(xml, money)
|
114
|
+
add_creditcard(xml, creditcard)
|
115
|
+
add_invoice_details(xml, options)
|
116
|
+
add_customer_details(xml, options)
|
117
|
+
add_memo(xml, options)
|
118
|
+
add_business_rules_data(xml)
|
119
|
+
xml.target!
|
120
|
+
end
|
121
|
+
|
122
|
+
def build_void_request(authorization, options)
|
123
|
+
xml = Builder::XmlMarkup.new
|
124
|
+
add_common_credit_card_info(xml,'VOID')
|
125
|
+
transaction_id, _ = authorization_parts_from(authorization)
|
126
|
+
add_transaction_id(xml, transaction_id)
|
127
|
+
xml.target!
|
128
|
+
end
|
129
|
+
|
130
|
+
def build_credit_request(money, authorization, options)
|
131
|
+
xml = Builder::XmlMarkup.new
|
132
|
+
add_common_credit_card_info(xml,'RETURN')
|
133
|
+
add_purchase_data(xml, money)
|
134
|
+
transaction_id, cc = authorization_parts_from(authorization)
|
135
|
+
add_transaction_id(xml, transaction_id)
|
136
|
+
xml.tag! 'CreditCardNumber', cc
|
137
|
+
xml.target!
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_common_credit_card_info(xml, process_type)
|
141
|
+
xml.tag! 'RequestType', 'ProcessSingleTransaction'
|
142
|
+
xml.tag! 'TransactionType', 'CREDIT'
|
143
|
+
xml.tag! 'PaymentType', 'CC'
|
144
|
+
xml.tag! 'ProcessType', process_type
|
145
|
+
end
|
146
|
+
|
147
|
+
def add_business_rules_data(xml)
|
148
|
+
xml.tag!('CustomerEmail', @options[:email_receipt] ? 'Y' : 'N')
|
149
|
+
xml.tag!('MerchantEmail', @options[:merchant_receipt] ? 'Y' : 'N')
|
150
|
+
end
|
151
|
+
|
152
|
+
def add_invoice_details(xml, options)
|
153
|
+
xml.tag! 'InvoiceNumber', options[:invoice]
|
154
|
+
xml.tag! 'InvoiceDescription', options[:merchant]
|
155
|
+
end
|
156
|
+
|
157
|
+
def add_customer_details(xml, options)
|
158
|
+
xml.tag! 'CustomerID', options[:customer]
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_transaction_id(xml, transaction_id)
|
162
|
+
xml.tag! 'TransactionID', transaction_id
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_memo(xml, options)
|
166
|
+
xml.tag! 'Memo', options[:description]
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_purchase_data(xml, money = 0)
|
170
|
+
xml.tag! 'Amount', amount(money)
|
171
|
+
xml.tag! 'TransactionDate', Time.now
|
172
|
+
end
|
173
|
+
|
174
|
+
def add_address(xml, creditcard, address, options, shipTo = false)
|
175
|
+
xml.tag! 'FirstName', creditcard.first_name
|
176
|
+
xml.tag! 'LastName', creditcard.last_name
|
177
|
+
xml.tag! 'Address', address[:address1] # => there is no support for address2 in quantum
|
178
|
+
xml.tag! 'City', address[:city]
|
179
|
+
xml.tag! 'State', address[:state]
|
180
|
+
xml.tag! 'ZipCode', address[:zip]
|
181
|
+
xml.tag! 'Country', address[:country]
|
182
|
+
xml.tag! 'EmailAddress', options[:email]
|
183
|
+
xml.tag! 'IPAddress', options[:ip]
|
184
|
+
end
|
185
|
+
|
186
|
+
def add_creditcard(xml, creditcard)
|
187
|
+
xml.tag! 'PaymentType', 'CC'
|
188
|
+
xml.tag! 'CreditCardNumber', creditcard.number
|
189
|
+
xml.tag! 'ExpireMonth', format(creditcard.month, :two_digits)
|
190
|
+
xml.tag! 'ExpireYear', format(creditcard.year, :four_digits)
|
191
|
+
xml.tag!('CVV2', creditcard.verification_value) unless (@options[:ignore_cvv] || creditcard.verification_value.blank? )
|
192
|
+
end
|
193
|
+
|
194
|
+
# Where we actually build the full SOAP request using builder
|
195
|
+
def build_request(body, options)
|
196
|
+
xml = Builder::XmlMarkup.new
|
197
|
+
xml.instruct!
|
198
|
+
xml.tag! 'QGWRequest' do
|
199
|
+
xml.tag! 'Authentication' do
|
200
|
+
xml.tag! 'GatewayLogin', @options[:login]
|
201
|
+
xml.tag! 'GatewayKey', @options[:password]
|
202
|
+
end
|
203
|
+
xml.tag! 'Request' do
|
204
|
+
xml << body
|
205
|
+
end
|
206
|
+
end
|
207
|
+
xml.target!
|
208
|
+
end
|
209
|
+
|
210
|
+
# Contact CyberSource, make the SOAP request, and parse the reply into a Response object
|
211
|
+
def commit(request, options)
|
212
|
+
headers = { 'Content-Type' => 'text/xml' }
|
213
|
+
response = parse(ssl_post(LIVE_URL, build_request(request, options), headers))
|
214
|
+
|
215
|
+
success = response[:request_status] == "Success"
|
216
|
+
message = response[:request_message]
|
217
|
+
|
218
|
+
if success # => checking for connectivity success first
|
219
|
+
success = %w(APPROVED FORCED VOIDED).include?(response[:Status])
|
220
|
+
message = response[:StatusDescription]
|
221
|
+
authorization = success ? authorization_for(response) : nil
|
222
|
+
end
|
223
|
+
|
224
|
+
Response.new(success, message, response,
|
225
|
+
:test => test?,
|
226
|
+
:authorization => authorization,
|
227
|
+
:avs_result => { :code => response[:AVSResponseCode] },
|
228
|
+
:cvv_result => response[:CVV2ResponseCode]
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Parse the SOAP response
|
233
|
+
# Technique inspired by the Paypal Gateway
|
234
|
+
def parse(xml)
|
235
|
+
reply = {}
|
236
|
+
|
237
|
+
begin
|
238
|
+
xml = REXML::Document.new(xml)
|
239
|
+
|
240
|
+
root = REXML::XPath.first(xml, "//QGWRequest/ResponseSummary")
|
241
|
+
parse_element(reply, root)
|
242
|
+
reply[:request_status] = reply[:Status]
|
243
|
+
reply[:request_message] = "#{reply[:Status]}: #{reply[:StatusDescription]}"
|
244
|
+
|
245
|
+
if root = REXML::XPath.first(xml, "//QGWRequest/Result")
|
246
|
+
root.elements.to_a.each do |node|
|
247
|
+
parse_element(reply, node)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
rescue Exception => e
|
251
|
+
reply[:request_status] = 'Failure'
|
252
|
+
reply[:request_message] = "Failure: There was a problem parsing the response XML"
|
253
|
+
end
|
254
|
+
|
255
|
+
return reply
|
256
|
+
end
|
257
|
+
|
258
|
+
def parse_element(reply, node)
|
259
|
+
if node.has_elements?
|
260
|
+
node.elements.each{|e| parse_element(reply, e) }
|
261
|
+
else
|
262
|
+
if node.parent.name =~ /item/
|
263
|
+
parent = node.parent.name + (node.parent.attributes["id"] ? "_" + node.parent.attributes["id"] : '')
|
264
|
+
reply[(parent + '_' + node.name).to_sym] = node.text
|
265
|
+
else
|
266
|
+
reply[node.name.to_sym] = node.text
|
267
|
+
end
|
268
|
+
end
|
269
|
+
return reply
|
270
|
+
end
|
271
|
+
|
272
|
+
def authorization_for(reply)
|
273
|
+
"#{reply[:TransactionID]};#{reply[:CreditCardNumber]}"
|
274
|
+
end
|
275
|
+
|
276
|
+
def authorization_parts_from(authorization)
|
277
|
+
authorization.split(/;/)
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
@@ -0,0 +1,297 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
class QuickpayGateway < Gateway
|
7
|
+
URL = 'https://secure.quickpay.dk/api'
|
8
|
+
|
9
|
+
self.default_currency = 'DKK'
|
10
|
+
self.money_format = :cents
|
11
|
+
self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master, :american_express, :diners_club, :jcb, :maestro]
|
12
|
+
self.supported_countries = ['DK', 'SE']
|
13
|
+
self.homepage_url = 'http://quickpay.dk/'
|
14
|
+
self.display_name = 'Quickpay'
|
15
|
+
|
16
|
+
MD5_CHECK_FIELDS = {
|
17
|
+
3 => {
|
18
|
+
:authorize => %w(protocol msgtype merchant ordernumber amount
|
19
|
+
currency autocapture cardnumber expirationdate
|
20
|
+
cvd cardtypelock testmode),
|
21
|
+
|
22
|
+
:capture => %w(protocol msgtype merchant amount transaction),
|
23
|
+
|
24
|
+
:cancel => %w(protocol msgtype merchant transaction),
|
25
|
+
|
26
|
+
:refund => %w(protocol msgtype merchant amount transaction),
|
27
|
+
|
28
|
+
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
29
|
+
expirationdate cvd cardtypelock description testmode),
|
30
|
+
|
31
|
+
:recurring => %w(protocol msgtype merchant ordernumber amount
|
32
|
+
currency autocapture transaction),
|
33
|
+
|
34
|
+
:status => %w(protocol msgtype merchant transaction),
|
35
|
+
|
36
|
+
:chstatus => %w(protocol msgtype merchant)
|
37
|
+
},
|
38
|
+
|
39
|
+
4 => {
|
40
|
+
:authorize => %w(protocol msgtype merchant ordernumber amount
|
41
|
+
currency autocapture cardnumber expirationdate cvd
|
42
|
+
cardtypelock testmode fraud_remote_addr
|
43
|
+
fraud_http_accept fraud_http_accept_language
|
44
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
45
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
46
|
+
|
47
|
+
:capture => %w(protocol msgtype merchant amount transaction
|
48
|
+
fraud_remote_addr fraud_http_accept
|
49
|
+
fraud_http_accept_language fraud_http_accept_encoding
|
50
|
+
fraud_http_accept_charset fraud_http_referer
|
51
|
+
fraud_http_user_agent apikey),
|
52
|
+
|
53
|
+
:cancel => %w(protocol msgtype merchant transaction fraud_remote_addr
|
54
|
+
fraud_http_accept fraud_http_accept_language
|
55
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
56
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
57
|
+
|
58
|
+
:refund => %w(protocol msgtype merchant amount transaction
|
59
|
+
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
60
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
61
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
62
|
+
|
63
|
+
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
64
|
+
expirationdate cvd cardtypelock description testmode
|
65
|
+
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
66
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
67
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
68
|
+
|
69
|
+
:recurring => %w(protocol msgtype merchant ordernumber amount currency
|
70
|
+
autocapture transaction fraud_remote_addr fraud_http_accept
|
71
|
+
fraud_http_accept_language fraud_http_accept_encoding
|
72
|
+
fraud_http_accept_charset fraud_http_referer
|
73
|
+
fraud_http_user_agent apikey),
|
74
|
+
|
75
|
+
:status => %w(protocol msgtype merchant transaction fraud_remote_addr
|
76
|
+
fraud_http_accept fraud_http_accept_language
|
77
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
78
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
79
|
+
|
80
|
+
:chstatus => %w(protocol msgtype merchant fraud_remote_addr fraud_http_accept
|
81
|
+
fraud_http_accept_language fraud_http_accept_encoding
|
82
|
+
fraud_http_accept_charset fraud_http_referer
|
83
|
+
fraud_http_user_agent apikey)
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
APPROVED = '000'
|
88
|
+
|
89
|
+
# The login is the QuickpayId
|
90
|
+
# The password is the md5checkword from the Quickpay manager
|
91
|
+
# To use the API-key from the Quickpay manager, specify :api-key
|
92
|
+
# Using the API-key, requires that you use version 4. Specify :version => 4 in options.
|
93
|
+
def initialize(options = {})
|
94
|
+
requires!(options, :login, :password)
|
95
|
+
@protocol = options.delete(:version) || 3 # default to protocol version 3
|
96
|
+
@options = options
|
97
|
+
super
|
98
|
+
end
|
99
|
+
|
100
|
+
def authorize(money, credit_card_or_reference, options = {})
|
101
|
+
post = {}
|
102
|
+
|
103
|
+
add_amount(post, money, options)
|
104
|
+
add_invoice(post, options)
|
105
|
+
add_creditcard_or_reference(post, credit_card_or_reference, options)
|
106
|
+
add_autocapture(post, false)
|
107
|
+
add_fraud_parameters(post, options)
|
108
|
+
add_testmode(post)
|
109
|
+
|
110
|
+
commit(recurring_or_authorize(credit_card_or_reference), post)
|
111
|
+
end
|
112
|
+
|
113
|
+
def purchase(money, credit_card_or_reference, options = {})
|
114
|
+
post = {}
|
115
|
+
|
116
|
+
add_amount(post, money, options)
|
117
|
+
add_creditcard_or_reference(post, credit_card_or_reference, options)
|
118
|
+
add_invoice(post, options)
|
119
|
+
add_fraud_parameters(post, options)
|
120
|
+
add_autocapture(post, true)
|
121
|
+
|
122
|
+
commit(recurring_or_authorize(credit_card_or_reference), post)
|
123
|
+
end
|
124
|
+
|
125
|
+
def capture(money, authorization, options = {})
|
126
|
+
post = {}
|
127
|
+
|
128
|
+
add_reference(post, authorization)
|
129
|
+
add_amount_without_currency(post, money)
|
130
|
+
add_fraud_parameters(post, options)
|
131
|
+
|
132
|
+
commit(:capture, post)
|
133
|
+
end
|
134
|
+
|
135
|
+
def void(identification, options = {})
|
136
|
+
post = {}
|
137
|
+
|
138
|
+
add_reference(post, identification)
|
139
|
+
add_fraud_parameters(post, options)
|
140
|
+
|
141
|
+
commit(:cancel, post)
|
142
|
+
end
|
143
|
+
|
144
|
+
def refund(money, identification, options = {})
|
145
|
+
post = {}
|
146
|
+
|
147
|
+
add_amount_without_currency(post, money)
|
148
|
+
add_reference(post, identification)
|
149
|
+
add_fraud_parameters(post, options)
|
150
|
+
|
151
|
+
commit(:refund, post)
|
152
|
+
end
|
153
|
+
|
154
|
+
def credit(money, identification, options = {})
|
155
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
156
|
+
refund(money, identification, options)
|
157
|
+
end
|
158
|
+
|
159
|
+
def store(creditcard, options = {})
|
160
|
+
post = {}
|
161
|
+
|
162
|
+
add_creditcard(post, creditcard, options)
|
163
|
+
add_invoice(post, options)
|
164
|
+
add_description(post, options)
|
165
|
+
add_fraud_parameters(post, options)
|
166
|
+
add_testmode(post)
|
167
|
+
|
168
|
+
commit(:subscribe, post)
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def add_amount(post, money, options = {})
|
174
|
+
post[:amount] = amount(money)
|
175
|
+
post[:currency] = options[:currency] || currency(money)
|
176
|
+
end
|
177
|
+
|
178
|
+
def add_amount_without_currency(post, money, options = {})
|
179
|
+
post[:amount] = amount(money)
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_invoice(post, options)
|
183
|
+
post[:ordernumber] = format_order_number(options[:order_id])
|
184
|
+
end
|
185
|
+
|
186
|
+
def add_creditcard(post, credit_card, options)
|
187
|
+
post[:cardnumber] = credit_card.number
|
188
|
+
post[:cvd] = credit_card.verification_value
|
189
|
+
post[:expirationdate] = expdate(credit_card)
|
190
|
+
post[:cardtypelock] = options[:cardtypelock] unless options[:cardtypelock].blank?
|
191
|
+
end
|
192
|
+
|
193
|
+
def add_reference(post, identification)
|
194
|
+
post[:transaction] = identification
|
195
|
+
end
|
196
|
+
|
197
|
+
def add_creditcard_or_reference(post, credit_card_or_reference, options)
|
198
|
+
if credit_card_or_reference.is_a?(String)
|
199
|
+
add_reference(post, credit_card_or_reference)
|
200
|
+
else
|
201
|
+
add_creditcard(post, credit_card_or_reference, options)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def add_autocapture(post, autocapture)
|
206
|
+
post[:autocapture] = autocapture ? 1 : 0
|
207
|
+
end
|
208
|
+
|
209
|
+
def recurring_or_authorize(credit_card_or_reference)
|
210
|
+
credit_card_or_reference.is_a?(String) ? :recurring : :authorize
|
211
|
+
end
|
212
|
+
|
213
|
+
def add_description(post, options)
|
214
|
+
post[:description] = options[:description]
|
215
|
+
end
|
216
|
+
|
217
|
+
def add_testmode(post)
|
218
|
+
post[:testmode] = test? ? '1' : '0'
|
219
|
+
end
|
220
|
+
|
221
|
+
def add_fraud_parameters(post, options)
|
222
|
+
if @protocol == 4
|
223
|
+
post[:fraud_remote_addr] = options[:fraud_remote_addr] if options[:fraud_remote_addr]
|
224
|
+
post[:fraud_http_accept] = options[:fraud_http_accept] if options[:fraud_http_accept]
|
225
|
+
post[:fraud_http_accept_language] = options[:fraud_http_accept_language] if options[:fraud_http_accept_language]
|
226
|
+
post[:fraud_http_accept_encoding] = options[:fraud_http_accept_encoding] if options[:fraud_http_accept_encoding]
|
227
|
+
post[:fraud_http_accept_charset] = options[:fraud_http_accept_charset] if options[:fraud_http_accept_charset]
|
228
|
+
post[:fraud_http_referer] = options[:fraud_http_referer] if options[:fraud_http_referer]
|
229
|
+
post[:fraud_http_user_agent] = options[:fraud_http_user_agent] if options[:fraud_http_user_agent]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def commit(action, params)
|
234
|
+
response = parse(ssl_post(URL, post_data(action, params)))
|
235
|
+
|
236
|
+
Response.new(successful?(response), message_from(response), response,
|
237
|
+
:test => test?,
|
238
|
+
:authorization => response[:transaction]
|
239
|
+
)
|
240
|
+
end
|
241
|
+
|
242
|
+
def successful?(response)
|
243
|
+
response[:qpstat] == APPROVED
|
244
|
+
end
|
245
|
+
|
246
|
+
def parse(data)
|
247
|
+
response = {}
|
248
|
+
|
249
|
+
doc = REXML::Document.new(data)
|
250
|
+
|
251
|
+
doc.root.elements.each do |element|
|
252
|
+
response[element.name.to_sym] = element.text
|
253
|
+
end
|
254
|
+
|
255
|
+
response
|
256
|
+
end
|
257
|
+
|
258
|
+
def message_from(response)
|
259
|
+
response[:qpstatmsg].to_s
|
260
|
+
end
|
261
|
+
|
262
|
+
def post_data(action, params = {})
|
263
|
+
params[:protocol] = @protocol
|
264
|
+
params[:msgtype] = action.to_s
|
265
|
+
params[:merchant] = @options[:login]
|
266
|
+
params[:apikey] = @options[:apikey] if @options[:apikey]
|
267
|
+
params[:md5check] = generate_check_hash(action, params)
|
268
|
+
|
269
|
+
params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
270
|
+
end
|
271
|
+
|
272
|
+
def generate_check_hash(action, params)
|
273
|
+
string = MD5_CHECK_FIELDS[@protocol][action].collect do |key|
|
274
|
+
params[key.to_sym]
|
275
|
+
end.join('')
|
276
|
+
|
277
|
+
# Add the md5checkword
|
278
|
+
string << @options[:password].to_s
|
279
|
+
|
280
|
+
Digest::MD5.hexdigest(string)
|
281
|
+
end
|
282
|
+
|
283
|
+
def expdate(credit_card)
|
284
|
+
year = format(credit_card.year, :two_digits)
|
285
|
+
month = format(credit_card.month, :two_digits)
|
286
|
+
|
287
|
+
"#{year}#{month}"
|
288
|
+
end
|
289
|
+
|
290
|
+
# Limited to 20 digits max
|
291
|
+
def format_order_number(number)
|
292
|
+
number.to_s.gsub(/[^\w_]/, '').rjust(4, "0")[0...20]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|