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,283 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'check.rb')
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class SmartPs < Gateway #:nodoc:
6
+
7
+ ##
8
+ # This is the base gateway for processors who use the smartPS processing system
9
+
10
+ self.abstract_class = true
11
+
12
+ def initialize(options = {})
13
+ requires!(options, :login, :password)
14
+ super
15
+ end
16
+
17
+ # Pass :store => true in the options to store the
18
+ # payment info at the gateway and get a generated
19
+ # customer_vault_id in the response.
20
+ # Pass :store => some_number_or_string to specify the
21
+ # customer_vault_id the gateway should use (make sure it's
22
+ # unique).
23
+ def authorize(money, creditcard, options = {})
24
+ post = {}
25
+ add_invoice(post, options)
26
+ add_payment_source(post, creditcard,options)
27
+ add_address(post, options[:billing_address] || options[:address])
28
+ add_address(post, options[:shipping_address], "shipping")
29
+ add_customer_data(post, options)
30
+ add_currency(post, money, options)
31
+ add_taxes(post, options)
32
+ add_processor(post, options)
33
+ commit('auth', money, post)
34
+ end
35
+
36
+ def purchase(money, payment_source, options = {})
37
+ post = {}
38
+ add_invoice(post, options)
39
+ add_payment_source(post, payment_source, options)
40
+ add_address(post, options[:billing_address] || options[:address])
41
+ add_address(post, options[:shipping_address], "shipping")
42
+ add_customer_data(post, options)
43
+ add_currency(post, money, options)
44
+ add_taxes(post, options)
45
+ add_processor(post, options)
46
+ add_eci(post, options)
47
+ commit('sale', money, post)
48
+ end
49
+
50
+ def capture(money, authorization, options = {})
51
+ post ={}
52
+ post[:transactionid] = authorization
53
+ commit('capture', money, post)
54
+ end
55
+
56
+ def void(authorization, options = {})
57
+ post ={}
58
+ post[:transactionid] = authorization
59
+ commit('void', nil, post)
60
+ end
61
+
62
+ def credit(money, payment_source, options = {})
63
+ post = {}
64
+ add_invoice(post, options)
65
+ add_payment_source(post, payment_source, options)
66
+ add_address(post, options[:billing_address] || options[:address])
67
+ add_customer_data(post, options)
68
+ add_sku(post,options)
69
+ add_currency(post, money, options)
70
+ add_processor(post, options)
71
+ commit('credit', money, post)
72
+ end
73
+
74
+ def refund(money, auth, options = {})
75
+ post = {}
76
+ add_transaction(post, auth)
77
+ commit('refund', money, post)
78
+ end
79
+
80
+ def verify(credit_card, options = {})
81
+ MultiResponse.run(:use_first_response) do |r|
82
+ r.process { authorize(100, credit_card, options) }
83
+ r.process(:ignore_result) { void(r.authorization, options) }
84
+ end
85
+ end
86
+
87
+ # Update the values (such as CC expiration) stored at
88
+ # the gateway. The CC number must be supplied in the
89
+ # CreditCard object.
90
+ def update(vault_id, creditcard, options = {})
91
+ post = {}
92
+ post[:customer_vault] = "update_customer"
93
+ add_customer_vault_id(post, vault_id)
94
+ add_creditcard(post, creditcard, options)
95
+ add_address(post, options[:billing_address] || options[:address])
96
+ add_customer_data(post, options)
97
+
98
+ commit(nil, nil, post)
99
+ end
100
+
101
+ # Amend an existing transaction
102
+ def amend(auth, options = {})
103
+ post = {}
104
+ add_invoice(post, options)
105
+ add_transaction(post, auth)
106
+ commit('update', nil, post)
107
+ end
108
+
109
+
110
+ def delete(vault_id)
111
+ post = {}
112
+ post[:customer_vault] = "delete_customer"
113
+ add_customer_vault_id(post, vault_id)
114
+ commit(nil, nil, post)
115
+ end
116
+
117
+ # To match the other stored-value gateways, like TrustCommerce,
118
+ # store and unstore need to be defined
119
+ def store(payment_source, options = {})
120
+ post = {}
121
+ billing_id = options.delete(:billing_id).to_s || true
122
+ add_payment_source(post, payment_source, :store => billing_id)
123
+ add_address(post, options[:billing_address] || options[:address])
124
+ add_customer_data(post, options)
125
+ commit(nil, nil, post)
126
+ end
127
+
128
+ alias_method :unstore, :delete
129
+
130
+ private
131
+ def add_customer_data(post, options)
132
+ if options.has_key? :email
133
+ post[:email] = options[:email]
134
+ end
135
+
136
+ if options.has_key? :ip
137
+ post[:ipaddress] = options[:ip]
138
+ end
139
+ end
140
+
141
+ def add_address(post, address,prefix="")
142
+ prefix +="_" unless prefix.blank?
143
+ unless address.blank? or address.values.blank?
144
+ post[prefix+"address1"] = address[:address1].to_s
145
+ post[prefix+"address2"] = address[:address2].to_s unless address[:address2].blank?
146
+ post[prefix+"company"] = address[:company].to_s
147
+ post[prefix+"phone"] = address[:phone].to_s
148
+ post[prefix+"zip"] = address[:zip].to_s
149
+ post[prefix+"city"] = address[:city].to_s
150
+ post[prefix+"country"] = address[:country].to_s
151
+ post[prefix+"state"] = address[:state].blank? ? 'n/a' : address[:state]
152
+ end
153
+ end
154
+
155
+ def add_currency(post, money, options)
156
+ post[:currency] = options[:currency] || currency(money)
157
+ end
158
+
159
+ def add_taxes(post, options)
160
+ post[:tax] = amount(options[:tax])
161
+ end
162
+
163
+ def add_processor(post, options)
164
+ post[:processor] = options[:processor] unless options[:processor].nil?
165
+ end
166
+
167
+ def add_invoice(post, options)
168
+ post[:orderid] = options[:order_id].to_s.gsub(/[^\w.]/, '')
169
+ end
170
+
171
+ def add_payment_source(params, source, options={})
172
+ case determine_funding_source(source)
173
+ when :vault then add_customer_vault_id(params, source)
174
+ when :credit_card then add_creditcard(params, source, options)
175
+ when :check then add_check(params, source, options)
176
+ end
177
+ end
178
+
179
+ def add_customer_vault_id(params, vault_id)
180
+ params[:customer_vault_id] = vault_id
181
+ end
182
+
183
+ def add_creditcard(post, creditcard, options)
184
+ if options[:store]
185
+ post[:customer_vault] = "add_customer"
186
+ post[:customer_vault_id] = options[:store] unless options[:store] == true
187
+ end
188
+ post[:ccnumber] = creditcard.number
189
+ post[:cvv] = creditcard.verification_value if creditcard.verification_value?
190
+ post[:ccexp] = expdate(creditcard)
191
+ post[:firstname] = creditcard.first_name
192
+ post[:lastname] = creditcard.last_name
193
+ end
194
+
195
+ def add_check(post, check, options)
196
+ if options[:store]
197
+ post[:customer_vault] = "add_customer"
198
+ post[:customer_vault_id] = options[:store] unless options[:store] == true
199
+ end
200
+
201
+ post[:payment] = 'check' # Set transaction to ACH
202
+ post[:checkname] = check.name # The name on the customer's Checking Account
203
+ post[:checkaba] = check.routing_number # The customer's bank routing number
204
+ post[:checkaccount] = check.account_number # The customer's account number
205
+ post[:account_holder_type] = check.account_holder_type # The customer's type of ACH account
206
+ post[:account_type] = check.account_type # The customer's type of ACH account
207
+ end
208
+
209
+ def add_sku(post,options)
210
+ post["product_sku_#"] = options[:sku] || options["product_sku_#"]
211
+ end
212
+
213
+ def add_transaction(post, auth)
214
+ post[:transactionid] = auth
215
+ end
216
+
217
+ def add_eci(post, options)
218
+ post[:billing_method] = options[:eci] if options[:eci]
219
+ end
220
+
221
+ def parse(body)
222
+ results = {}
223
+ body.split(/&/).each do |pair|
224
+ key,val = pair.split(/=/)
225
+ results[key] = val
226
+ end
227
+
228
+ results
229
+ end
230
+
231
+ def commit(action, money, parameters)
232
+ parameters[:amount] = amount(money) if money
233
+ response = parse( ssl_post(self.live_url, post_data(action,parameters)) )
234
+ Response.new(response["response"] == "1", message_from(response), response,
235
+ :authorization => (response["transactionid"] || response["customer_vault_id"]),
236
+ :test => test?,
237
+ :cvv_result => response["cvvresponse"],
238
+ :avs_result => { :code => response["avsresponse"] }
239
+ )
240
+
241
+ end
242
+
243
+ def expdate(creditcard)
244
+ year = sprintf("%.04i", creditcard.year)
245
+ month = sprintf("%.02i", creditcard.month)
246
+
247
+ "#{month}#{year[-2..-1]}"
248
+ end
249
+
250
+
251
+ def message_from(response)
252
+ case response["responsetext"]
253
+ when "SUCCESS", "Approved", nil # This is dubious, but responses from UPDATE are nil.
254
+ "This transaction has been approved"
255
+ when "DECLINE"
256
+ "This transaction has been declined"
257
+ else
258
+ response["responsetext"]
259
+ end
260
+ end
261
+
262
+ def post_data(action, parameters = {})
263
+ post = {}
264
+ post[:username] = @options[:login]
265
+ post[:password] = @options[:password]
266
+ post[:type] = action if action
267
+
268
+ request = post.merge(parameters).map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
269
+ request
270
+ end
271
+
272
+ def determine_funding_source(source)
273
+ case
274
+ when source.is_a?(String) then :vault
275
+ when CreditCard.card_companies.keys.include?(card_brand(source)) then :credit_card
276
+ when card_brand(source) == 'check' then :check
277
+ else raise ArgumentError, "Unsupported funding source provided"
278
+ end
279
+ end
280
+ end
281
+ end
282
+ end
283
+
@@ -0,0 +1,194 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class SoEasyPayGateway < Gateway
4
+ self.live_url = self.test_url = 'https://secure.soeasypay.com/gateway.asmx'
5
+ self.money_format = :cents
6
+
7
+ self.supported_countries = [
8
+ 'US', 'CA', 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE',
9
+ 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU',
10
+ 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB',
11
+ 'IS', 'NO', 'CH'
12
+ ]
13
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :maestro, :jcb, :solo, :diners_club]
14
+ self.homepage_url = 'http://www.soeasypay.com/'
15
+ self.display_name = 'SoEasyPay'
16
+
17
+ def initialize(options = {})
18
+ requires!(options, :login, :password)
19
+ super
20
+ end
21
+
22
+ def authorize(money, payment_source, options = {})
23
+ if payment_source.respond_to?(:number)
24
+ commit('AuthorizeTransaction', do_authorization(money, payment_source, options), options)
25
+ else
26
+ commit('ReauthorizeTransaction', do_reauthorization(money, payment_source, options), options)
27
+ end
28
+ end
29
+
30
+ def purchase(money, payment_source, options = {})
31
+ if payment_source.respond_to?(:number)
32
+ commit('SaleTransaction', do_sale(money, payment_source, options), options)
33
+ else
34
+ commit('RebillTransaction', do_rebill(money, payment_source, options), options)
35
+ end
36
+ end
37
+
38
+ def capture(money, authorization, options = {})
39
+ commit('CaptureTransaction', do_capture(money, authorization, options), options)
40
+ end
41
+
42
+ def refund(money, authorization, options={})
43
+ commit('RefundTransaction', do_refund(money, authorization, options), options)
44
+ end
45
+
46
+ def void(authorization, options={})
47
+ commit('CancelTransaction', do_void(authorization, options), options)
48
+ end
49
+
50
+ private
51
+
52
+ def do_authorization(money, card, options)
53
+ build_soap('AuthorizeTransaction') do |soap|
54
+ fill_credentials(soap, options)
55
+ fill_order_info(soap, money, options)
56
+ fill_cardholder(soap, card, options)
57
+ fill_card(soap, card)
58
+ end
59
+ end
60
+
61
+ def do_sale(money, card, options)
62
+ build_soap('SaleTransaction') do |soap|
63
+ fill_credentials(soap, options)
64
+ fill_order_info(soap, money, options)
65
+ fill_cardholder(soap, card, options)
66
+ fill_card(soap, card)
67
+ end
68
+ end
69
+
70
+ def do_reauthorization(money, authorization, options)
71
+ build_soap('ReauthorizeTransaction') do |soap|
72
+ fill_credentials(soap, options)
73
+ fill_order_info(soap, money, options)
74
+ fill_transaction_id(soap, authorization)
75
+ end
76
+ end
77
+
78
+ def do_rebill(money, authorization, options)
79
+ build_soap('RebillTransaction') do |soap|
80
+ fill_credentials(soap, options)
81
+ fill_order_info(soap, money, options)
82
+ fill_transaction_id(soap, authorization)
83
+ end
84
+ end
85
+
86
+ def do_capture(money, authorization, options)
87
+ build_soap('CaptureTransaction') do |soap|
88
+ fill_credentials(soap, options)
89
+ fill_order_info(soap, money, options, :no_currency)
90
+ fill_transaction_id(soap, authorization)
91
+ end
92
+ end
93
+
94
+ def do_refund(money, authorization, options)
95
+ build_soap('RefundTransaction') do |soap|
96
+ fill_credentials(soap, options)
97
+ fill_order_info(soap, money, options, :no_currency)
98
+ fill_transaction_id(soap, authorization)
99
+ end
100
+ end
101
+
102
+ def do_void(authorization, options)
103
+ build_soap('CancelTransaction') do |soap|
104
+ fill_credentials(soap, options)
105
+ fill_transaction_id(soap, authorization)
106
+ end
107
+ end
108
+
109
+ def fill_credentials(soap, options)
110
+ soap.tag!('websiteID', @options[:login].to_s)
111
+ soap.tag!('password', @options[:password].to_s)
112
+ end
113
+
114
+ def fill_cardholder(soap, card, options)
115
+ ch_info = options[:billing_address] || options[:address]
116
+
117
+ soap.tag!('customerIP',options[:ip].to_s)
118
+ name = card.name || ch_info[:name]
119
+ soap.tag!('cardHolderName', name.to_s)
120
+ address = ch_info[:address1] || ''
121
+ address << ch_info[:address2] if ch_info[:address2]
122
+ soap.tag!('cardHolderAddress', address.to_s)
123
+ soap.tag!('cardHolderZipcode', ch_info[:zip].to_s)
124
+ soap.tag!('cardHolderCity', ch_info[:city].to_s)
125
+ soap.tag!('cardHolderState', ch_info[:state].to_s)
126
+ soap.tag!('cardHolderCountryCode', ch_info[:country].to_s)
127
+ soap.tag!('cardHolderPhone', ch_info[:phone].to_s)
128
+ soap.tag!('cardHolderEmail', options[:email].to_s)
129
+ end
130
+
131
+ def fill_transaction_id(soap, transaction_id)
132
+ soap.tag!('transactionID', transaction_id.to_s)
133
+ end
134
+
135
+ def fill_card(soap, card)
136
+ soap.tag!('cardNumber', card.number.to_s)
137
+ soap.tag!('cardSecurityCode', card.verification_value.to_s)
138
+ soap.tag!('cardExpireMonth', card.month.to_s.rjust(2, "0"))
139
+ soap.tag!('cardExpireYear', card.year.to_s)
140
+ end
141
+
142
+ def fill_order_info(soap, money, options, skip_currency=false)
143
+ soap.tag!('orderID', options[:order_id].to_s)
144
+ soap.tag!('orderDescription', "Order #{options[:order_id]}")
145
+ soap.tag!('amount', amount(money).to_s)
146
+ soap.tag!('currency', (options[:currency] || currency(money)).to_s) unless skip_currency
147
+ end
148
+
149
+ def parse(response, action)
150
+ result = {}
151
+ document = REXML::Document.new(response)
152
+ response_element = document.root.get_elements("//[@xsi:type='tns:#{action}Response']").first
153
+ response_element.elements.each do |element|
154
+ result[element.name.underscore] = element.text
155
+ end
156
+ result
157
+ end
158
+
159
+ def commit(soap_action, soap, options)
160
+ headers = {"SOAPAction" => "\"urn:Interface##{soap_action}\"",
161
+ "Content-Type" => "text/xml; charset=utf-8"}
162
+ response_string = ssl_post(test? ? self.test_url : self.live_url, soap, headers)
163
+ response = parse(response_string, soap_action)
164
+ return Response.new(response['errorcode'] == '000',
165
+ response['errormessage'],
166
+ response,
167
+ :test => test?,
168
+ :authorization => response['transaction_id'])
169
+ end
170
+
171
+ def build_soap(request)
172
+ retval = Builder::XmlMarkup.new(:indent => 2)
173
+ retval.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
174
+ retval.tag!('soap:Envelope', {
175
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
176
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
177
+ 'xmlns:soapenc' => 'http://schemas.xmlsoap.org/soap/encoding/',
178
+ 'xmlns:tns' => 'urn:Interface',
179
+ 'xmlns:types' => 'urn:Interface/encodedTypes',
180
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'}) do
181
+ retval.tag!('soap:Body', {'soap:encodingStyle'=>'http://schemas.xmlsoap.org/soap/encoding/'}) do
182
+ retval.tag!("tns:#{request}") do
183
+ retval.tag!("#{request}Request", {'xsi:type'=>"tns:#{request}Request"}) do
184
+ yield retval
185
+ end
186
+ end
187
+ end
188
+ end
189
+ retval.target!
190
+ end
191
+
192
+ end
193
+ end
194
+ end