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,216 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ class CheckoutGateway < Gateway
7
+ self.default_currency = 'USD'
8
+ self.money_format = :decimals
9
+
10
+ self.supported_countries = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MT', 'MU', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK', 'US']
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
12
+
13
+ self.homepage_url = 'https://www.checkout.com/'
14
+ self.display_name = 'Checkout.com'
15
+
16
+ self.live_url = 'https://api.checkout.com/Process/gateway.aspx'
17
+
18
+ ACTIONS = {
19
+ 'purchase' => '1',
20
+ 'authorize' => '4',
21
+ 'capture' => '5',
22
+ 'refund' => '2',
23
+ 'void_purchase' => '3',
24
+ 'void_authorize' => '9',
25
+ 'void_capture' => '7'
26
+ }
27
+
28
+ def initialize(options = {})
29
+ requires!(options, :merchant_id, :password)
30
+ super
31
+ end
32
+
33
+ def purchase(amount, payment_method, options)
34
+ requires!(options, :order_id)
35
+
36
+ commit('purchase', amount, options) do |xml|
37
+ add_credentials(xml, options)
38
+ add_invoice(xml, amount, options)
39
+ add_track_id(xml, options[:order_id])
40
+ add_payment_method(xml, payment_method)
41
+ add_billing_info(xml, options)
42
+ add_shipping_info(xml, options)
43
+ add_user_defined_fields(xml, options)
44
+ add_other_fields(xml, options)
45
+ end
46
+ end
47
+
48
+ def authorize(amount, payment_method, options)
49
+ requires!(options, :order_id)
50
+
51
+ commit('authorize', amount, options) do |xml|
52
+ add_credentials(xml, options)
53
+ add_invoice(xml, amount, options)
54
+ add_track_id(xml, options[:order_id])
55
+ add_payment_method(xml, payment_method)
56
+ add_billing_info(xml, options)
57
+ add_shipping_info(xml, options)
58
+ add_user_defined_fields(xml, options)
59
+ add_other_fields(xml, options)
60
+ end
61
+ end
62
+
63
+ def capture(amount, authorization, options = {})
64
+ commit('capture', amount, options) do |xml|
65
+ add_credentials(xml, options)
66
+ add_reference(xml, authorization)
67
+ add_invoice(xml, amount, options)
68
+ add_user_defined_fields(xml, options)
69
+ add_other_fields(xml, options)
70
+ end
71
+ end
72
+
73
+ def void(authorization, options = {})
74
+ _, _, orig_action, amount, currency = split_authorization(authorization)
75
+ commit("void_#{orig_action}") do |xml|
76
+ add_credentials(xml, options)
77
+ add_invoice(xml, amount.to_i, options.merge(currency: currency))
78
+ add_reference(xml, authorization)
79
+ end
80
+ end
81
+
82
+ def refund(amount, authorization, options = {})
83
+ commit('refund') do |xml|
84
+ add_credentials(xml, options)
85
+ add_invoice(xml, amount.to_i, options)
86
+ add_reference(xml, authorization)
87
+ end
88
+ end
89
+
90
+ def verify(credit_card, options={})
91
+ MultiResponse.run(:use_first_response) do |r|
92
+ r.process { authorize(100, credit_card, options) }
93
+ r.process(:ignore_result) { void(r.authorization, options) }
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ def add_credentials(xml, options)
100
+ xml.merchantid_ @options[:merchant_id]
101
+ xml.password_ @options[:password]
102
+ end
103
+
104
+ def add_invoice(xml, amount, options)
105
+ xml.bill_amount_ amount(amount)
106
+ xml.bill_currencycode_ options[:currency] || currency(amount)
107
+ end
108
+
109
+ def add_payment_method(xml, payment_method)
110
+ xml.bill_cardholder_ payment_method.name
111
+ xml.bill_cc_ payment_method.number
112
+ xml.bill_expmonth_ format(payment_method.month, :two_digits)
113
+ xml.bill_expyear_ format(payment_method.year, :four_digits)
114
+ if payment_method.verification_value?
115
+ xml.bill_cvv2_ payment_method.verification_value
116
+ end
117
+ end
118
+
119
+ def add_billing_info(xml, options)
120
+ if options[:billing_address]
121
+ xml.bill_address_ options[:billing_address][:address1]
122
+ xml.bill_city_ options[:billing_address][:city]
123
+ xml.bill_state_ options[:billing_address][:state]
124
+ xml.bill_postal_ options[:billing_address][:zip]
125
+ xml.bill_country_ options[:billing_address][:country]
126
+ xml.bill_phone_ options[:billing_address][:phone]
127
+ end
128
+ end
129
+
130
+ def add_shipping_info(xml, options)
131
+ if options[:shipping_address]
132
+ xml.ship_address_ options[:shipping_address][:address1]
133
+ xml.ship_address2_ options[:shipping_address][:address2]
134
+ xml.ship_city_ options[:shipping_address][:city]
135
+ xml.ship_state_ options[:shipping_address][:state]
136
+ xml.ship_postal_ options[:shipping_address][:zip]
137
+ xml.ship_country_ options[:shipping_address][:country]
138
+ xml.ship_phone_ options[:shipping_address][:phone]
139
+ end
140
+ end
141
+
142
+ def add_user_defined_fields(xml, options)
143
+ xml.udf1_ options[:udf1]
144
+ xml.udf2_ options[:udf2]
145
+ xml.udf3_ options[:udf3]
146
+ xml.udf4_ options[:udf4]
147
+ xml.udf5_ options[:udf5]
148
+ end
149
+
150
+ def add_other_fields(xml, options)
151
+ xml.bill_email_ options[:email]
152
+ xml.bill_customerip_ options[:ip]
153
+ xml.merchantcustomerid_ options[:customer]
154
+ end
155
+
156
+ def add_reference(xml, authorization)
157
+ transid, trackid, _, _, _ = split_authorization(authorization)
158
+ xml.transid transid
159
+ add_track_id(xml, trackid)
160
+ end
161
+
162
+ def add_track_id(xml, trackid)
163
+ xml.trackid(trackid) if trackid
164
+ end
165
+
166
+ def commit(action, amount=nil, options={}, &builder)
167
+ response = parse_xml(ssl_post(live_url, build_xml(action, &builder)))
168
+ Response.new(
169
+ (response[:responsecode] == "0"),
170
+ (response[:result] || response[:error_text] || "Unknown Response"),
171
+ response,
172
+ authorization: authorization_from(response, action, amount, options),
173
+ test: test?
174
+ )
175
+ end
176
+
177
+ def build_xml(action)
178
+ Nokogiri::XML::Builder.new do |xml|
179
+ xml.request do
180
+ xml.action_ ACTIONS[action]
181
+ yield xml
182
+ end
183
+ end.to_xml
184
+ end
185
+
186
+ def parse_xml(xml)
187
+ response = {}
188
+
189
+ Nokogiri::XML(CGI.unescapeHTML(xml)).xpath("//response").children.each do |node|
190
+ if node.text?
191
+ next
192
+ elsif (node.elements.size == 0)
193
+ response[node.name.downcase.to_sym] = node.text
194
+ else
195
+ node.elements.each do |childnode|
196
+ name = "#{node.name.downcase}_#{childnode.name.downcase}"
197
+ response[name.to_sym] = childnode.text
198
+ end
199
+ end
200
+ end
201
+
202
+ response
203
+ end
204
+
205
+ def authorization_from(response, action, amount, options)
206
+ currency = options[:currency] || currency(amount)
207
+ [response[:tranid], response[:trackid], action, amount, currency].join("|")
208
+ end
209
+
210
+ def split_authorization(authorization)
211
+ transid, trackid, action, amount, currency = authorization.split("|")
212
+ [transid, trackid, action, amount, currency]
213
+ end
214
+ end
215
+ end
216
+ end
@@ -0,0 +1,200 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class CheckoutV2Gateway < Gateway
4
+ self.display_name = "Checkout.com V2 Gateway"
5
+ self.homepage_url = "https://www.checkout.com/"
6
+ self.test_url = "https://api2.checkout.com/v2"
7
+ self.live_url = "http://sandbox.checkout.com/api2/v2"
8
+
9
+ self.supported_countries = ['AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HR', 'HU', 'IE', 'IS', 'IT', 'LI', 'LT', 'LU', 'LV', 'MT', 'MU', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK', 'US']
10
+ self.default_currency = "USD"
11
+ self.money_format = :cents
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
13
+
14
+ def initialize(options={})
15
+ requires!(options, :secret_key)
16
+ super
17
+ end
18
+
19
+ def purchase(amount, payment_method, options={})
20
+ MultiResponse.run do |r|
21
+ r.process { authorize(amount, payment_method, options) }
22
+ r.process { capture(amount, r.authorization, options) }
23
+ end
24
+ end
25
+
26
+ def authorize(amount, payment_method, options={})
27
+ post = {}
28
+ post[:autoCapture] = "n"
29
+ add_invoice(post, amount, options)
30
+ add_payment_method(post, payment_method)
31
+ add_customer_data(post, options)
32
+
33
+ commit(:authorize, post)
34
+ end
35
+
36
+ def capture(amount, authorization, options={})
37
+ post = {}
38
+ add_invoice(post, amount, options)
39
+ add_customer_data(post, options)
40
+
41
+ commit(:capture, post, authorization)
42
+ end
43
+
44
+ def void(authorization, options={})
45
+ post = {}
46
+ commit(:void, post, authorization)
47
+ end
48
+
49
+ def refund(amount, authorization, options={})
50
+ post = {}
51
+ add_invoice(post, amount, options)
52
+ add_customer_data(post, options)
53
+
54
+ commit(:refund, post, authorization)
55
+ end
56
+
57
+ def verify(credit_card, options={})
58
+ MultiResponse.run(:use_first_response) do |r|
59
+ r.process { authorize(100, credit_card, options) }
60
+ r.process(:ignore_result) { void(r.authorization, options) }
61
+ end
62
+ end
63
+
64
+ def supports_scrubbing?
65
+ true
66
+ end
67
+
68
+ def scrub(transcript)
69
+ transcript.
70
+ gsub(%r((Authorization: )[^\\]*)i, '\1[FILTERED]').
71
+ gsub(%r(("number\\":\\")\d+), '\1[FILTERED]').
72
+ gsub(%r(("cvv\\":\\")\d+), '\1[FILTERED]')
73
+ end
74
+
75
+ private
76
+
77
+ def add_invoice(post, money, options)
78
+ post[:value] = amount(money)
79
+ post[:trackId] = options[:order_id]
80
+ post[:currency] = options[:currency] || currency(money)
81
+ end
82
+
83
+ def add_payment_method(post, payment_method)
84
+ post[:card] = {}
85
+ post[:card][:name] = payment_method.name
86
+ post[:card][:number] = payment_method.number
87
+ post[:card][:cvv] = payment_method.verification_value
88
+ post[:card][:expiryYear] = format(payment_method.year, :four_digits)
89
+ post[:card][:expiryMonth] = format(payment_method.month, :two_digits)
90
+ end
91
+
92
+ def add_customer_data(post, options)
93
+ post[:email] = options[:email] || "unspecified@example.com"
94
+ address = options[:billing_address]
95
+ if(address && post[:card])
96
+ post[:card][:billingDetails] = {}
97
+ post[:card][:billingDetails][:address1] = address[:address1]
98
+ post[:card][:billingDetails][:address2] = address[:address2]
99
+ post[:card][:billingDetails][:city] = address[:city]
100
+ post[:card][:billingDetails][:state] = address[:state]
101
+ post[:card][:billingDetails][:country] = address[:country]
102
+ post[:card][:billingDetails][:postcode] = address[:zip]
103
+ post[:card][:billingDetails][:phone] = { number: address[:phone] }
104
+ end
105
+ end
106
+
107
+ def commit(action, post, authorization = nil)
108
+ begin
109
+ raw_response = ssl_post(url(post, action, authorization), post.to_json, headers)
110
+ response = parse(raw_response)
111
+ rescue ResponseError => e
112
+ raise unless(e.response.code.to_s =~ /4\d\d/)
113
+ response = parse(e.response.body)
114
+ end
115
+
116
+ succeeded = success_from(response)
117
+ Response.new(
118
+ succeeded,
119
+ message_from(succeeded, response),
120
+ response,
121
+ authorization: authorization_from(response),
122
+ error_code: error_code_from(succeeded, response),
123
+ test: test?,
124
+ avs_result: avs_result(action, response),
125
+ cvv_result: cvv_result(action, response))
126
+ end
127
+
128
+ def headers
129
+ {
130
+ "Authorization" => @options[:secret_key],
131
+ "Content-Type" => "application/json;charset=UTF-8"
132
+ }
133
+ end
134
+
135
+ def url(post, action, authorization)
136
+ if action == :authorize
137
+ "#{base_url}/charges/card"
138
+ else
139
+ "#{base_url}/charges/#{authorization}/#{action}"
140
+ end
141
+ end
142
+
143
+ def base_url
144
+ test? ? test_url : live_url
145
+ end
146
+
147
+ def avs_result(action, response)
148
+ action == :purchase ? AVSResult.new(code: response["card"]["avsCheck"]) : nil
149
+ end
150
+
151
+ def cvv_result(action, response)
152
+ action == :purchase ? CVVResult.new(response["card"]["cvvCheck"]) : nil
153
+ end
154
+
155
+ def parse(body)
156
+ JSON.parse(body)
157
+ rescue JSON::ParserError
158
+ {
159
+ "message" => "Invalid JSON response received from CheckoutV2Gateway. Please contact CheckoutV2Gateway if you continue to receive this message.",
160
+ "raw_response" => scrub(body)
161
+ }
162
+ end
163
+
164
+ def success_from(response)
165
+ response["responseCode"] == ("10000" || "10100")
166
+ end
167
+
168
+ def message_from(succeeded, response)
169
+ if succeeded
170
+ "Succeeded"
171
+ elsif response["errors"]
172
+ response["message"] + ": " + response["errors"].first
173
+ else
174
+ response["responseMessage"] || response["message"] || "Unable to read error message"
175
+ end
176
+ end
177
+
178
+ STANDARD_ERROR_CODE_MAPPING = {
179
+ "20014" => STANDARD_ERROR_CODE[:invalid_number],
180
+ "20100" => STANDARD_ERROR_CODE[:invalid_expiry_date],
181
+ "20054" => STANDARD_ERROR_CODE[:expired_card],
182
+ "40104" => STANDARD_ERROR_CODE[:incorrect_cvc],
183
+ "40108" => STANDARD_ERROR_CODE[:incorrect_zip],
184
+ "40111" => STANDARD_ERROR_CODE[:incorrect_address],
185
+ "20005" => STANDARD_ERROR_CODE[:card_declined],
186
+ "20088" => STANDARD_ERROR_CODE[:processing_error],
187
+ "20001" => STANDARD_ERROR_CODE[:call_issuer],
188
+ "30004" => STANDARD_ERROR_CODE[:pickup_card]
189
+ }
190
+
191
+ def authorization_from(raw)
192
+ raw["id"]
193
+ end
194
+
195
+ def error_code_from(succeeded, response)
196
+ succeeded ? nil : STANDARD_ERROR_CODE_MAPPING[response["responseCode"]]
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,143 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class CommercegateGateway < Gateway
4
+ self.test_url = self.live_url = 'https://secure.commercegate.com/gateway/nvp'
5
+
6
+ self.supported_countries = %w(
7
+ AD AT AX BE BG CH CY CZ DE DK ES FI FR GB GG
8
+ GI GR HR HU IE IM IS IT JE LI LT LU LV MC MT
9
+ NL NO PL PT RO SE SI SK VA
10
+ )
11
+
12
+ self.money_format = :dollars
13
+ self.default_currency = 'EUR'
14
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
15
+ self.homepage_url = 'http://www.commercegate.com/'
16
+ self.display_name = 'CommerceGate'
17
+
18
+ def initialize(options = {})
19
+ requires!(options, :login, :password, :site_id, :offer_id)
20
+ super
21
+ end
22
+
23
+ def authorize(money, creditcard, options = {})
24
+ post = {}
25
+ add_creditcard(post, creditcard)
26
+ add_auth_purchase_options(post, money, options)
27
+ commit('AUTH', post)
28
+ end
29
+
30
+ def capture(money, authorization, options = {})
31
+ post = {}
32
+ post[:currencyCode] = (options[:currency] || currency(money))
33
+ post[:amount] = amount(money)
34
+ post[:transID] = authorization
35
+ commit('CAPTURE', post)
36
+ end
37
+
38
+ def purchase(money, creditcard, options = {})
39
+ post = {}
40
+ add_creditcard(post, creditcard)
41
+ add_auth_purchase_options(post, money, options)
42
+ commit('SALE', post)
43
+ end
44
+
45
+ def refund(money, identification, options = {})
46
+ post = {}
47
+ post[:currencyCode] = options[:currency] || currency(money)
48
+ post[:amount] = amount(money)
49
+ post[:transID] = identification
50
+ commit('REFUND', post)
51
+ end
52
+
53
+ def void(identification, options = {})
54
+ post = {}
55
+ post[:transID] = identification
56
+ commit('VOID_AUTH', post)
57
+ end
58
+
59
+ private
60
+
61
+ def add_address(post, address)
62
+ if address
63
+ post[:address] = address[:address1]
64
+ post[:city] = address[:city]
65
+ post[:state] = address[:state]
66
+ post[:postalCode] = address[:zip]
67
+ end
68
+ post[:countryCode] = ((address && address[:country]) || "US")
69
+ end
70
+
71
+ def add_auth_purchase_options(post, money, options)
72
+ add_address(post, options[:address])
73
+
74
+ post[:customerIP] = options[:ip] || "127.0.0.1"
75
+ post[:amount] = amount(money)
76
+ post[:email] = options[:email] || "unknown@example.com"
77
+ post[:currencyCode]= options[:currency] || currency(money)
78
+ post[:merchAcct] = options[:merchant]
79
+
80
+ end
81
+
82
+ def add_creditcard(params, creditcard)
83
+ params[:firstName] = creditcard.first_name
84
+ params[:lastName] = creditcard.last_name
85
+ params[:cardNumber] = creditcard.number
86
+ params[:expiryMonth] = creditcard.month
87
+ params[:expiryYear] = creditcard.year
88
+ params[:cvv] = creditcard.verification_value if creditcard.verification_value?
89
+ end
90
+
91
+ def commit(action, parameters)
92
+ parameters[:apiUsername] = @options[:login]
93
+ parameters[:apiPassword] = @options[:password]
94
+ parameters[:siteID] = @options[:site_id]
95
+ parameters[:offerID] = @options[:offer_id]
96
+ parameters[:action] = action
97
+
98
+ response = parse(ssl_post(self.live_url, post_data(parameters)))
99
+
100
+ Response.new(
101
+ successful?(response),
102
+ message_from(response),
103
+ response,
104
+ authorization: response['transID'],
105
+ test: test?,
106
+ avs_result: {code: response['avsCode']},
107
+ cvv_result: response['cvvCode']
108
+ )
109
+ end
110
+
111
+ def parse(body)
112
+ results = {}
113
+
114
+ body.split(/\&/).each do |pair|
115
+ key,val = pair.split(%r{=})
116
+ results[key] = CGI.unescape(val)
117
+ end
118
+
119
+ results
120
+ end
121
+
122
+ def successful?(response)
123
+ response['returnCode'] == '0'
124
+ end
125
+
126
+ def message_from(response)
127
+ if response['returnText'].present?
128
+ response['returnText']
129
+ else
130
+ "Invalid response received from the CommerceGate API. " +
131
+ "Please contact CommerceGate support if you continue to receive this message. " +
132
+ "(The raw response returned by the API was #{response.inspect})"
133
+ end
134
+ end
135
+
136
+ def post_data(parameters)
137
+ parameters.collect do |key, value|
138
+ "#{key}=#{CGI.escape(value.to_s)}"
139
+ end.join("&")
140
+ end
141
+ end
142
+ end
143
+ end