start_activemerchant 1.50.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 (218) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1769 -0
  3. data/CONTRIBUTORS +540 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +226 -0
  6. data/lib/active_merchant.rb +67 -0
  7. data/lib/active_merchant/billing.rb +15 -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 +404 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +195 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +291 -0
  18. data/lib/active_merchant/billing/gateways.rb +14 -0
  19. data/lib/active_merchant/billing/gateways/allied_wallet.rb +203 -0
  20. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  21. data/lib/active_merchant/billing/gateways/authorize_net.rb +510 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  24. data/lib/active_merchant/billing/gateways/axcessms.rb +181 -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 +192 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +389 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +58 -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 +211 -0
  37. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  39. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  40. data/lib/active_merchant/billing/gateways/braintree_blue.rb +574 -0
  41. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  42. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  43. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  44. data/lib/active_merchant/billing/gateways/card_stream.rb +238 -0
  45. data/lib/active_merchant/billing/gateways/cashnet.rb +202 -0
  46. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  47. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  48. data/lib/active_merchant/billing/gateways/cenpos.rb +262 -0
  49. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  50. data/lib/active_merchant/billing/gateways/checkout.rb +216 -0
  51. data/lib/active_merchant/billing/gateways/checkout_v2.rb +200 -0
  52. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  53. data/lib/active_merchant/billing/gateways/conekta.rb +210 -0
  54. data/lib/active_merchant/billing/gateways/cyber_source.rb +720 -0
  55. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  56. data/lib/active_merchant/billing/gateways/dibs.rb +206 -0
  57. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  58. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  59. data/lib/active_merchant/billing/gateways/epay.rb +274 -0
  60. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  61. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  62. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  63. data/lib/active_merchant/billing/gateways/eway_rapid.rb +522 -0
  64. data/lib/active_merchant/billing/gateways/exact.rb +227 -0
  65. data/lib/active_merchant/billing/gateways/ezic.rb +206 -0
  66. data/lib/active_merchant/billing/gateways/fat_zebra.rb +213 -0
  67. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  68. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  69. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  70. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  71. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +413 -0
  72. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  73. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  74. data/lib/active_merchant/billing/gateways/garanti.rb +261 -0
  75. data/lib/active_merchant/billing/gateways/global_transport.rb +179 -0
  76. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  77. data/lib/active_merchant/billing/gateways/hps.rb +287 -0
  78. data/lib/active_merchant/billing/gateways/iats_payments.rb +277 -0
  79. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  80. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  81. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  82. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  83. data/lib/active_merchant/billing/gateways/inspire.rb +219 -0
  84. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  85. data/lib/active_merchant/billing/gateways/ipp.rb +175 -0
  86. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  87. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  88. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  89. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  90. data/lib/active_merchant/billing/gateways/litle.rb +345 -0
  91. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  92. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  93. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  94. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  95. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  96. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  97. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  98. data/lib/active_merchant/billing/gateways/mercury.rb +326 -0
  99. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  100. data/lib/active_merchant/billing/gateways/migs.rb +280 -0
  101. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  102. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  103. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  104. data/lib/active_merchant/billing/gateways/monei.rb +307 -0
  105. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  106. data/lib/active_merchant/billing/gateways/moneris_us.rb +298 -0
  107. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  108. data/lib/active_merchant/billing/gateways/nab_transact.rb +290 -0
  109. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  110. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  111. data/lib/active_merchant/billing/gateways/netbilling.rb +224 -0
  112. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  113. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  114. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  115. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  116. data/lib/active_merchant/billing/gateways/omise.rb +319 -0
  117. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  118. data/lib/active_merchant/billing/gateways/optimal_payment.rb +314 -0
  119. data/lib/active_merchant/billing/gateways/orbital.rb +834 -0
  120. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  121. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  122. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  123. data/lib/active_merchant/billing/gateways/pay_conex.rb +246 -0
  124. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
  125. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  126. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  127. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  128. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  129. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  130. data/lib/active_merchant/billing/gateways/payflow.rb +308 -0
  131. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +220 -0
  132. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  133. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  134. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  135. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  136. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  137. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  138. data/lib/active_merchant/billing/gateways/paymill.rb +282 -0
  139. data/lib/active_merchant/billing/gateways/paypal.rb +129 -0
  140. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +679 -0
  141. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  142. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  143. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  144. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  145. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  146. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  147. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  148. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  149. data/lib/active_merchant/billing/gateways/payu_in.rb +247 -0
  150. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  151. data/lib/active_merchant/billing/gateways/pin.rb +207 -0
  152. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  153. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  154. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  155. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  156. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  157. data/lib/active_merchant/billing/gateways/quickbooks.rb +280 -0
  158. data/lib/active_merchant/billing/gateways/quickpay.rb +26 -0
  159. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +188 -0
  160. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +240 -0
  161. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +227 -0
  162. data/lib/active_merchant/billing/gateways/qvalent.rb +179 -0
  163. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  164. data/lib/active_merchant/billing/gateways/redsys.rb +406 -0
  165. data/lib/active_merchant/billing/gateways/s5.rb +226 -0
  166. data/lib/active_merchant/billing/gateways/sage.rb +173 -0
  167. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +89 -0
  168. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +115 -0
  169. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  170. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  171. data/lib/active_merchant/billing/gateways/sage_pay.rb +399 -0
  172. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  173. data/lib/active_merchant/billing/gateways/secure_net.rb +263 -0
  174. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  175. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  176. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  177. data/lib/active_merchant/billing/gateways/skip_jack.rb +451 -0
  178. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  179. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  180. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  181. data/lib/active_merchant/billing/gateways/stripe.rb +489 -0
  182. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  183. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  184. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  185. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  186. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  187. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  188. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  189. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  190. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +259 -0
  191. data/lib/active_merchant/billing/gateways/vanco.rb +280 -0
  192. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  193. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  194. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  195. data/lib/active_merchant/billing/gateways/wepay.rb +205 -0
  196. data/lib/active_merchant/billing/gateways/wirecard.rb +420 -0
  197. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  198. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +204 -0
  199. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  200. data/lib/active_merchant/billing/model.rb +30 -0
  201. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +24 -0
  202. data/lib/active_merchant/billing/payment_token.rb +21 -0
  203. data/lib/active_merchant/billing/rails.rb +3 -0
  204. data/lib/active_merchant/billing/response.rb +92 -0
  205. data/lib/active_merchant/connection.rb +172 -0
  206. data/lib/active_merchant/country.rb +332 -0
  207. data/lib/active_merchant/empty.rb +20 -0
  208. data/lib/active_merchant/errors.rb +35 -0
  209. data/lib/active_merchant/network_connection_retries.rb +79 -0
  210. data/lib/active_merchant/post_data.rb +24 -0
  211. data/lib/active_merchant/posts_data.rb +84 -0
  212. data/lib/active_merchant/version.rb +3 -0
  213. data/lib/activemerchant.rb +1 -0
  214. data/lib/certs/cacert.pem +3866 -0
  215. data/lib/support/gateway_support.rb +71 -0
  216. data/lib/support/outbound_hosts.rb +28 -0
  217. data/lib/support/ssl_verify.rb +93 -0
  218. metadata +387 -0
@@ -0,0 +1,277 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class IatsPaymentsGateway < Gateway
4
+ class_attribute :live_na_url, :live_uk_url
5
+
6
+ self.live_na_url = 'https://www.iatspayments.com/NetGate'
7
+ self.live_uk_url = 'https://www.uk.iatspayments.com/NetGate'
8
+
9
+ self.supported_countries = %w(AU BR CA CH DE DK ES FI FR GR HK IE IT NL NO PT SE SG TR GB US TH ID PH BE)
10
+ self.default_currency = 'USD'
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
12
+
13
+ self.homepage_url = 'http://home.iatspayments.com/'
14
+ self.display_name = 'iATS Payments'
15
+
16
+ ACTIONS = {
17
+ purchase: "ProcessCreditCardV1",
18
+ purchase_check: "ProcessACHEFTV1",
19
+ refund: "ProcessCreditCardRefundWithTransactionIdV1",
20
+ refund_check: "ProcessACHEFTRefundWithTransactionIdV1",
21
+ store: "CreateCreditCardCustomerCodeV1",
22
+ unstore: "DeleteCustomerCodeV1"
23
+ }
24
+
25
+ def initialize(options={})
26
+ if(options[:login])
27
+ ActiveMerchant.deprecated("The 'login' option is deprecated in favor of 'agent_code' and will be removed in a future version.")
28
+ options[:agent_code] = options[:login]
29
+ end
30
+
31
+ options[:region] = 'na' unless options[:region]
32
+
33
+ requires!(options, :agent_code, :password, :region)
34
+ super
35
+ end
36
+
37
+ def purchase(money, payment, options={})
38
+ post = {}
39
+ add_invoice(post, money, options)
40
+ add_payment(post, payment)
41
+ add_address(post, options)
42
+ add_ip(post, options)
43
+ add_description(post, options)
44
+
45
+ commit((payment.is_a?(Check) ? :purchase_check : :purchase), post)
46
+ end
47
+
48
+ def refund(money, authorization, options={})
49
+ post = {}
50
+ transaction_id, payment_type = split_authorization(authorization)
51
+ post[:transaction_id] = transaction_id
52
+ add_invoice(post, -money, options)
53
+ add_ip(post, options)
54
+ add_description(post, options)
55
+
56
+ commit((payment_type == 'check' ? :refund_check : :refund), post)
57
+ end
58
+
59
+ def store(credit_card, options = {})
60
+ post = {}
61
+ add_payment(post, credit_card)
62
+ add_address(post, options)
63
+ add_ip(post, options)
64
+ add_description(post, options)
65
+ add_store_defaults(post)
66
+
67
+ commit(:store, post)
68
+ end
69
+
70
+ def unstore(authorization, options = {})
71
+ post = {}
72
+ post[:customer_code] = authorization
73
+ add_ip(post, options)
74
+
75
+ commit(:unstore, post)
76
+ end
77
+
78
+ private
79
+
80
+ def add_ip(post, options)
81
+ post[:customer_ip_address] = options[:ip] if options.has_key?(:ip)
82
+ end
83
+
84
+ def add_address(post, options)
85
+ billing_address = options[:billing_address] || options[:address]
86
+ if(billing_address)
87
+ post[:address] = billing_address[:address1]
88
+ post[:city] = billing_address[:city]
89
+ post[:state] = billing_address[:state]
90
+ post[:zip_code] = billing_address[:zip]
91
+ end
92
+ end
93
+
94
+ def add_invoice(post, money, options)
95
+ post[:invoice_num] = options[:order_id] if options[:order_id]
96
+ post[:total] = amount(money)
97
+ end
98
+
99
+ def add_description(post, options)
100
+ post[:comment] = options[:description] if options[:description]
101
+ end
102
+
103
+ def add_payment(post, payment)
104
+ if payment.is_a?(Check)
105
+ add_check(post, payment)
106
+ else
107
+ add_credit_card(post, payment)
108
+ end
109
+ end
110
+
111
+ def add_credit_card(post, payment)
112
+ post[:first_name] = payment.first_name
113
+ post[:last_name] = payment.last_name
114
+ post[:credit_card_num] = payment.number
115
+ post[:credit_card_expiry] = expdate(payment)
116
+ post[:cvv2] = payment.verification_value if payment.verification_value?
117
+ post[:mop] = creditcard_brand(payment.brand)
118
+ end
119
+
120
+ def add_check(post, payment)
121
+ post[:first_name] = payment.first_name
122
+ post[:last_name] = payment.last_name
123
+ post[:account_num] = "#{payment.routing_number}#{payment.account_number}"
124
+ post[:account_type] = payment.account_type.upcase
125
+ end
126
+
127
+ def add_store_defaults(post)
128
+ post[:recurring] = false
129
+ post[:begin_date] = Time.now.xmlschema
130
+ post[:end_date] = Time.now.xmlschema
131
+ post[:amount] = 0
132
+ end
133
+
134
+ def expdate(creditcard)
135
+ year = sprintf("%.4i", creditcard.year)
136
+ month = sprintf("%.2i", creditcard.month)
137
+
138
+ "#{month}/#{year[-2..-1]}"
139
+ end
140
+
141
+ def creditcard_brand(brand)
142
+ case brand
143
+ when "visa" then "VISA"
144
+ when "master" then "MC"
145
+ when "discover" then "DSC"
146
+ when "american_express" then "AMX"
147
+ when "maestro" then "MAESTR"
148
+ else
149
+ raise "Unhandled credit card brand #{brand}"
150
+ end
151
+ end
152
+
153
+ def commit(action, parameters)
154
+ response = parse(ssl_post(url(action), post_data(action, parameters),
155
+ { 'Content-Type' => 'application/soap+xml; charset=utf-8'}))
156
+
157
+ Response.new(
158
+ success_from(response),
159
+ message_from(response),
160
+ response,
161
+ authorization: authorization_from(action, response),
162
+ test: test?
163
+ )
164
+ end
165
+
166
+ def endpoints
167
+ {
168
+ purchase: "ProcessLink.asmx",
169
+ purchase_check: "ProcessLink.asmx",
170
+ refund: "ProcessLink.asmx",
171
+ refund_check: "ProcessLink.asmx",
172
+ store: "CustomerLink.asmx",
173
+ unstore: "CustomerLink.asmx"
174
+ }
175
+ end
176
+
177
+ def url(action)
178
+ base_url = @options[:region] == 'uk' ? live_uk_url : live_na_url
179
+ "#{base_url}/#{endpoints[action]}?op=#{ACTIONS[action]}"
180
+ end
181
+
182
+ def parse(body)
183
+ response = {}
184
+ hashify_xml!(body, response)
185
+ response
186
+ end
187
+
188
+ def dexmlize_param_name(name)
189
+ names = {
190
+ 'AUTHORIZATIONRESULT' => :authorization_result,
191
+ 'SETTLEMENTBATCHDATE' => :settlement_batch_date,
192
+ 'SETTLEMENTDATE' => :settlement_date,
193
+ 'TRANSACTIONID' => :transaction_id
194
+ }
195
+ names[name] || name.to_s.downcase.intern
196
+ end
197
+
198
+ def hashify_xml!(xml, response)
199
+ xml = REXML::Document.new(xml)
200
+
201
+ xml.elements.each("//IATSRESPONSE/*") do |node|
202
+ recursively_parse_element(node, response)
203
+ end
204
+ end
205
+
206
+ def recursively_parse_element(node, response)
207
+ if(node.has_elements?)
208
+ node.elements.each { |n| recursively_parse_element(n, response) }
209
+ else
210
+ response[dexmlize_param_name(node.name)] = (node.text ? node.text.strip : nil)
211
+ end
212
+ end
213
+
214
+ def successful_result_message?(response)
215
+ response[:authorization_result].start_with?('OK')
216
+ end
217
+
218
+ def success_from(response)
219
+ response[:status] == "Success" && successful_result_message?(response)
220
+ end
221
+
222
+ def message_from(response)
223
+ if(!successful_result_message?(response))
224
+ return response[:authorization_result].strip
225
+ elsif(response[:status] == 'Failure')
226
+ return response[:errors]
227
+ else
228
+ response[:status]
229
+ end
230
+ end
231
+
232
+ def authorization_from(action, response)
233
+ if [:store, :unstore].include?(action)
234
+ response[:customercode]
235
+ elsif [:purchase_check].include?(action)
236
+ response[:transaction_id] ? "#{response[:transaction_id]}|check" : nil
237
+ else
238
+ response[:transaction_id]
239
+ end
240
+ end
241
+
242
+ def split_authorization(authorization)
243
+ authorization.split("|")
244
+ end
245
+
246
+ def envelope_namespaces
247
+ {
248
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
249
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
250
+ "xmlns:soap12" => "http://www.w3.org/2003/05/soap-envelope"
251
+ }
252
+ end
253
+
254
+ def post_data(action, parameters = {})
255
+ xml = Builder::XmlMarkup.new
256
+ xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
257
+ xml.tag! 'soap12:Envelope', envelope_namespaces do
258
+ xml.tag! 'soap12:Body' do
259
+ xml.tag! ACTIONS[action], { "xmlns" => "https://www.iatspayments.com/NetGate/" } do
260
+ xml.tag!('agentCode', @options[:agent_code])
261
+ xml.tag!('password', @options[:password])
262
+ parameters.each do |name, value|
263
+ xml.tag!(xmlize_param_name(name), value)
264
+ end
265
+ end
266
+ end
267
+ end
268
+ xml.target!
269
+ end
270
+
271
+ def xmlize_param_name(name)
272
+ names = { customer_ip_address: 'customerIPAddress' }
273
+ names[name] || name.to_s.camelcase(:lower)
274
+ end
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,246 @@
1
+ require 'active_merchant/billing/gateways/ideal/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