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.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1596 -0
  3. data/CONTRIBUTORS +511 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +18 -0
  6. data/lib/active_merchant.rb +108 -0
  7. data/lib/active_merchant/billing.rb +13 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/avs_result.rb +98 -0
  10. data/lib/active_merchant/billing/base.rb +72 -0
  11. data/lib/active_merchant/billing/check.rb +76 -0
  12. data/lib/active_merchant/billing/compatibility.rb +120 -0
  13. data/lib/active_merchant/billing/credit_card.rb +352 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +268 -0
  18. data/lib/active_merchant/billing/gateways.rb +17 -0
  19. data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
  20. data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
  21. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  24. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  25. data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
  28. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
  35. data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
  36. data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
  37. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  38. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  42. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  43. data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
  44. data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
  45. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  46. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  47. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  48. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  49. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  50. data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
  51. data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
  52. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  53. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  54. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  55. data/lib/active_merchant/billing/gateways/epay.rb +275 -0
  56. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  57. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  58. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  59. data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
  60. data/lib/active_merchant/billing/gateways/exact.rb +218 -0
  61. data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
  62. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  63. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  64. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  65. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  66. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
  67. data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
  68. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  69. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  70. data/lib/active_merchant/billing/gateways/hps.rb +288 -0
  71. data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
  72. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  73. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  74. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  75. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  76. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  77. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  78. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  79. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  80. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  81. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  82. data/lib/active_merchant/billing/gateways/litle.rb +346 -0
  83. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  84. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  85. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  86. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  87. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  88. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  89. data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
  90. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  91. data/lib/active_merchant/billing/gateways/migs.rb +265 -0
  92. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  93. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  94. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  95. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  96. data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
  97. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  98. data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
  99. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  100. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  101. data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
  102. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  103. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  104. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  105. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  106. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  107. data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
  108. data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
  109. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  110. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  111. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  112. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
  113. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  114. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  115. data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
  116. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  117. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
  119. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
  120. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  121. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  122. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  123. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  124. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  125. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  126. data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
  127. data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
  128. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
  129. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  130. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  131. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  132. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  133. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  134. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  135. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  136. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  137. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  138. data/lib/active_merchant/billing/gateways/pin.rb +197 -0
  139. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  140. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  141. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  142. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  143. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  144. data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
  145. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  146. data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
  147. data/lib/active_merchant/billing/gateways/sage.rb +175 -0
  148. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
  149. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
  150. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  151. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
  152. data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
  153. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  154. data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
  155. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  156. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  157. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  158. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  159. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  160. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  161. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  162. data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
  163. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  164. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  165. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  166. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  167. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  168. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  169. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  170. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  171. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
  172. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  173. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  174. data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
  175. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  176. data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
  177. data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
  178. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  179. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  180. data/lib/active_merchant/billing/model.rb +30 -0
  181. data/lib/active_merchant/billing/payment_token.rb +21 -0
  182. data/lib/active_merchant/billing/rails.rb +3 -0
  183. data/lib/active_merchant/billing/response.rb +91 -0
  184. data/lib/active_merchant/country.rb +332 -0
  185. data/lib/active_merchant/empty.rb +20 -0
  186. data/lib/active_merchant/errors.rb +29 -0
  187. data/lib/active_merchant/offsite_payments_shim.rb +19 -0
  188. data/lib/active_merchant/version.rb +3 -0
  189. data/lib/activemerchant.rb +1 -0
  190. data/lib/support/gateway_support.rb +71 -0
  191. data/lib/support/outbound_hosts.rb +25 -0
  192. data/lib/support/ssl_verify.rb +93 -0
  193. 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
+