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,278 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class CertoDirectGateway < Gateway
4
+ self.live_url = self.test_url = "https://secure.certodirect.com/gateway/process/v2"
5
+
6
+ self.supported_countries = [
7
+ "BE", "BG", "CZ", "DK", "DE", "EE", "IE", "ES", "FR",
8
+ "IT", "CY", "LV", "LT", "LU", "HU", "MT", "NL", "AT", "PL",
9
+ "PT", "RO", "SI", "SK", "FI", "SE", "GB"
10
+ ]
11
+
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
13
+ self.homepage_url = 'http://www.certodirect.com/'
14
+ self.display_name = 'CertoDirect'
15
+
16
+ # Creates a new CertoDirectGateway
17
+ #
18
+ # The gateway requires that a valid login and password be passed
19
+ # in the +options+ hash.
20
+ #
21
+ # ==== Options
22
+ #
23
+ # * <tt>:login</tt> -- The CertoDirect Shop ID (REQUIRED)
24
+ # * <tt>:password</tt> -- The CertoDirect Shop Password. (REQUIRED)
25
+ # * <tt>:test</tt> -- +true+ or +false+. If true, perform transactions against the test server.
26
+ # Otherwise, perform transactions against the production server.
27
+ def initialize(options = {})
28
+ requires!(options, :login, :password)
29
+ super
30
+ end
31
+
32
+ # Perform a purchase, which is essentially an authorization and capture in a single operation.
33
+ #
34
+ # ==== Parameters
35
+ #
36
+ # * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
37
+ # * <tt>credit_card</tt> -- The CreditCard details for the transaction.
38
+ # * <tt>options</tt> -- A hash of optional parameters.
39
+ def purchase(money, credit_card, options = {})
40
+ requires!(options, :email, :currency, :ip, :description)
41
+
42
+ commit(build_sale_request(money, credit_card, options))
43
+ end
44
+
45
+ # Refund a transaction.
46
+ #
47
+ # This transaction indicates to the gateway that
48
+ # money should flow from the merchant to the customer.
49
+ #
50
+ # ==== Parameters
51
+ #
52
+ # * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
53
+ # * <tt>identification</tt> -- The ID of the original order against which the refund is being issued.
54
+ # * <tt>options</tt> -- A hash of parameters.
55
+ def refund(money, identification, options = {})
56
+ requires!(options, :reason)
57
+
58
+ commit(build_refund_request(money, identification, options))
59
+ end
60
+
61
+ # Performs an authorization, which reserves the funds on the customer's credit card, but does not
62
+ # charge the card.
63
+ #
64
+ # ==== Parameters
65
+ #
66
+ # * <tt>money</tt> -- The amount to be authorized as an Integer value in cents.
67
+ # * <tt>credit_card</tt> -- The CreditCard details for the transaction.
68
+ # * <tt>options</tt> -- A hash of optional parameters.
69
+ def authorize(money, credit_card, options = {})
70
+ requires!(options, :email, :currency, :ip, :description)
71
+
72
+ commit(build_authorize_request(money, credit_card, options))
73
+ end
74
+
75
+ # Captures the funds from an authorized transaction.
76
+ #
77
+ # ==== Parameters
78
+ #
79
+ # * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
80
+ # * <tt>identification</tt> -- The authorization returned from the previous authorize request.
81
+ def capture(money, identification, options = {})
82
+ commit(build_capture_request(money, identification))
83
+ end
84
+
85
+ # Void a previous transaction
86
+ #
87
+ # ==== Parameters
88
+ #
89
+ # * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
90
+ # * <tt>identification</tt> - The authorization returned from the previous authorize request.
91
+ def void(money, identification, options = {})
92
+ commit(build_void_request(money, identification))
93
+ end
94
+
95
+ # Create a recurring payment.
96
+ #
97
+ # ==== Parameters
98
+ #
99
+ # * <tt>options</tt> -- A hash of parameters.
100
+ #
101
+ # ==== Options
102
+ #
103
+ def recurring(identification, options={})
104
+ ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE
105
+
106
+ commit(build_recurring_request(identification, options))
107
+ end
108
+
109
+ private
110
+
111
+ def commit(request_xml)
112
+ begin
113
+ response = Hash.from_xml(ssl_post(self.live_url, request_xml, headers))
114
+ Response.new(success?(response),
115
+ message(response),
116
+ response,
117
+ :test => test?,
118
+ :authorization => authorization(response))
119
+ rescue ResponseError => e
120
+ raise e unless e.response.code == '403'
121
+ response = Hash.from_xml(e.response.body)['response']
122
+ Response.new(false, message(response), {}, :test => test?)
123
+ end
124
+ end
125
+
126
+ def build_sale_request(money, credit_card, options)
127
+ build_request_xml('Sale') do |xml|
128
+ add_order(xml, money, credit_card, options)
129
+ end
130
+ end
131
+
132
+ def build_authorize_request(money, credit_card, options)
133
+ build_request_xml('Authorize') do |xml|
134
+ add_order(xml, money, credit_card, options)
135
+ end
136
+ end
137
+
138
+ def build_refund_request(money, identification, options)
139
+ build_request_xml('Refund') do |xml|
140
+ add_reference_info(xml, money, identification, options)
141
+ xml.tag! 'reason', options[:reason]
142
+ end
143
+ end
144
+
145
+ def build_capture_request(money, identification)
146
+ build_request_xml('Capture') do |xml|
147
+ add_reference_info(xml, money, identification, options)
148
+ end
149
+ end
150
+
151
+ def build_void_request(money, identification)
152
+ build_request_xml('Void') do |xml|
153
+ add_reference_info(xml, money, identification, options)
154
+ end
155
+ end
156
+
157
+ def build_recurring_request(identification, options)
158
+ build_request_xml('Sale') do |xml|
159
+ xml.tag! 'order' do
160
+ xml.tag!('test', 'true') if test?
161
+ xml.tag! 'initial_order_id', identification, :type => 'integer'
162
+
163
+ add_order_details(xml, options[:amount], options) if has_any_order_details_key?(options)
164
+ add_address(xml, 'billing_address', options[:billing_address]) if options[:billing_address]
165
+ add_address(xml, 'shipping_address', options[:shipping_address]) if options[:shipping_address]
166
+ end
167
+ end
168
+ end
169
+
170
+ def build_request_xml(type, &block)
171
+ xml = Builder::XmlMarkup.new(:indent => 2)
172
+ xml.tag! 'transaction' do
173
+ xml.tag! 'type', type
174
+ yield(xml)
175
+ end
176
+ xml.target!
177
+ end
178
+
179
+ def add_order(xml, money, credit_card, options)
180
+ xml.tag! 'order' do
181
+ xml.tag!('test', 'true') if test?
182
+
183
+ xml.tag!('return_url', options[:return_url]) if options[:return_url]
184
+ xml.tag!('cancel_url', options[:cancel_url]) if options[:cancel_url]
185
+
186
+ xml.tag! 'payment_method_type', 'CreditCard'
187
+ xml.tag! 'payment_method' do
188
+ xml.tag! 'number', credit_card.number
189
+ xml.tag! 'exp_month', "%02i" % credit_card.month
190
+ xml.tag! 'exp_year', credit_card.year
191
+ xml.tag! 'holder', credit_card.name
192
+ xml.tag! 'verification_value', credit_card.verification_value
193
+ end
194
+
195
+ add_order_details(xml, money, options)
196
+ add_address(xml, 'billing_address', options[:billing_address]) if options[:billing_address]
197
+ add_address(xml, 'shipping_address', options[:shipping_address]) if options[:shipping_address]
198
+ end
199
+ end
200
+
201
+ def add_order_details(xml, money, options)
202
+ xml.tag! 'details' do
203
+ xml.tag!('amount', localized_amount(money, options[:currency]), :type => 'decimal') if money
204
+ xml.tag!('currency', options[:currency]) if options[:currency]
205
+ xml.tag!('email', options[:email]) if options[:email]
206
+ xml.tag!('ip', options[:ip]) if options[:ip]
207
+ xml.tag!('shipping', options[:shipping], :type => 'decimal') if options[:shipping]
208
+ xml.tag!('description', options[:description]) if options[:description]
209
+ end
210
+ end
211
+
212
+ def add_reference_info(xml, money, identification, options)
213
+ xml.tag! 'order_id', identification, :type => 'integer'
214
+ xml.tag! 'amount', localized_amount(money, options[:currency]), :type => 'decimal'
215
+ end
216
+
217
+ def add_address(xml, address_type, address)
218
+ xml.tag! address_type do
219
+ xml.tag! 'address', address[:address1]
220
+ xml.tag! 'city', address[:city]
221
+ xml.tag! 'country', address[:country]
222
+ xml.tag! 'first_name', address[:first_name]
223
+ xml.tag! 'last_name', address[:last_name]
224
+ xml.tag! 'state', address[:state]
225
+ xml.tag! 'phone', address[:phone]
226
+ xml.tag! 'zip', address[:zip]
227
+ end
228
+ end
229
+
230
+ def has_any_order_details_key?(options)
231
+ [ :currency, :amount, :email, :ip, :shipping, :description ].any? do |key|
232
+ options.has_key?(key)
233
+ end
234
+ end
235
+
236
+ def success?(response)
237
+ %w(completed forwarding).include?(state(response)) and
238
+ status(response) == 'success'
239
+ end
240
+
241
+ def error?(response)
242
+ response['errors']
243
+ end
244
+
245
+ def state(response)
246
+ response["transaction"].try(:[], "state")
247
+ end
248
+
249
+ def status(response)
250
+ response['transaction'].try(:[], 'response').try(:[], 'status')
251
+ end
252
+
253
+ def authorization(response)
254
+ error?(response) ? nil : response["transaction"]["order"]['id'].to_s
255
+ end
256
+
257
+ def message(response)
258
+ return response['errors'].join('; ') if error?(response)
259
+
260
+ if state(response) == 'completed'
261
+ response["transaction"]["response"]["message"]
262
+ else
263
+ response['transaction']['message']
264
+ end
265
+ end
266
+
267
+ def headers
268
+ { 'authorization' => basic_auth,
269
+ 'Accept' => 'application/xml',
270
+ 'Content-Type' => 'application/xml' }
271
+ end
272
+
273
+ def basic_auth
274
+ 'Basic ' + ["#{@options[:login]}:#{@options[:password]}"].pack('m').delete("\r\n")
275
+ end
276
+ end
277
+ end
278
+ end
@@ -0,0 +1,213 @@
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
+ @url = (options[:gateway_url] || self.live_url)
30
+
31
+ requires!(options, :merchant_id, :password)
32
+ super
33
+ end
34
+
35
+ def purchase(amount, payment_method, options)
36
+ requires!(options, :order_id)
37
+
38
+ commit('purchase', amount, options) do |xml|
39
+ add_credentials(xml, options)
40
+ add_invoice(xml, amount, options)
41
+ add_payment_method(xml, payment_method)
42
+ add_billing_info(xml, options)
43
+ add_shipping_info(xml, options)
44
+ add_user_defined_fields(xml, options)
45
+ add_other_fields(xml, options)
46
+ end
47
+ end
48
+
49
+ def authorize(amount, payment_method, options)
50
+ requires!(options, :order_id)
51
+
52
+ commit('authorize', amount, options) do |xml|
53
+ add_credentials(xml, options)
54
+ add_invoice(xml, amount, options)
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
+ xml.trackid_ options[:order_id] if options[:order_id]
108
+ end
109
+
110
+ def add_payment_method(xml, payment_method)
111
+ xml.bill_cardholder_ payment_method.name
112
+ xml.bill_cc_ payment_method.number
113
+ xml.bill_expmonth_ format(payment_method.month, :two_digits)
114
+ xml.bill_expyear_ format(payment_method.year, :four_digits)
115
+ if payment_method.verification_value?
116
+ xml.bill_cvv2_ payment_method.verification_value
117
+ end
118
+ end
119
+
120
+ def add_billing_info(xml, options)
121
+ if options[:billing_address]
122
+ xml.bill_address_ options[:billing_address][:address1]
123
+ xml.bill_city_ options[:billing_address][:city]
124
+ xml.bill_state_ options[:billing_address][:state]
125
+ xml.bill_postal_ options[:billing_address][:zip]
126
+ xml.bill_country_ options[:billing_address][:country]
127
+ xml.bill_phone_ options[:billing_address][:phone]
128
+ end
129
+ end
130
+
131
+ def add_shipping_info(xml, options)
132
+ if options[:shipping_address]
133
+ xml.ship_address_ options[:shipping_address][:address1]
134
+ xml.ship_address2_ options[:shipping_address][:address2]
135
+ xml.ship_city_ options[:shipping_address][:city]
136
+ xml.ship_state_ options[:shipping_address][:state]
137
+ xml.ship_postal_ options[:shipping_address][:zip]
138
+ xml.ship_country_ options[:shipping_address][:country]
139
+ xml.ship_phone_ options[:shipping_address][:phone]
140
+ end
141
+ end
142
+
143
+ def add_user_defined_fields(xml, options)
144
+ xml.udf1_ options[:udf1]
145
+ xml.udf2_ options[:udf2]
146
+ xml.udf3_ options[:udf3]
147
+ xml.udf4_ options[:udf4]
148
+ xml.udf5_ options[:udf5]
149
+ end
150
+
151
+ def add_other_fields(xml, options)
152
+ xml.bill_email_ options[:email]
153
+ xml.bill_customerip_ options[:ip]
154
+ xml.merchantcustomerid_ options[:customer]
155
+ end
156
+
157
+ def add_reference(xml, authorization)
158
+ transid, trackid, _, _, _ = split_authorization(authorization)
159
+ xml.transid transid
160
+ xml.trackid trackid if trackid
161
+ end
162
+
163
+ def commit(action, amount=nil, options={}, &builder)
164
+ response = parse_xml(ssl_post(@url, build_xml(action, &builder)))
165
+ Response.new(
166
+ (response[:responsecode] == "0"),
167
+ (response[:result] || response[:error_text] || "Unknown Response"),
168
+ response,
169
+ authorization: authorization_from(response, action, amount, options),
170
+ test: test?
171
+ )
172
+ end
173
+
174
+ def build_xml(action)
175
+ Nokogiri::XML::Builder.new do |xml|
176
+ xml.request do
177
+ xml.action_ ACTIONS[action]
178
+ yield xml
179
+ end
180
+ end.to_xml
181
+ end
182
+
183
+ def parse_xml(xml)
184
+ response = {}
185
+
186
+ Nokogiri::XML(CGI.unescapeHTML(xml)).xpath("//response").children.each do |node|
187
+ if node.text?
188
+ next
189
+ elsif (node.elements.size == 0)
190
+ response[node.name.downcase.to_sym] = node.text
191
+ else
192
+ node.elements.each do |childnode|
193
+ name = "#{node.name.downcase}_#{childnode.name.downcase}"
194
+ response[name.to_sym] = childnode.text
195
+ end
196
+ end
197
+ end
198
+
199
+ response
200
+ end
201
+
202
+ def authorization_from(response, action, amount, options)
203
+ currency = options[:currency] || currency(amount)
204
+ [response[:tranid], response[:trackid], action, amount, currency].join("|")
205
+ end
206
+
207
+ def split_authorization(authorization)
208
+ transid, trackid, action, amount, currency = authorization.split("|")
209
+ [transid, trackid, action, amount, currency]
210
+ end
211
+ end
212
+ end
213
+ end