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,254 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+
4
+ class UsaEpayTransactionGateway < Gateway
5
+ self.live_url = 'https://www.usaepay.com/gate'
6
+ self.test_url = 'https://sandbox.usaepay.com/gate'
7
+
8
+ self.supported_cardtypes = [:visa, :master, :american_express]
9
+ self.supported_countries = ['US']
10
+ self.homepage_url = 'http://www.usaepay.com/'
11
+ self.display_name = 'USA ePay'
12
+
13
+ TRANSACTIONS = {
14
+ :authorization => 'cc:authonly',
15
+ :purchase => 'cc:sale',
16
+ :capture => 'cc:capture',
17
+ :refund => 'cc:refund',
18
+ :void => 'cc:void'
19
+ }
20
+
21
+ STANDARD_ERROR_CODE_MAPPING = {
22
+ '00011' => STANDARD_ERROR_CODE[:incorrect_number],
23
+ '00012' => STANDARD_ERROR_CODE[:incorrect_number],
24
+ '00013' => STANDARD_ERROR_CODE[:incorrect_number],
25
+ '00014' => STANDARD_ERROR_CODE[:invalid_number],
26
+ '00015' => STANDARD_ERROR_CODE[:invalid_expiry_date],
27
+ '00016' => STANDARD_ERROR_CODE[:invalid_expiry_date],
28
+ '00017' => STANDARD_ERROR_CODE[:expired_card],
29
+ '10116' => STANDARD_ERROR_CODE[:incorrect_cvc],
30
+ '10107' => STANDARD_ERROR_CODE[:incorrect_zip],
31
+ '10109' => STANDARD_ERROR_CODE[:incorrect_address],
32
+ '10110' => STANDARD_ERROR_CODE[:incorrect_address],
33
+ '10111' => STANDARD_ERROR_CODE[:incorrect_address],
34
+ '10127' => STANDARD_ERROR_CODE[:card_declined],
35
+ '10128' => STANDARD_ERROR_CODE[:processing_error],
36
+ '10132' => STANDARD_ERROR_CODE[:processing_error],
37
+ '00043' => STANDARD_ERROR_CODE[:call_issuer]
38
+ }
39
+
40
+ def initialize(options = {})
41
+ requires!(options, :login)
42
+ super
43
+ end
44
+
45
+ def authorize(money, credit_card, options = {})
46
+ post = {}
47
+
48
+ add_amount(post, money)
49
+ add_invoice(post, options)
50
+ add_credit_card(post, credit_card)
51
+ unless credit_card.track_data.present?
52
+ add_address(post, credit_card, options)
53
+ add_customer_data(post, options)
54
+ end
55
+ add_split_payments(post, options)
56
+
57
+ commit(:authorization, post)
58
+ end
59
+
60
+ def purchase(money, credit_card, options = {})
61
+ post = {}
62
+
63
+ add_amount(post, money)
64
+ add_invoice(post, options)
65
+ add_credit_card(post, credit_card)
66
+ unless credit_card.track_data.present?
67
+ add_address(post, credit_card, options)
68
+ add_customer_data(post, options)
69
+ end
70
+ add_split_payments(post, options)
71
+
72
+ commit(:purchase, post)
73
+ end
74
+
75
+ def capture(money, authorization, options = {})
76
+ post = { :refNum => authorization }
77
+
78
+ add_amount(post, money)
79
+ commit(:capture, post)
80
+ end
81
+
82
+ def refund(money, authorization, options = {})
83
+ post = { :refNum => authorization }
84
+
85
+ add_amount(post, money)
86
+ commit(:refund, post)
87
+ end
88
+
89
+ def verify(creditcard, options = {})
90
+ MultiResponse.run(:use_first_response) do |r|
91
+ r.process { authorize(1, creditcard, options) }
92
+ r.process(:ignore_result) { void(r.authorization, options) }
93
+ end
94
+ end
95
+
96
+ def void(authorization, options = {})
97
+ post = { :refNum => authorization }
98
+ commit(:void, post)
99
+ end
100
+
101
+ private
102
+
103
+ def add_amount(post, money)
104
+ post[:amount] = amount(money)
105
+ end
106
+
107
+ def expdate(credit_card)
108
+ year = format(credit_card.year, :two_digits)
109
+ month = format(credit_card.month, :two_digits)
110
+
111
+ "#{month}#{year}"
112
+ end
113
+
114
+ def add_customer_data(post, options)
115
+ address = options[:billing_address] || options[:address] || {}
116
+ post[:street] = address[:address1]
117
+ post[:zip] = address[:zip]
118
+
119
+ if options.has_key? :email
120
+ post[:custemail] = options[:email]
121
+ post[:custreceipt] = 'No'
122
+ end
123
+
124
+ if options.has_key? :customer
125
+ post[:custid] = options[:customer]
126
+ end
127
+
128
+ if options.has_key? :ip
129
+ post[:ip] = options[:ip]
130
+ end
131
+ end
132
+
133
+ def add_address(post, credit_card, options)
134
+ billing_address = options[:billing_address] || options[:address]
135
+
136
+ add_address_for_type(:billing, post, credit_card, billing_address) if billing_address
137
+ add_address_for_type(:shipping, post, credit_card, options[:shipping_address]) if options[:shipping_address]
138
+ end
139
+
140
+ def add_address_for_type(type, post, credit_card, address)
141
+ prefix = address_key_prefix(type)
142
+
143
+ post[address_key(prefix, 'fname')] = credit_card.first_name
144
+ post[address_key(prefix, 'lname')] = credit_card.last_name
145
+ post[address_key(prefix, 'company')] = address[:company] unless address[:company].blank?
146
+ post[address_key(prefix, 'street')] = address[:address1] unless address[:address1].blank?
147
+ post[address_key(prefix, 'street2')] = address[:address2] unless address[:address2].blank?
148
+ post[address_key(prefix, 'city')] = address[:city] unless address[:city].blank?
149
+ post[address_key(prefix, 'state')] = address[:state] unless address[:state].blank?
150
+ post[address_key(prefix, 'zip')] = address[:zip] unless address[:zip].blank?
151
+ post[address_key(prefix, 'country')] = address[:country] unless address[:country].blank?
152
+ post[address_key(prefix, 'phone')] = address[:phone] unless address[:phone].blank?
153
+ end
154
+
155
+ def address_key_prefix(type)
156
+ case type
157
+ when :shipping then 'ship'
158
+ when :billing then 'bill'
159
+ end
160
+ end
161
+
162
+ def address_key(prefix, key)
163
+ "#{prefix}#{key}".to_sym
164
+ end
165
+
166
+ def add_invoice(post, options)
167
+ post[:invoice] = options[:order_id]
168
+ post[:description] = options[:description]
169
+ end
170
+
171
+ def add_credit_card(post, credit_card)
172
+ if credit_card.track_data.present?
173
+ post[:magstripe] = credit_card.track_data
174
+ post[:cardpresent] = true
175
+ else
176
+ post[:card] = credit_card.number
177
+ post[:cvv2] = credit_card.verification_value if credit_card.verification_value?
178
+ post[:expir] = expdate(credit_card)
179
+ post[:name] = credit_card.name
180
+ end
181
+ end
182
+
183
+ # see: http://wiki.usaepay.com/developer/transactionapi#split_payments
184
+ def add_split_payments(post, options)
185
+ return unless options[:split_payments].is_a?(Array)
186
+ options[:split_payments].each_with_index do |payment, index|
187
+ prefix = '%02d' % (index + 2)
188
+ post["#{prefix}key"] = payment[:key]
189
+ post["#{prefix}amount"] = amount(payment[:amount])
190
+ post["#{prefix}description"] = payment[:description]
191
+ end
192
+
193
+ # When blank it's 'Stop'. 'Continue' is another one
194
+ post['onError'] = options[:on_error] || 'Void'
195
+ end
196
+
197
+ def parse(body)
198
+ fields = {}
199
+ for line in body.split('&')
200
+ key, value = *line.scan( %r{^(\w+)\=(.*)$} ).flatten
201
+ fields[key] = CGI.unescape(value.to_s)
202
+ end
203
+
204
+ {
205
+ :status => fields['UMstatus'],
206
+ :auth_code => fields['UMauthCode'],
207
+ :ref_num => fields['UMrefNum'],
208
+ :batch => fields['UMbatch'],
209
+ :avs_result => fields['UMavsResult'],
210
+ :avs_result_code => fields['UMavsResultCode'],
211
+ :cvv2_result => fields['UMcvv2Result'],
212
+ :cvv2_result_code => fields['UMcvv2ResultCode'],
213
+ :vpas_result_code => fields['UMvpasResultCode'],
214
+ :result => fields['UMresult'],
215
+ :error => fields['UMerror'],
216
+ :error_code => fields['UMerrorcode'],
217
+ :acs_url => fields['UMacsurl'],
218
+ :payload => fields['UMpayload']
219
+ }.delete_if{|k, v| v.nil?}
220
+ end
221
+
222
+ def commit(action, parameters)
223
+ url = (test? ? self.test_url : self.live_url)
224
+ response = parse(ssl_post(url, post_data(action, parameters)))
225
+ Response.new(response[:status] == 'Approved', message_from(response), response,
226
+ :test => test?,
227
+ :authorization => response[:ref_num],
228
+ :cvv_result => response[:cvv2_result_code],
229
+ :avs_result => { :code => response[:avs_result_code] },
230
+ :error_code => STANDARD_ERROR_CODE_MAPPING[response[:error_code]]
231
+ )
232
+ end
233
+
234
+ def message_from(response)
235
+ if response[:status] == "Approved"
236
+ return 'Success'
237
+ else
238
+ return 'Unspecified error' if response[:error].blank?
239
+ return response[:error]
240
+ end
241
+ end
242
+
243
+ def post_data(action, parameters = {})
244
+ parameters[:command] = TRANSACTIONS[action]
245
+ parameters[:key] = @options[:login]
246
+ parameters[:software] = 'Active Merchant'
247
+ parameters[:testmode] = (@options[:test] ? 1 : 0)
248
+
249
+ parameters.collect { |key, value| "UM#{key}=#{CGI.escape(value.to_s)}" }.join("&")
250
+ end
251
+ end
252
+ end
253
+ end
254
+
@@ -0,0 +1,225 @@
1
+ require 'rexml/document'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class VerifiGateway < Gateway
6
+ class VerifiPostData < PostData
7
+ # Fields that will be sent even if they are blank
8
+ self.required_fields = [ :amount, :type, :ccnumber, :ccexp, :firstname, :lastname,
9
+ :company, :address1, :address2, :city, :state, :zip, :country, :phone ]
10
+ end
11
+
12
+ self.live_url = self.test_url = 'https://secure.verifi.com/gw/api/transact.php'
13
+
14
+ RESPONSE_CODE_MESSAGES = {
15
+ "100" => "Transaction was Approved",
16
+ "200" => "Transaction was Declined by Processor",
17
+ "201" => "Do Not Honor",
18
+ "202" => "Insufficient Funds",
19
+ "203" => "Over Limit",
20
+ "204" => "Transaction not allowed",
21
+ "220" => "Incorrect payment Data",
22
+ "221" => "No Such Card Issuer",
23
+ "222" => "No Card Number on file with Issuer",
24
+ "223" => "Expired Card",
25
+ "224" => "Invalid Expiration Date",
26
+ "225" => "Invalid Card Security Code",
27
+ "240" => "Call Issuer for Further Information",
28
+ "250" => "Pick Up Card",
29
+ "251" => "Lost Card",
30
+ "252" => "Stolen Card",
31
+ "253" => "Fraudulent Card",
32
+ "260" => "Declined With further Instructions Available (see response text)",
33
+ "261" => "Declined - Stop All Recurring Payments",
34
+ "262" => "Declined - Stop this Recurring Program",
35
+ "263" => "Declined - Update Cardholder Data Available",
36
+ "264" => "Declined - Retry in a few days",
37
+ "300" => "Transaction was Rejected by Gateway",
38
+ "400" => "Transaction Error Returned by Processor",
39
+ "410" => "Invalid Merchant Configuration",
40
+ "411" => "Merchant Account is Inactive",
41
+ "420" => "Communication Error",
42
+ "421" => "Communication Error with Issuer",
43
+ "430" => "Duplicate Transaction at Processor",
44
+ "440" => "Processor Format Error",
45
+ "441" => "Invalid Transaction Information",
46
+ "460" => "Processor Feature Not Available",
47
+ "461" => "Unsupported Card Type"
48
+ }
49
+
50
+ SUCCESS = 1
51
+
52
+ TRANSACTIONS = {
53
+ :authorization => 'auth',
54
+ :purchase => 'sale',
55
+ :capture => 'capture',
56
+ :void => 'void',
57
+ :credit => 'credit',
58
+ :refund => 'refund'
59
+ }
60
+
61
+ self.supported_countries = ['US']
62
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
63
+ self.homepage_url = 'http://www.verifi.com/'
64
+ self.display_name = 'Verifi'
65
+
66
+ def initialize(options = {})
67
+ requires!(options, :login, :password)
68
+ super
69
+ end
70
+
71
+ def purchase(money, credit_card, options = {})
72
+ sale_authorization_or_credit_template(:purchase, money, credit_card, options)
73
+ end
74
+
75
+ def authorize(money, credit_card, options = {})
76
+ sale_authorization_or_credit_template(:authorization, money, credit_card, options)
77
+ end
78
+
79
+ def capture(money, authorization, options = {})
80
+ capture_void_or_refund_template(:capture, money, authorization, options)
81
+ end
82
+
83
+ def void(authorization, options = {})
84
+ capture_void_or_refund_template(:void, 0, authorization, options)
85
+ end
86
+
87
+ def credit(money, credit_card_or_authorization, options = {})
88
+ if credit_card_or_authorization.is_a?(String)
89
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
90
+ refund(money, credit_card_or_authorization, options)
91
+ else
92
+ sale_authorization_or_credit_template(:credit, money, credit_card_or_authorization, options)
93
+ end
94
+ end
95
+
96
+ def refund(money, reference, options = {})
97
+ capture_void_or_refund_template(:refund, money, reference, options)
98
+ end
99
+
100
+ private
101
+
102
+ def sale_authorization_or_credit_template(trx_type, money, credit_card, options = {})
103
+ post = VerifiPostData.new
104
+ add_security_key_data(post, options, money)
105
+ add_credit_card(post, credit_card)
106
+ add_addresses(post, options)
107
+ add_customer_data(post, options)
108
+ add_invoice_data(post, options)
109
+ add_optional_data(post, options)
110
+ commit(trx_type, money, post)
111
+ end
112
+
113
+ def capture_void_or_refund_template(trx_type, money, authorization, options)
114
+ post = VerifiPostData.new
115
+ post[:transactionid] = authorization
116
+
117
+ commit(trx_type, money, post)
118
+ end
119
+
120
+ def add_credit_card(post, credit_card)
121
+ post[:ccnumber] = credit_card.number
122
+ post[:ccexp] = expdate(credit_card)
123
+ post[:firstname] = credit_card.first_name
124
+ post[:lastname] = credit_card.last_name
125
+ post[:cvv] = credit_card.verification_value
126
+ end
127
+
128
+ def add_addresses(post, options)
129
+ if billing_address = options[:billing_address] || options[:address]
130
+ post[:company] = billing_address[:company]
131
+ post[:address1] = billing_address[:address1]
132
+ post[:address2] = billing_address[:address2]
133
+ post[:city] = billing_address[:city]
134
+ post[:state] = billing_address[:state]
135
+ post[:zip] = billing_address[:zip]
136
+ post[:country] = billing_address[:country]
137
+ post[:phone] = billing_address[:phone]
138
+ post[:fax] = billing_address[:fax]
139
+ end
140
+
141
+ if shipping_address = options[:shipping_address]
142
+ post[:shipping_firstname] = shipping_address[:first_name]
143
+ post[:shipping_lastname] = shipping_address[:last_name]
144
+ post[:shipping_company] = shipping_address[:company]
145
+ post[:shipping_address1] = shipping_address[:address1]
146
+ post[:shipping_address2] = shipping_address[:address2]
147
+ post[:shipping_city] = shipping_address[:city]
148
+ post[:shipping_state] = shipping_address[:state]
149
+ post[:shipping_zip] = shipping_address[:zip]
150
+ post[:shipping_country] = shipping_address[:country]
151
+ post[:shipping_email] = shipping_address[:email]
152
+ end
153
+ end
154
+
155
+ def add_customer_data(post, options)
156
+ post[:email] = options[:email]
157
+ post[:ipaddress] = options[:ip]
158
+ end
159
+
160
+ def add_invoice_data(post, options)
161
+ post[:orderid] = options[:order_id]
162
+ post[:ponumber] = options[:invoice]
163
+ post[:orderdescription] = options[:description]
164
+ post[:tax] = options[:tax]
165
+ post[:shipping] = options[:shipping]
166
+ end
167
+
168
+ def add_optional_data(post, options)
169
+ post[:billing_method] = options[:billing_method]
170
+ post[:website] = options[:website]
171
+ post[:descriptor] = options[:descriptor]
172
+ post[:descriptor_phone] = options[:descriptor_phone]
173
+ post[:cardholder_auth] = options[:cardholder_auth]
174
+ post[:cavv] = options[:cavv]
175
+ post[:xid] = options[:xid]
176
+ post[:customer_receipt] = options[:customer_receipt]
177
+ end
178
+
179
+ def add_security_key_data(post, options, money)
180
+ # MD5(username|password|orderid|amount|time)
181
+ now = Time.now.to_i.to_s
182
+ md5 = Digest::MD5.new
183
+ md5 << @options[:login].to_s + "|"
184
+ md5 << @options[:password].to_s + "|"
185
+ md5 << options[:order_id].to_s + "|"
186
+ md5 << amount(money).to_s + "|"
187
+ md5 << now
188
+ post[:key] = md5.hexdigest
189
+ post[:time] = now
190
+ end
191
+
192
+ def commit(trx_type, money, post)
193
+ post[:amount] = amount(money)
194
+
195
+ response = parse( ssl_post(self.live_url, post_data(trx_type, post)) )
196
+
197
+ Response.new(response[:response].to_i == SUCCESS, message_from(response), response,
198
+ :test => test?,
199
+ :authorization => response[:transactionid],
200
+ :avs_result => { :code => response[:avsresponse] },
201
+ :cvv_result => response[:cvvresponse]
202
+ )
203
+ end
204
+
205
+ def message_from(response)
206
+ response[:response_code_message] ? response[:response_code_message] : ""
207
+ end
208
+
209
+ def parse(body)
210
+ results = {}
211
+ CGI.parse(body).each { |key, value| results[key.intern] = value[0] }
212
+ results[:response_code_message] = RESPONSE_CODE_MESSAGES[results[:response_code]] if results[:response_code]
213
+ results
214
+ end
215
+
216
+ def post_data(trx_type, post)
217
+ post[:username] = @options[:login]
218
+ post[:password] = @options[:password]
219
+ post[:type] = TRANSACTIONS[trx_type]
220
+
221
+ post.to_s
222
+ end
223
+ end
224
+ end
225
+ end