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,246 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/ideal_response'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# Implementation contains some simplifications
|
6
|
+
# - does not support multiple subID per merchant
|
7
|
+
# - language is fixed to 'nl'
|
8
|
+
class IdealBaseGateway < Gateway
|
9
|
+
class_attribute :server_pem, :pem_password, :default_expiration_period
|
10
|
+
self.default_expiration_period = 'PT10M'
|
11
|
+
self.default_currency = 'EUR'
|
12
|
+
self.pem_password = true
|
13
|
+
|
14
|
+
self.abstract_class = true
|
15
|
+
|
16
|
+
# These constants will never change for most users
|
17
|
+
AUTHENTICATION_TYPE = 'SHA1_RSA'
|
18
|
+
LANGUAGE = 'nl'
|
19
|
+
SUB_ID = '0'
|
20
|
+
API_VERSION = '1.1.0'
|
21
|
+
|
22
|
+
def initialize(options = {})
|
23
|
+
requires!(options, :login, :password, :pem)
|
24
|
+
|
25
|
+
options[:pem_password] = options[:password]
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
# Setup transaction. Get redirect_url from response.service_url
|
30
|
+
def setup_purchase(money, options = {})
|
31
|
+
requires!(options, :issuer_id, :return_url, :order_id, :currency, :description, :entrance_code)
|
32
|
+
|
33
|
+
commit(build_transaction_request(money, options))
|
34
|
+
end
|
35
|
+
|
36
|
+
# Check status of transaction and confirm payment
|
37
|
+
# transaction_id must be a valid transaction_id from a prior setup.
|
38
|
+
def capture(transaction, options = {})
|
39
|
+
options[:transaction_id] = transaction
|
40
|
+
commit(build_status_request(options))
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get list of issuers from response.issuer_list
|
44
|
+
def issuers
|
45
|
+
commit(build_directory_request)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def url
|
51
|
+
(test? ? test_url : live_url)
|
52
|
+
end
|
53
|
+
|
54
|
+
def token
|
55
|
+
@token ||= create_fingerprint(@options[:pem])
|
56
|
+
end
|
57
|
+
|
58
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
59
|
+
# <AcquirerTrxReq xmlns="http://www.idealdesk.com/Message" version="1.1.0">
|
60
|
+
# <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
|
61
|
+
# <Issuer>
|
62
|
+
# <issuerID>1003</issuerID>
|
63
|
+
# </Issuer>
|
64
|
+
# <Merchant>
|
65
|
+
# <merchantID>000123456</merchantID>
|
66
|
+
# <subID>0</subID>
|
67
|
+
# <authentication>passkey</authentication>
|
68
|
+
# <token>1</token>
|
69
|
+
# <tokenCode>3823ad872eff23</tokenCode>
|
70
|
+
# <merchantReturnURL>https://www.mijnwinkel.nl/betaalafhandeling
|
71
|
+
# </merchantReturnURL>
|
72
|
+
# </Merchant>
|
73
|
+
# <Transaction>
|
74
|
+
# <purchaseID>iDEAL-aankoop 21</purchaseID>
|
75
|
+
# <amount>5999</amount>
|
76
|
+
# <currency>EUR</currency>
|
77
|
+
# <expirationPeriod>PT3M30S</expirationPeriod>
|
78
|
+
# <language>nl</language>
|
79
|
+
# <description>Documentensuite</description>
|
80
|
+
# <entranceCode>D67tyx6rw9IhY71</entranceCode>
|
81
|
+
# </Transaction>
|
82
|
+
# </AcquirerTrxReq>
|
83
|
+
def build_transaction_request(money, options)
|
84
|
+
date_time_stamp = create_time_stamp
|
85
|
+
message = date_time_stamp +
|
86
|
+
options[:issuer_id] +
|
87
|
+
@options[:login] +
|
88
|
+
SUB_ID +
|
89
|
+
options[:return_url] +
|
90
|
+
options[:order_id] +
|
91
|
+
money.to_s +
|
92
|
+
(options[:currency] || currency(money)) +
|
93
|
+
LANGUAGE +
|
94
|
+
options[:description] +
|
95
|
+
options[:entrance_code]
|
96
|
+
token_code = sign_message(@options[:pem], @options[:password], message)
|
97
|
+
|
98
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
99
|
+
xml.instruct!
|
100
|
+
xml.tag! 'AcquirerTrxReq', 'xmlns' => 'http://www.idealdesk.com/Message', 'version' => API_VERSION do
|
101
|
+
xml.tag! 'createDateTimeStamp', date_time_stamp
|
102
|
+
xml.tag! 'Issuer' do
|
103
|
+
xml.tag! 'issuerID', options[:issuer_id]
|
104
|
+
end
|
105
|
+
xml.tag! 'Merchant' do
|
106
|
+
xml.tag! 'merchantID', @options[:login]
|
107
|
+
xml.tag! 'subID', SUB_ID
|
108
|
+
xml.tag! 'authentication', AUTHENTICATION_TYPE
|
109
|
+
xml.tag! 'token', token
|
110
|
+
xml.tag! 'tokenCode', token_code
|
111
|
+
xml.tag! 'merchantReturnURL', options[:return_url]
|
112
|
+
end
|
113
|
+
xml.tag! 'Transaction' do
|
114
|
+
xml.tag! 'purchaseID', options[:order_id]
|
115
|
+
xml.tag! 'amount', money
|
116
|
+
xml.tag! 'currency', options[:currency]
|
117
|
+
xml.tag! 'expirationPeriod', options[:expiration_period] || default_expiration_period
|
118
|
+
xml.tag! 'language', LANGUAGE
|
119
|
+
xml.tag! 'description', options[:description]
|
120
|
+
xml.tag! 'entranceCode', options[:entrance_code]
|
121
|
+
end
|
122
|
+
xml.target!
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
127
|
+
# <AcquirerStatusReq xmlns="http://www.idealdesk.com/Message" version="1.1.0">
|
128
|
+
# <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
|
129
|
+
# <Merchant>
|
130
|
+
# <merchantID>000123456</merchantID>
|
131
|
+
# <subID>0</subID>
|
132
|
+
# <authentication>keyed hash</authentication>
|
133
|
+
# <token>1</token>
|
134
|
+
# <tokenCode>3823ad872eff23</tokenCode>
|
135
|
+
# </Merchant>
|
136
|
+
# <Transaction>
|
137
|
+
# <transactionID>0001023456789112</transactionID>
|
138
|
+
# </Transaction>
|
139
|
+
# </AcquirerStatusReq>
|
140
|
+
def build_status_request(options)
|
141
|
+
datetimestamp = create_time_stamp
|
142
|
+
message = datetimestamp + @options[:login] + SUB_ID + options[:transaction_id]
|
143
|
+
tokenCode = sign_message(@options[:pem], @options[:password], message)
|
144
|
+
|
145
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
146
|
+
xml.instruct!
|
147
|
+
xml.tag! 'AcquirerStatusReq', 'xmlns' => 'http://www.idealdesk.com/Message', 'version' => API_VERSION do
|
148
|
+
xml.tag! 'createDateTimeStamp', datetimestamp
|
149
|
+
xml.tag! 'Merchant' do
|
150
|
+
xml.tag! 'merchantID', @options[:login]
|
151
|
+
xml.tag! 'subID', SUB_ID
|
152
|
+
xml.tag! 'authentication' , AUTHENTICATION_TYPE
|
153
|
+
xml.tag! 'token', token
|
154
|
+
xml.tag! 'tokenCode', tokenCode
|
155
|
+
end
|
156
|
+
xml.tag! 'Transaction' do
|
157
|
+
xml.tag! 'transactionID', options[:transaction_id]
|
158
|
+
end
|
159
|
+
end
|
160
|
+
xml.target!
|
161
|
+
end
|
162
|
+
|
163
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
164
|
+
# <DirectoryReq xmlns="http://www.idealdesk.com/Message" version="1.1.0">
|
165
|
+
# <createDateTimeStamp>2001-12-17T09:30:47.0Z</createDateTimeStamp>
|
166
|
+
# <Merchant>
|
167
|
+
# <merchantID>000000001</merchantID>
|
168
|
+
# <subID>0</subID>
|
169
|
+
# <authentication>1</authentication>
|
170
|
+
# <token>hashkey</token>
|
171
|
+
# <tokenCode>WajqV1a3nDen0be2r196g9FGFF=</tokenCode>
|
172
|
+
# </Merchant>
|
173
|
+
# </DirectoryReq>
|
174
|
+
def build_directory_request
|
175
|
+
datetimestamp = create_time_stamp
|
176
|
+
message = datetimestamp + @options[:login] + SUB_ID
|
177
|
+
tokenCode = sign_message(@options[:pem], @options[:password], message)
|
178
|
+
|
179
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
180
|
+
xml.instruct!
|
181
|
+
xml.tag! 'DirectoryReq', 'xmlns' => 'http://www.idealdesk.com/Message', 'version' => API_VERSION do
|
182
|
+
xml.tag! 'createDateTimeStamp', datetimestamp
|
183
|
+
xml.tag! 'Merchant' do
|
184
|
+
xml.tag! 'merchantID', @options[:login]
|
185
|
+
xml.tag! 'subID', SUB_ID
|
186
|
+
xml.tag! 'authentication', AUTHENTICATION_TYPE
|
187
|
+
xml.tag! 'token', token
|
188
|
+
xml.tag! 'tokenCode', tokenCode
|
189
|
+
end
|
190
|
+
end
|
191
|
+
xml.target!
|
192
|
+
end
|
193
|
+
|
194
|
+
def commit(request)
|
195
|
+
raw_response = ssl_post(url, request)
|
196
|
+
response = Hash.from_xml(raw_response.to_s)
|
197
|
+
response_type = response.keys[0]
|
198
|
+
|
199
|
+
case response_type
|
200
|
+
when 'AcquirerTrxRes', 'DirectoryRes'
|
201
|
+
success = true
|
202
|
+
when 'ErrorRes'
|
203
|
+
success = false
|
204
|
+
when 'AcquirerStatusRes'
|
205
|
+
raise SecurityError, "Message verification failed.", caller unless status_response_verified?(response)
|
206
|
+
success = (response['AcquirerStatusRes']['Transaction']['status'] == 'Success')
|
207
|
+
else
|
208
|
+
raise ArgumentError, "Unknown response type.", caller
|
209
|
+
end
|
210
|
+
|
211
|
+
return IdealResponse.new(success, response.keys[0], response, :test => test?)
|
212
|
+
end
|
213
|
+
|
214
|
+
def create_fingerprint(cert_file)
|
215
|
+
cert_data = OpenSSL::X509::Certificate.new(cert_file).to_s
|
216
|
+
cert_data = cert_data.sub(/-----BEGIN CERTIFICATE-----/, '')
|
217
|
+
cert_data = cert_data.sub(/-----END CERTIFICATE-----/, '')
|
218
|
+
fingerprint = Base64.decode64(cert_data)
|
219
|
+
fingerprint = Digest::SHA1.hexdigest(fingerprint)
|
220
|
+
return fingerprint.upcase
|
221
|
+
end
|
222
|
+
|
223
|
+
def sign_message(private_key_data, password, data)
|
224
|
+
private_key = OpenSSL::PKey::RSA.new(private_key_data, password)
|
225
|
+
signature = private_key.sign(OpenSSL::Digest::SHA1.new, data.gsub('\s', ''))
|
226
|
+
return Base64.encode64(signature).gsub(/\n/, '')
|
227
|
+
end
|
228
|
+
|
229
|
+
def verify_message(cert_file, data, signature)
|
230
|
+
public_key = OpenSSL::X509::Certificate.new(cert_file).public_key
|
231
|
+
return public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), data)
|
232
|
+
end
|
233
|
+
|
234
|
+
def status_response_verified?(response)
|
235
|
+
transaction = response['AcquirerStatusRes']['Transaction']
|
236
|
+
message = response['AcquirerStatusRes']['createDateTimeStamp'] + transaction['transactionID' ] + transaction['status']
|
237
|
+
message << transaction['consumerAccountNumber'].to_s
|
238
|
+
verify_message(server_pem, message, response['AcquirerStatusRes']['Signature']['signatureValue'])
|
239
|
+
end
|
240
|
+
|
241
|
+
def create_time_stamp
|
242
|
+
Time.now.gmtime.strftime('%Y-%m-%dT%H:%M:%S.000Z')
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIICQDCCAakCBELvbPYwDQYJKoZIhvcNAQEEBQAwZzELMAkGA1UEBhMCREUxDzANBgNVBAgTBkhl
|
3
|
+
c3NlbjESMBAGA1UEBxMJRnJhbmtmdXJ0MQ4wDAYDVQQKEwVpREVBTDEOMAwGA1UECxMFaURFQUwx
|
4
|
+
EzARBgNVBAMTCmlERUFMIFJhYm8wHhcNMDUwODAyMTI1NDE0WhcNMTUwNzMxMTI1NDE0WjBnMQsw
|
5
|
+
CQYDVQQGEwJERTEPMA0GA1UECBMGSGVzc2VuMRIwEAYDVQQHEwlGcmFua2Z1cnQxDjAMBgNVBAoT
|
6
|
+
BWlERUFMMQ4wDAYDVQQLEwVpREVBTDETMBEGA1UEAxMKaURFQUwgUmFibzCBnzANBgkqhkiG9w0B
|
7
|
+
AQEFAAOBjQAwgYkCgYEA486iIKVhr8RNjxH+PZ3yTWx/8k2fqDFm8XU8I1Z5esRmPFnXmlgA8cG7
|
8
|
+
e9AaBPaLoP7Dc8dRQoUO66KMakzGI/WAVdHIJiiKrz8xOcioIgrzPSqec7aqse3J28UraEHkGESJ
|
9
|
+
7dAW7Pw/shrmpmkzKsunLt6AkXss4W3JUndZUN0CAwEAATANBgkqhkiG9w0BAQQFAAOBgQCGy/FK
|
10
|
+
Lotp2ZOTtuLMgvDy74eicq/Znv4bLfpglzAPHycRHcHsXuer/lNHyvpKf2gdYe+IFalUW3OJZWIM
|
11
|
+
jpm4UniJ16RPdgwWVRJEdPr/P7JXMIqD2IEOgujuuTQ7x0VgCf9XrsPsP9ZR5DIPcDDhbrpSE0yF
|
12
|
+
Do77nwG61xMaGA==
|
13
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class IdealResponse < Response
|
4
|
+
|
5
|
+
def issuer_list
|
6
|
+
list = @params.values[0]['Directory']['Issuer']
|
7
|
+
case list
|
8
|
+
when Hash
|
9
|
+
return [list]
|
10
|
+
when Array
|
11
|
+
return list
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def service_url
|
16
|
+
@params.values[0]['Issuer']['issuerAuthenticationURL']
|
17
|
+
end
|
18
|
+
|
19
|
+
def transaction
|
20
|
+
@params.values[0]['Transaction']
|
21
|
+
end
|
22
|
+
|
23
|
+
def error
|
24
|
+
@params.values[0]['Error']
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/ideal/ideal_base'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# First, make sure you have everything setup correctly and all of your dependencies in place with:
|
6
|
+
#
|
7
|
+
# require 'rubygems'
|
8
|
+
# require 'active_merchant'
|
9
|
+
#
|
10
|
+
# ActiveMerchant expects the amounts to be given as an Integer in cents. In this case, 10 EUR becomes 1000.
|
11
|
+
#
|
12
|
+
# Create certificates for authentication:
|
13
|
+
#
|
14
|
+
# The PEM file expected should contain both the certificate and the generated PEM file.
|
15
|
+
# Some sample shell commands to generate the certificates:
|
16
|
+
#
|
17
|
+
# openssl genrsa -aes128 -out priv.pem -passout pass:[YOUR PASSWORD] 1024
|
18
|
+
# openssl req -x509 -new -key priv.pem -passin pass:[YOUR PASSWORD] -days 3000 -out cert.cer
|
19
|
+
# cat cert.cer priv.pem > ideal.pem
|
20
|
+
#
|
21
|
+
# Following the steps above, upload cert.cer to the ideal web interface and pass the path of ideal.pem to the :pem option.
|
22
|
+
#
|
23
|
+
# Configure the gateway using your iDEAL bank account info and security settings:
|
24
|
+
#
|
25
|
+
# Create gateway:
|
26
|
+
# gateway = ActiveMerchant::Billing::IdealRabobankGateway.new(
|
27
|
+
# :login => '123456789', # 9 digit merchant number
|
28
|
+
# :pem => File.read(Rails.root + 'config/ideal.pem'),
|
29
|
+
# :password => 'password' # password for the PEM key
|
30
|
+
# )
|
31
|
+
#
|
32
|
+
# Get list of issuers to fill selection list on your payment form:
|
33
|
+
# response = gateway.issuers
|
34
|
+
# list = response.issuer_list
|
35
|
+
#
|
36
|
+
# Request transaction:
|
37
|
+
#
|
38
|
+
# options = {
|
39
|
+
# :issuer_id => '0001',
|
40
|
+
# :expiration_period => 'PT10M',
|
41
|
+
# :return_url => 'http://www.return.url',
|
42
|
+
# :order_id => '1234567890123456',
|
43
|
+
# :currency => 'EUR',
|
44
|
+
# :description => 'Een omschrijving',
|
45
|
+
# :entrance_code => '1234'
|
46
|
+
# }
|
47
|
+
#
|
48
|
+
# response = gateway.setup_purchase(amount, options)
|
49
|
+
# transaction_id = response.transaction['transactionID']
|
50
|
+
# redirect_url = response.service_url
|
51
|
+
#
|
52
|
+
# Mandatory status request will confirm transaction:
|
53
|
+
# response = gateway.capture(transaction_id)
|
54
|
+
#
|
55
|
+
# Implementation contains some simplifications
|
56
|
+
# - does not support multiple subID per merchant
|
57
|
+
# - language is fixed to 'nl'
|
58
|
+
class IdealRabobankGateway < IdealBaseGateway
|
59
|
+
class_attribute :test_url, :live_url
|
60
|
+
|
61
|
+
self.test_url = 'https://idealtest.rabobank.nl/ideal/iDeal'
|
62
|
+
self.live_url = 'https://ideal.rabobank.nl/ideal/iDeal'
|
63
|
+
self.server_pem = File.read(File.dirname(__FILE__) + '/ideal/ideal_rabobank.pem')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'check.rb')
|
2
|
+
module ActiveMerchant #:nodoc:
|
3
|
+
module Billing #:nodoc:
|
4
|
+
class InspireGateway < Gateway
|
5
|
+
self.live_url = self.test_url = 'https://secure.inspiregateway.net/api/transact.php'
|
6
|
+
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express]
|
9
|
+
self.homepage_url = 'http://www.inspiregateway.com'
|
10
|
+
self.display_name = 'Inspire Commerce'
|
11
|
+
|
12
|
+
# Creates a new InspireGateway
|
13
|
+
#
|
14
|
+
# The gateway requires that a valid login and password be passed
|
15
|
+
# in the +options+ hash.
|
16
|
+
#
|
17
|
+
# ==== Options
|
18
|
+
#
|
19
|
+
# * <tt>:login</tt> -- The Inspire Username.
|
20
|
+
# * <tt>:password</tt> -- The Inspire Passowrd.
|
21
|
+
# See the Inspire Integration Guide for details. (default: +false+)
|
22
|
+
def initialize(options = {})
|
23
|
+
requires!(options, :login, :password)
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
# Pass :store => true in the options to store the
|
28
|
+
# payment info at Inspire Gateway and get a generated
|
29
|
+
# customer_vault_id in the response.
|
30
|
+
# Pass :store => some_number_or_string to specify the
|
31
|
+
# customer_vault_id InspireGateway should use (make sure it's
|
32
|
+
# unique).
|
33
|
+
def authorize(money, creditcard, options = {})
|
34
|
+
post = {}
|
35
|
+
add_invoice(post, options)
|
36
|
+
add_payment_source(post, creditcard,options)
|
37
|
+
add_address(post, creditcard, options)
|
38
|
+
add_customer_data(post, options)
|
39
|
+
|
40
|
+
commit('auth', money, post)
|
41
|
+
end
|
42
|
+
|
43
|
+
def purchase(money, payment_source, options = {})
|
44
|
+
post = {}
|
45
|
+
add_invoice(post, options)
|
46
|
+
add_payment_source(post, payment_source, options)
|
47
|
+
add_address(post, payment_source, options)
|
48
|
+
add_customer_data(post, options)
|
49
|
+
|
50
|
+
commit('sale', money, post)
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture(money, authorization, options = {})
|
54
|
+
post ={}
|
55
|
+
post[:transactionid] = authorization
|
56
|
+
commit('capture', money, post)
|
57
|
+
end
|
58
|
+
|
59
|
+
def void(authorization, options = {})
|
60
|
+
post ={}
|
61
|
+
post[:transactionid] = authorization
|
62
|
+
commit('void', nil, post)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Update the values (such as CC expiration) stored at
|
66
|
+
# InspireGateway. The CC number must be supplied in the
|
67
|
+
# CreditCard object.
|
68
|
+
def update(vault_id, creditcard, options = {})
|
69
|
+
post = {}
|
70
|
+
post[:customer_vault] = "update_customer"
|
71
|
+
add_customer_vault_id(post, vault_id)
|
72
|
+
add_creditcard(post, creditcard, options)
|
73
|
+
add_address(post, creditcard, options)
|
74
|
+
add_customer_data(post, options)
|
75
|
+
|
76
|
+
commit(nil, nil, post)
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete(vault_id)
|
80
|
+
post = {}
|
81
|
+
post[:customer_vault] = "delete_customer"
|
82
|
+
add_customer_vault_id(post, vault_id)
|
83
|
+
commit(nil, nil, post)
|
84
|
+
end
|
85
|
+
|
86
|
+
# To match the other stored-value gateways, like TrustCommerce,
|
87
|
+
# store and unstore need to be defined
|
88
|
+
def store(creditcard, options = {})
|
89
|
+
billing_id = options.delete(:billing_id).to_s || true
|
90
|
+
authorize(100, creditcard, options.merge(:store => billing_id))
|
91
|
+
end
|
92
|
+
|
93
|
+
alias_method :unstore, :delete
|
94
|
+
|
95
|
+
private
|
96
|
+
def add_customer_data(post, options)
|
97
|
+
if options.has_key? :email
|
98
|
+
post[:email] = options[:email]
|
99
|
+
end
|
100
|
+
|
101
|
+
if options.has_key? :ip
|
102
|
+
post[:ipaddress] = options[:ip]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_address(post, creditcard, options)
|
107
|
+
if address = options[:billing_address] || options[:address]
|
108
|
+
post[:address1] = address[:address1].to_s
|
109
|
+
post[:address2] = address[:address2].to_s unless address[:address2].blank?
|
110
|
+
post[:company] = address[:company].to_s
|
111
|
+
post[:phone] = address[:phone].to_s
|
112
|
+
post[:zip] = address[:zip].to_s
|
113
|
+
post[:city] = address[:city].to_s
|
114
|
+
post[:country] = address[:country].to_s
|
115
|
+
post[:state] = address[:state].blank? ? 'n/a' : address[:state]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def add_invoice(post, options)
|
120
|
+
post[:orderid] = options[:order_id].to_s.gsub(/[^\w.]/, '')
|
121
|
+
post[:orderdescription] = options[:description]
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_payment_source(params, source, options={})
|
125
|
+
case determine_funding_source(source)
|
126
|
+
when :vault then add_customer_vault_id(params, source)
|
127
|
+
when :credit_card then add_creditcard(params, source, options)
|
128
|
+
when :check then add_check(params, source)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_customer_vault_id(params,vault_id)
|
133
|
+
params[:customer_vault_id] = vault_id
|
134
|
+
end
|
135
|
+
|
136
|
+
def add_creditcard(post, creditcard,options)
|
137
|
+
if options[:store]
|
138
|
+
post[:customer_vault] = "add_customer"
|
139
|
+
post[:customer_vault_id] = options[:store] unless options[:store] == true
|
140
|
+
end
|
141
|
+
post[:ccnumber] = creditcard.number
|
142
|
+
post[:cvv] = creditcard.verification_value if creditcard.verification_value?
|
143
|
+
post[:ccexp] = expdate(creditcard)
|
144
|
+
post[:firstname] = creditcard.first_name
|
145
|
+
post[:lastname] = creditcard.last_name
|
146
|
+
end
|
147
|
+
|
148
|
+
def add_check(post, check)
|
149
|
+
post[:payment] = 'check' # Set transaction to ACH
|
150
|
+
post[:checkname] = check.name # The name on the customer's Checking Account
|
151
|
+
post[:checkaba] = check.routing_number # The customer's bank routing number
|
152
|
+
post[:checkaccount] = check.account_number # The customer's account number
|
153
|
+
post[:account_holder_type] = check.account_holder_type # The customer's type of ACH account
|
154
|
+
post[:account_type] = check.account_type # The customer's type of ACH account
|
155
|
+
end
|
156
|
+
|
157
|
+
def parse(body)
|
158
|
+
results = {}
|
159
|
+
body.split(/&/).each do |pair|
|
160
|
+
key,val = pair.split(/=/)
|
161
|
+
results[key] = val
|
162
|
+
end
|
163
|
+
|
164
|
+
results
|
165
|
+
end
|
166
|
+
|
167
|
+
def commit(action, money, parameters)
|
168
|
+
parameters[:amount] = amount(money) if money
|
169
|
+
|
170
|
+
response = parse( ssl_post(self.live_url, post_data(action,parameters)) )
|
171
|
+
|
172
|
+
Response.new(response["response"] == "1", message_from(response), response,
|
173
|
+
:authorization => response["transactionid"],
|
174
|
+
:test => test?,
|
175
|
+
:cvv_result => response["cvvresponse"],
|
176
|
+
:avs_result => { :code => response["avsresponse"] }
|
177
|
+
)
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
def message_from(response)
|
182
|
+
case response["responsetext"]
|
183
|
+
when "SUCCESS","Approved"
|
184
|
+
"This transaction has been approved"
|
185
|
+
when "DECLINE"
|
186
|
+
"This transaction has been declined"
|
187
|
+
else
|
188
|
+
response["responsetext"]
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def post_data(action, parameters = {})
|
193
|
+
post = {}
|
194
|
+
post[:username] = @options[:login]
|
195
|
+
post[:password] = @options[:password]
|
196
|
+
post[:type] = action if action
|
197
|
+
|
198
|
+
request = post.merge(parameters).map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
|
199
|
+
request
|
200
|
+
end
|
201
|
+
|
202
|
+
def determine_funding_source(source)
|
203
|
+
case
|
204
|
+
when source.is_a?(String) then :vault
|
205
|
+
when CreditCard.card_companies.keys.include?(card_brand(source)) then :credit_card
|
206
|
+
when card_brand(source) == 'check' then :check
|
207
|
+
else raise ArgumentError, "Unsupported funding source provided"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|