jelaniharris-activemerchant 1.24.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. data/CHANGELOG +893 -0
  2. data/CONTRIBUTORS +307 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +196 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant.rb +63 -0
  7. data/lib/active_merchant/billing.rb +9 -0
  8. data/lib/active_merchant/billing/avs_result.rb +98 -0
  9. data/lib/active_merchant/billing/base.rb +57 -0
  10. data/lib/active_merchant/billing/check.rb +68 -0
  11. data/lib/active_merchant/billing/credit_card.rb +274 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +143 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  15. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  16. data/lib/active_merchant/billing/gateway.rb +170 -0
  17. data/lib/active_merchant/billing/gateways.rb +18 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +694 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +946 -0
  20. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  21. data/lib/active_merchant/billing/gateways/beanstream.rb +167 -0
  22. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +388 -0
  23. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  24. data/lib/active_merchant/billing/gateways/blue_pay.rb +492 -0
  25. data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
  26. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  27. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  28. data/lib/active_merchant/billing/gateways/braintree_blue.rb +335 -0
  29. data/lib/active_merchant/billing/gateways/braintree_orange.rb +21 -0
  30. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  31. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  32. data/lib/active_merchant/billing/gateways/certo_direct.rb +279 -0
  33. data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
  34. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  35. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  36. data/lib/active_merchant/billing/gateways/elavon.rb +137 -0
  37. data/lib/active_merchant/billing/gateways/epay.rb +276 -0
  38. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  39. data/lib/active_merchant/billing/gateways/eway_managed.rb +265 -0
  40. data/lib/active_merchant/billing/gateways/exact.rb +227 -0
  41. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  42. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  43. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  44. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
  45. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  46. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  47. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  48. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  49. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  50. data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
  51. data/lib/active_merchant/billing/gateways/itransact.rb +450 -0
  52. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  53. data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
  54. data/lib/active_merchant/billing/gateways/litle.rb +275 -0
  55. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +157 -0
  56. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  57. data/lib/active_merchant/billing/gateways/migs.rb +259 -0
  58. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  59. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  60. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  61. data/lib/active_merchant/billing/gateways/moneris.rb +250 -0
  62. data/lib/active_merchant/billing/gateways/moneris_us.rb +211 -0
  63. data/lib/active_merchant/billing/gateways/nab_transact.rb +255 -0
  64. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  65. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  66. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  67. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  68. data/lib/active_merchant/billing/gateways/ogone.rb +422 -0
  69. data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
  70. data/lib/active_merchant/billing/gateways/orbital.rb +353 -0
  71. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  72. data/lib/active_merchant/billing/gateways/pay_junction.rb +397 -0
  73. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  74. data/lib/active_merchant/billing/gateways/paybox_direct.rb +199 -0
  75. data/lib/active_merchant/billing/gateways/payflow.rb +266 -0
  76. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +211 -0
  77. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  78. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  79. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  80. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  81. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  82. data/lib/active_merchant/billing/gateways/payment_express.rb +282 -0
  83. data/lib/active_merchant/billing/gateways/paypal.rb +106 -0
  84. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +640 -0
  85. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  86. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +245 -0
  87. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  88. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +43 -0
  89. data/lib/active_merchant/billing/gateways/paypal_express.rb +178 -0
  90. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  91. data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
  92. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  93. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  94. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  95. data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
  96. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  97. data/lib/active_merchant/billing/gateways/quickpay.rb +298 -0
  98. data/lib/active_merchant/billing/gateways/realex.rb +313 -0
  99. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  100. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  101. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  102. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  103. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  104. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  105. data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
  106. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  107. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  108. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  109. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  110. data/lib/active_merchant/billing/gateways/skip_jack.rb +458 -0
  111. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  112. data/lib/active_merchant/billing/gateways/stripe.rb +236 -0
  113. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  114. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  115. data/lib/active_merchant/billing/gateways/trust_commerce.rb +437 -0
  116. data/lib/active_merchant/billing/gateways/usa_epay.rb +23 -0
  117. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
  118. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +202 -0
  119. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  120. data/lib/active_merchant/billing/gateways/viaklix.rb +194 -0
  121. data/lib/active_merchant/billing/gateways/vindicia.rb +359 -0
  122. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  123. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  124. data/lib/active_merchant/billing/integrations.rb +17 -0
  125. data/lib/active_merchant/billing/integrations/action_view_helper.rb +72 -0
  126. data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
  127. data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
  128. data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
  129. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  130. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  131. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  132. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  133. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  134. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  135. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  136. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  137. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  138. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  139. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  140. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  141. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  142. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  143. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  144. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  145. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  146. data/lib/active_merchant/billing/integrations/dotpay.rb +22 -0
  147. data/lib/active_merchant/billing/integrations/dotpay/helper.rb +77 -0
  148. data/lib/active_merchant/billing/integrations/dotpay/notification.rb +86 -0
  149. data/lib/active_merchant/billing/integrations/dotpay/return.rb +11 -0
  150. data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
  151. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
  152. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
  153. data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
  154. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  155. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  156. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  157. data/lib/active_merchant/billing/integrations/epay.rb +21 -0
  158. data/lib/active_merchant/billing/integrations/epay/helper.rb +55 -0
  159. data/lib/active_merchant/billing/integrations/epay/notification.rb +110 -0
  160. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  161. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  162. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  163. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  164. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  165. data/lib/active_merchant/billing/integrations/helper.rb +113 -0
  166. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  167. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  168. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  169. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  170. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  171. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  172. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  173. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  174. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  175. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  176. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  177. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  178. data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
  179. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
  180. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
  181. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  182. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  183. data/lib/active_merchant/billing/integrations/paypal/notification.rb +155 -0
  184. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  185. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  186. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +71 -0
  187. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  188. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  189. data/lib/active_merchant/billing/integrations/robokassa.rb +49 -0
  190. data/lib/active_merchant/billing/integrations/robokassa/common.rb +19 -0
  191. data/lib/active_merchant/billing/integrations/robokassa/helper.rb +50 -0
  192. data/lib/active_merchant/billing/integrations/robokassa/notification.rb +55 -0
  193. data/lib/active_merchant/billing/integrations/robokassa/return.rb +17 -0
  194. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  195. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  196. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +129 -0
  197. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  198. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  199. data/lib/active_merchant/billing/integrations/two_checkout.rb +44 -0
  200. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +91 -0
  201. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +139 -0
  202. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  203. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  204. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  205. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  206. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  207. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  208. data/lib/active_merchant/billing/integrations/verkkomaksut.rb +20 -0
  209. data/lib/active_merchant/billing/integrations/verkkomaksut/helper.rb +87 -0
  210. data/lib/active_merchant/billing/integrations/verkkomaksut/notification.rb +59 -0
  211. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  212. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  213. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  214. data/lib/active_merchant/billing/response.rb +32 -0
  215. data/lib/active_merchant/version.rb +3 -0
  216. data/lib/activemerchant.rb +1 -0
  217. data/lib/support/gateway_support.rb +58 -0
  218. data/lib/support/outbound_hosts.rb +25 -0
  219. metadata +447 -0
@@ -0,0 +1,388 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ module BeanstreamCore
4
+ URL = 'https://www.beanstream.com/scripts/process_transaction.asp'
5
+ RECURRING_URL = 'https://www.beanstream.com/scripts/recurring_billing.asp'
6
+ SECURE_PROFILE_URL = 'https://www.beanstream.com/scripts/payment_profile.asp'
7
+ SP_SERVICE_VERSION = '1.1'
8
+
9
+ TRANSACTIONS = {
10
+ :authorization => 'PA',
11
+ :purchase => 'P',
12
+ :capture => 'PAC',
13
+ :refund => 'R',
14
+ :void => 'VP',
15
+ :check_purchase => 'D',
16
+ :check_refund => 'C',
17
+ :void_purchase => 'VP',
18
+ :void_refund => 'VR'
19
+ }
20
+
21
+ PROFILE_OPERATIONS = {
22
+ :new => 'N',
23
+ :modify => 'M'
24
+ }
25
+
26
+ CVD_CODES = {
27
+ '1' => 'M',
28
+ '2' => 'N',
29
+ '3' => 'I',
30
+ '4' => 'S',
31
+ '5' => 'U',
32
+ '6' => 'P'
33
+ }
34
+
35
+ AVS_CODES = {
36
+ '0' => 'R',
37
+ '5' => 'I',
38
+ '9' => 'I'
39
+ }
40
+
41
+ PERIODS = {
42
+ :days => 'D',
43
+ :weeks => 'W',
44
+ :months => 'M',
45
+ :years => 'Y'
46
+ }
47
+
48
+ PERIODICITIES = {
49
+ :daily => [:days, 1],
50
+ :weekly => [:weeks, 1],
51
+ :biweekly => [:weeks, 2],
52
+ :monthly => [:months, 1],
53
+ :bimonthly => [:months, 2],
54
+ :yearly => [:years, 1]
55
+ }
56
+
57
+ RECURRING_OPERATION = {
58
+ :update => 'M',
59
+ :cancel => 'C'
60
+ }
61
+
62
+ def self.included(base)
63
+ base.default_currency = 'CAD'
64
+
65
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
66
+ base.supported_countries = ['CA']
67
+
68
+ # The card types supported by the payment gateway
69
+ base.supported_cardtypes = [:visa, :master, :american_express]
70
+
71
+ # The homepage URL of the gateway
72
+ base.homepage_url = 'http://www.beanstream.com/'
73
+
74
+ # The name of the gateway
75
+ base.display_name = 'Beanstream.com'
76
+ end
77
+
78
+ # Only <tt>:login</tt> is required by default,
79
+ # which is the merchant's merchant ID. If you'd like to perform void,
80
+ # capture or refund transactions then you'll also need to add a username
81
+ # and password to your account under administration -> account settings ->
82
+ # order settings -> Use username/password validation
83
+ def initialize(options = {})
84
+ requires!(options, :login)
85
+ @options = options
86
+ super
87
+ end
88
+
89
+ def capture(money, authorization, options = {})
90
+ reference, amount, type = split_auth(authorization)
91
+
92
+ post = {}
93
+ add_amount(post, money)
94
+ add_reference(post, reference)
95
+ add_transaction_type(post, :capture)
96
+ commit(post)
97
+ end
98
+
99
+ def refund(money, source, options = {})
100
+ post = {}
101
+ reference, amount, type = split_auth(source)
102
+ add_reference(post, reference)
103
+ add_transaction_type(post, refund_action(type))
104
+ add_amount(post, money)
105
+ commit(post)
106
+ end
107
+
108
+ def credit(money, source, options = {})
109
+ deprecated Gateway::CREDIT_DEPRECATION_MESSAGE
110
+ refund(money, source, options)
111
+ end
112
+
113
+ private
114
+ def purchase_action(source)
115
+ if source.is_a?(Check)
116
+ :check_purchase
117
+ else
118
+ :purchase
119
+ end
120
+ end
121
+
122
+ def void_action(original_transaction_type)
123
+ (original_transaction_type == TRANSACTIONS[:refund]) ? :void_refund : :void_purchase
124
+ end
125
+
126
+ def refund_action(type)
127
+ (type == TRANSACTIONS[:check_purchase]) ? :check_refund : :refund
128
+ end
129
+
130
+ def secure_profile_action(type)
131
+ PROFILE_OPERATIONS[type] || PROFILE_OPERATIONS[:new]
132
+ end
133
+
134
+ def split_auth(string)
135
+ string.split(";")
136
+ end
137
+
138
+ def add_amount(post, money)
139
+ post[:trnAmount] = amount(money)
140
+ end
141
+
142
+ def add_original_amount(post, amount)
143
+ post[:trnAmount] = amount
144
+ end
145
+
146
+ def add_reference(post, reference)
147
+ post[:adjId] = reference
148
+ end
149
+
150
+ def add_address(post, options)
151
+ prepare_address_for_non_american_countries(options)
152
+
153
+ if billing_address = options[:billing_address] || options[:address]
154
+ post[:ordName] = billing_address[:name]
155
+ post[:ordEmailAddress] = options[:email]
156
+ post[:ordPhoneNumber] = billing_address[:phone]
157
+ post[:ordAddress1] = billing_address[:address1]
158
+ post[:ordAddress2] = billing_address[:address2]
159
+ post[:ordCity] = billing_address[:city]
160
+ post[:ordProvince] = billing_address[:state]
161
+ post[:ordPostalCode] = billing_address[:zip]
162
+ post[:ordCountry] = billing_address[:country]
163
+ end
164
+ if shipping_address = options[:shipping_address]
165
+ post[:shipName] = shipping_address[:name]
166
+ post[:shipEmailAddress] = options[:email]
167
+ post[:shipPhoneNumber] = shipping_address[:phone]
168
+ post[:shipAddress1] = shipping_address[:address1]
169
+ post[:shipAddress2] = shipping_address[:address2]
170
+ post[:shipCity] = shipping_address[:city]
171
+ post[:shipProvince] = shipping_address[:state]
172
+ post[:shipPostalCode] = shipping_address[:zip]
173
+ post[:shipCountry] = shipping_address[:country]
174
+ post[:shippingMethod] = shipping_address[:shipping_method]
175
+ post[:deliveryEstimate] = shipping_address[:delivery_estimate]
176
+ end
177
+ end
178
+
179
+ def prepare_address_for_non_american_countries(options)
180
+ [ options[:billing_address], options[:shipping_address] ].compact.each do |address|
181
+ unless ['US', 'CA'].include?(address[:country])
182
+ address[:state] = '--'
183
+ address[:zip] = '000000' unless address[:zip]
184
+ end
185
+ end
186
+ end
187
+
188
+ def add_invoice(post, options)
189
+ post[:trnOrderNumber] = options[:order_id]
190
+ post[:trnComments] = options[:description]
191
+ post[:ordItemPrice] = amount(options[:subtotal])
192
+ post[:ordShippingPrice] = amount(options[:shipping])
193
+ post[:ordTax1Price] = amount(options[:tax1] || options[:tax])
194
+ post[:ordTax2Price] = amount(options[:tax2])
195
+ post[:ref1] = options[:custom]
196
+ end
197
+
198
+ def add_credit_card(post, credit_card)
199
+ if credit_card
200
+ post[:trnCardOwner] = credit_card.name
201
+ post[:trnCardNumber] = credit_card.number
202
+ post[:trnExpMonth] = format(credit_card.month, :two_digits)
203
+ post[:trnExpYear] = format(credit_card.year, :two_digits)
204
+ post[:trnCardCvd] = credit_card.verification_value
205
+ end
206
+ end
207
+
208
+ def add_check(post, check)
209
+ # The institution number of the consumer’s financial institution. Required for Canadian dollar EFT transactions.
210
+ post[:institutionNumber] = check.institution_number
211
+
212
+ # The bank transit number of the consumer’s bank account. Required for Canadian dollar EFT transactions.
213
+ post[:transitNumber] = check.transit_number
214
+
215
+ # The routing number of the consumer’s bank account. Required for US dollar EFT transactions.
216
+ post[:routingNumber] = check.routing_number
217
+
218
+ # The account number of the consumer’s bank account. Required for both Canadian and US dollar EFT transactions.
219
+ post[:accountNumber] = check.account_number
220
+ end
221
+
222
+ def add_secure_profile_variables(post, options = {})
223
+ post[:serviceVersion] = SP_SERVICE_VERSION
224
+ post[:responseFormat] = 'QS'
225
+ post[:cardValidation] = (options[:cardValidation].to_i == 1) || '0'
226
+
227
+ post[:operationType] = options[:operationType] || options[:operation] || secure_profile_action(:new)
228
+ post[:customerCode] = options[:billing_id] || options[:vault_id] || false
229
+ post[:status] = options[:status]
230
+ end
231
+
232
+ def add_recurring_amount(post, money)
233
+ post[:amount] = amount(money)
234
+ end
235
+
236
+ def add_recurring_invoice(post, options)
237
+ post[:rbApplyTax1] = options[:apply_tax1]
238
+ end
239
+
240
+ def add_recurring_operation_type(post, operation)
241
+ post[:operationType] = RECURRING_OPERATION[operation]
242
+ end
243
+
244
+ def add_recurring_service(post, options)
245
+ post[:serviceVersion] = '1.0'
246
+ post[:merchantId] = @options[:login]
247
+ post[:passCode] = @options[:recurring_api_key]
248
+ post[:rbAccountId] = options[:account_id]
249
+ end
250
+
251
+ def add_recurring_type(post, options)
252
+ # XXX requires!
253
+ post[:trnRecurring] = 1
254
+ period, increment = interval(options)
255
+ post[:rbBillingPeriod] = PERIODS[period]
256
+ post[:rbBillingIncrement] = increment
257
+
258
+ if options.include? :start_date
259
+ post[:rbCharge] = 0
260
+ post[:rbFirstBilling] = options[:start_date].strftime('%m%d%Y')
261
+ end
262
+
263
+ if count = options[:occurrences] || options[:payments]
264
+ post[:rbExpiry] = (options[:start_date] || Date.current).advance(period => count).strftime('%m%d%Y')
265
+ end
266
+ end
267
+
268
+ def interval(options)
269
+ if options.include? :periodicity
270
+ requires!(options, [:periodicity, *PERIODICITIES.keys])
271
+ PERIODICITIES[options[:periodicity]]
272
+ elsif options.include? :interval
273
+ interval = options[:interval]
274
+ if interval.respond_to? :parts
275
+ parts = interval.parts
276
+ raise ArgumentError.new("Cannot recur with mixed interval (#{interval}). Use only one of: days, weeks, months or years") if parts.length > 1
277
+ parts.first
278
+ elsif interval.kind_of? Hash
279
+ requires!(interval, :unit)
280
+ unit, length = interval.values_at(:unit, :length)
281
+ length ||= 1
282
+ [unit, length]
283
+ end
284
+ end
285
+ end
286
+
287
+ def parse(body)
288
+ results = {}
289
+ if !body.nil?
290
+ body.split(/&/).each do |pair|
291
+ key, val = pair.split(/=/)
292
+ results[key.to_sym] = val.nil? ? nil : CGI.unescape(val)
293
+ end
294
+ end
295
+
296
+ # Clean up the message text if there is any
297
+ if results[:messageText]
298
+ results[:messageText].gsub!(/<LI>/, "")
299
+ results[:messageText].gsub!(/(\.)?<br>/, ". ")
300
+ results[:messageText].strip!
301
+ end
302
+
303
+ results
304
+ end
305
+
306
+ def recurring_parse(data)
307
+ REXML::Document.new(data).root.elements.to_a.inject({}) do |response, element|
308
+ response[element.name.to_sym] = element.text
309
+ response
310
+ end
311
+ end
312
+
313
+ def commit(params, use_profile_api = false)
314
+ post(post_data(params,use_profile_api),use_profile_api)
315
+ end
316
+
317
+ def recurring_commit(params)
318
+ recurring_post(post_data(params, false))
319
+ end
320
+
321
+ def post(data, use_profile_api=nil)
322
+ response = parse(ssl_post((use_profile_api ? SECURE_PROFILE_URL : URL), data))
323
+ response[:customer_vault_id] = response[:customerCode] if response[:customerCode]
324
+ build_response(success?(response), message_from(response), response,
325
+ :test => test? || response[:authCode] == "TEST",
326
+ :authorization => authorization_from(response),
327
+ :cvv_result => CVD_CODES[response[:cvdId]],
328
+ :avs_result => { :code => (AVS_CODES.include? response[:avsId]) ? AVS_CODES[response[:avsId]] : response[:avsId] }
329
+ )
330
+ end
331
+
332
+ def recurring_post(data)
333
+ response = recurring_parse(ssl_post(RECURRING_URL, data))
334
+ build_response(recurring_success?(response), recurring_message_from(response), response)
335
+ end
336
+
337
+ def authorization_from(response)
338
+ "#{response[:trnId]};#{response[:trnAmount]};#{response[:trnType]}"
339
+ end
340
+
341
+ def message_from(response)
342
+ response[:messageText] || response[:responseMessage]
343
+ end
344
+
345
+ def recurring_message_from(response)
346
+ response[:message]
347
+ end
348
+
349
+ def success?(response)
350
+ response[:responseType] == 'R' || response[:trnApproved] == '1' || response[:responseCode] == '1'
351
+ end
352
+
353
+ def recurring_success?(response)
354
+ response[:code] == '1'
355
+ end
356
+
357
+ def add_source(post, source)
358
+ if source.is_a?(String) or source.is_a?(Integer)
359
+ post[:customerCode] = source
360
+ else
361
+ card_brand(source) == "check" ? add_check(post, source) : add_credit_card(post, source)
362
+ end
363
+ end
364
+
365
+ def add_transaction_type(post, action)
366
+ post[:trnType] = TRANSACTIONS[action]
367
+ end
368
+
369
+ def post_data(params, use_profile_api)
370
+ params[:requestType] = 'BACKEND'
371
+ if use_profile_api
372
+ params[:merchantId] = @options[:login]
373
+ params[:passCode] = @options[:secure_profile_api_key]
374
+ else
375
+ params[:username] = @options[:user] if @options[:user]
376
+ params[:password] = @options[:password] if @options[:password]
377
+ params[:merchant_id] = @options[:login]
378
+ end
379
+ params[:vbvEnabled] = '0'
380
+ params[:scEnabled] = '0'
381
+
382
+ params.reject{|k, v| v.blank?}.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
383
+ end
384
+
385
+ end
386
+ end
387
+ end
388
+
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/beanstream/beanstream_core'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class BeanstreamInteracResponse < Response
6
+ def redirect
7
+ params['pageContents']
8
+ end
9
+ end
10
+
11
+ class BeanstreamInteracGateway < Gateway
12
+ include BeanstreamCore
13
+
14
+ # Confirm a transaction posted back from the bank to Beanstream.
15
+ # Confirming a transaction does not require any credentials,
16
+ # and in an application with many merchants sharing a funded
17
+ # URL the application may not yet know which merchant the
18
+ # post back is for until the response of the confirmation is
19
+ # received, which contains the order number.
20
+ def self.confirm(transaction)
21
+ gateway = new(:login => '')
22
+ gateway.confirm(transaction)
23
+ end
24
+
25
+ def purchase(money, options = {})
26
+ post = {}
27
+ add_amount(post, money)
28
+ add_invoice(post, options)
29
+ add_address(post, options)
30
+ add_interac_details(post, options)
31
+ add_transaction_type(post, :purchase)
32
+ commit(post)
33
+ end
34
+
35
+ # Confirm a transaction posted back from the bank to Beanstream.
36
+ def confirm(transaction)
37
+ post(transaction)
38
+ end
39
+
40
+ private
41
+
42
+ def add_interac_details(post, options)
43
+ address = options[:billing_address] || options[:address] || {}
44
+ post[:trnCardOwner] = address[:name]
45
+ post[:paymentMethod] = 'IO'
46
+ end
47
+
48
+ def build_response(*args)
49
+ BeanstreamInteracResponse.new(*args)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,492 @@
1
+ require 'digest/md5'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class BluePayGateway < Gateway
6
+ class_attribute :live_url, :rebilling_url, :ignore_http_status
7
+
8
+ self.live_url = 'https://secure.bluepay.com/interfaces/bp20post'
9
+ self.rebilling_url = 'https://secure.bluepay.com/interfaces/bp20rebadmin'
10
+
11
+ self.ignore_http_status = true
12
+
13
+ RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
14
+ AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38
15
+
16
+ CARD_CODE_ERRORS = %w( N S )
17
+ AVS_ERRORS = %w( A E N R W Z )
18
+ AVS_REASON_CODES = %w(27 45)
19
+
20
+ class_attribute :duplicate_window
21
+
22
+ self.supported_countries = ['US']
23
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
24
+ self.homepage_url = 'http://www.bluepay.com/'
25
+ self.display_name = 'BluePay'
26
+ self.money_format = :dollars
27
+
28
+
29
+ # Creates a new BluepayGateway
30
+ #
31
+ # The gateway requires that a valid Account ID and Secret Key be passed
32
+ # in the +options+ hash.
33
+ #
34
+ # ==== Options
35
+ #
36
+ # * <tt>:account_id</tt> -- The BluePay gateway Account ID (REQUIRED)
37
+ # * <tt>:secret_key</tt> -- The BluePay gateway Secret Key (REQUIRED)
38
+ # * <tt>:test</tt> -- set to true for TEST mode or false for LIVE mode
39
+ def initialize(options = {})
40
+ requires!(options, :login, :password)
41
+ @options = options
42
+ super
43
+ end
44
+
45
+ # Performs an authorization, which reserves the funds on the customer's credit card. This does not actually take funds from the customer
46
+ # This is referred to an AUTH transaction in BluePay
47
+ #
48
+ # ==== Parameters
49
+ #
50
+ # * <tt>money</tt> -- The amount to be authorized as an Integer value in cents.
51
+ # * <tt>payment_object</tt> -- This can either be one of three things:
52
+ # A CreditCard object,
53
+ # A Check object,
54
+ # or a token. The token is called the Master ID. This is a unique transaction ID returned from a previous transaction. This token associates all the stored information for a previous transaction.
55
+ # * <tt>options</tt> -- A hash of optional parameters.
56
+ def authorize(money, payment_object, options = {})
57
+ post = {}
58
+ post[:MASTER_ID] = ''
59
+ if payment_object != nil && payment_object.class() != String
60
+ payment_object.class() == ActiveMerchant::Billing::Check ?
61
+ add_check(post, payment_object) :
62
+ add_creditcard(post, payment_object)
63
+ else
64
+ post[:MASTER_ID] = payment_object
65
+ end
66
+ add_invoice(post, options)
67
+ add_address(post, options)
68
+ add_customer_data(post, options)
69
+ if options[:rebill] != nil
70
+ post[:DO_REBILL] = '1'
71
+ post[:REB_AMOUNT] = amount(options[:rebill_amount])
72
+ post[:REB_FIRST_DATE] = options[:rebill_start_date]
73
+ post[:REB_EXPR] = options[:rebill_expression]
74
+ post[:REB_CYCLES] = options[:rebill_cycles]
75
+ end
76
+ post[:TRANS_TYPE] = 'AUTH'
77
+ commit('AUTH_ONLY', money, post)
78
+ end
79
+
80
+ # Perform a purchase, which is essentially an authorization and capture in a single operation.
81
+ # This is referred to a SALE transaction in BluePay
82
+ #
83
+ # ==== Parameters
84
+ #
85
+ # * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
86
+ # * <tt>payment_object</tt> -- This can either be one of three things:
87
+ # A CreditCard object,
88
+ # A Check object,
89
+ # or a token. The token is called the Master ID. This is a unique transaction ID returned from a previous transaction. This token associates all the stored information for a previous transaction.
90
+ # * <tt>options</tt> -- A hash of optional parameters.,
91
+ def purchase(money, payment_object, options = {})
92
+ post = {}
93
+ post[:MASTER_ID] = ''
94
+ if payment_object != nil && payment_object.class() != String
95
+ payment_object.class() == ActiveMerchant::Billing::Check ?
96
+ add_check(post, payment_object) :
97
+ add_creditcard(post, payment_object)
98
+ else
99
+ post[:MASTER_ID] = payment_object
100
+ end
101
+ add_invoice(post, options)
102
+ add_address(post, options)
103
+ add_customer_data(post, options)
104
+ if options[:rebill] != nil
105
+ post[:DO_REBILL] = '1'
106
+ post[:REB_AMOUNT] = amount(options[:rebill_amount])
107
+ post[:REB_FIRST_DATE] = options[:rebill_start_date]
108
+ post[:REB_EXPR] = options[:rebill_expression]
109
+ post[:REB_CYCLES] = options[:rebill_cycles]
110
+ end
111
+ post[:TRANS_TYPE] = 'SALE'
112
+ commit('AUTH_CAPTURE', money, post)
113
+ end
114
+
115
+ # Captures the funds from an authorize transaction.
116
+ # This is referred to a CAPTURE transaction in BluePay
117
+ #
118
+ # ==== Parameters
119
+ #
120
+ # * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
121
+ # * <tt>identification</tt> -- The Master ID, or token, returned from the previous authorize transaction.
122
+ def capture(money, identification, options = {})
123
+ post = {}
124
+ add_address(post, options)
125
+ add_customer_data(post, options)
126
+ post[:MASTER_ID] = identification
127
+ post[:TRANS_TYPE] = 'CAPTURE'
128
+ commit('PRIOR_AUTH_CAPTURE', money, post)
129
+ end
130
+
131
+ # Void a previous transaction
132
+ # This is referred to a VOID transaction in BluePay
133
+ #
134
+ # ==== Parameters
135
+ #
136
+ # * <tt>identification</tt> - The Master ID, or token, returned from a previous authorize transaction.
137
+ def void(identification, options = {})
138
+ post = {}
139
+ post[:MASTER_ID] = identification
140
+ post[:TRANS_TYPE] = 'VOID'
141
+ commit('VOID', nil, post)
142
+ end
143
+
144
+ # Performs a credit.
145
+ #
146
+ # This transaction indicates that money should flow from the merchant to the customer.
147
+ #
148
+ # ==== Parameters
149
+ #
150
+ # * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
151
+ # * <tt>payment_object</tt> -- This can either be one of three things:
152
+ # A CreditCard object,
153
+ # A Check object,
154
+ # or a token. The token is called the Master ID. This is a unique transaction ID returned from a previous transaction. This token associates all the stored information for a previous transaction.
155
+ # If the payment_object is a token, then the transaction type will reverse a previous capture or purchase transaction, returning the funds to the customer. If the amount is nil, a full credit will be processed. This is referred to a REFUND transaction in BluePay.
156
+ # If the payment_object is either a CreditCard or Check object, then the transaction type will be an unmatched credit placing funds in the specified account. This is referred to a CREDIT transaction in BluePay.
157
+ # * <tt>options</tt> -- A hash of parameters.
158
+ def refund(money, payment_object, options = {})
159
+ post = {}
160
+ post[:PAYMENT_ACCOUNT] = ''
161
+ if payment_object != nil && payment_object.class() != String
162
+ payment_object.class() == ActiveMerchant::Billing::Check ?
163
+ add_check(post, payment_object) :
164
+ add_creditcard(post, payment_object)
165
+ post[:TRANS_TYPE] = 'CREDIT'
166
+ else
167
+ post[:MASTER_ID] = payment_object
168
+ post[:TRANS_TYPE] = 'REFUND'
169
+ end
170
+
171
+ options[:first_name] ? post[:NAME1] = options[:first_name] : post[:NAME1] = ''
172
+ post[:NAME2] = options[:last_name] if options[:last_name]
173
+ post[:ZIP] = options[:zip] if options[:zip]
174
+ add_invoice(post, options)
175
+ add_address(post, options)
176
+ add_customer_data(post, options)
177
+ commit('CREDIT', money, post)
178
+ end
179
+
180
+ def credit(money, identification, options = {})
181
+ deprecated CREDIT_DEPRECATION_MESSAGE
182
+ refund(money, identification, options)
183
+ end
184
+
185
+ # Create a new recurring payment.
186
+ #
187
+ # ==== Parameters
188
+ #
189
+ # * <tt>money</tt> -- The amount to charge the customer at the time of the recurring payment setup, in cents. Set to zero if you do not want the customer to be charged at this time.
190
+ # * <tt>payment_object</tt> -- This can either be one of three things:
191
+ # A CreditCard object,
192
+ # A Check object,
193
+ # or a token. The token is called the Master ID. This is a unique transaction ID returned from a previous transaction. This token associates all the stored information for a previous transaction.
194
+ # * <tt>options</tt> -- A hash of optional parameters.,
195
+
196
+ # ==== Options
197
+ #
198
+ # * <tt>:rebill_start_date</tt> is a string that tells the gateway when to start the rebill. (REQUIRED)
199
+ # Has two valid formats:
200
+ # "YYYY-MM-DD HH:MM:SS" Hours, minutes, and seconds are optional.
201
+ # "XX UNITS" Relative date as explained below. Marked from the time of the
202
+ # transaction (i.e.: 10 DAYS, 1 MONTH, 1 YEAR)
203
+ # * <tt>:rebill_expression</tt> is the period of time in-between rebillings. (REQUIRED)
204
+ # It uses the same "XX UNITS" format as rebill_start_date, explained above.
205
+ # Optional parameters include:
206
+ # * <tt>rebill_cycles</tt>: Number of times to rebill. Don't send or set to nil for infinite rebillings (or
207
+ # until canceled).
208
+ # * <tt>rebill_amount</tt>: Amount to rebill. Defaults to amount of transaction for rebillings.
209
+ #
210
+ # For example, to charge the customer $19.95 now and then charge $39.95 in 60 days every 3 months for 5 times, the options hash would be as follows:
211
+ # :rebill_start_date => '60 DAYS',
212
+ # :rebill_expression => '3 MONTHS',
213
+ # :rebill_cycles => '5',
214
+ # :rebill_amount => '39.95'
215
+ # A money object of 1995 cents would be passed into the 'money' parameter.
216
+ def recurring(money, payment_object, options = {})
217
+ requires!(options, :rebill_start_date, :rebill_expression)
218
+ options[:rebill] = '1'
219
+ money == nil ? authorize(money, payment_object, options) :
220
+ purchase(money, payment_object, options)
221
+ end
222
+
223
+ # View a recurring payment
224
+ #
225
+ # This will pull data associated with a current recurring billing
226
+ #
227
+ # ==== Parameters
228
+ #
229
+ # * <tt>rebill_id</tt> -- A string containing the rebill_id of the recurring billing that is already active (REQUIRED)
230
+ def status_recurring(rebill_id)
231
+ post = {}
232
+ requires!(rebill_id)
233
+ post[:REBILL_ID] = rebill_id
234
+ post[:TRANS_TYPE] = 'GET'
235
+ commit('rebill', 'nil', post)
236
+ end
237
+
238
+ # Update a recurring payment's details.
239
+ #
240
+ # This transaction updates an existing recurring billing
241
+ #
242
+ # ==== Options
243
+ #
244
+ # * <tt>:rebill_id</tt> -- The 12 digit rebill ID used to update a particular rebilling cycle. (REQUIRED)
245
+ # * <tt>:rebill_amount</tt> -- A string containing the new rebilling amount.
246
+ # * <tt>:rebill_next_date</tt> -- A string containing the new rebilling next date.
247
+ # * <tt>:rebill_expression</tt> -- A string containing the new rebilling expression.
248
+ # * <tt>:rebill_cycles</tt> -- A string containing the new rebilling cycles.
249
+ # * <tt>:rebill_next_amount</tt> -- A string containing the next rebilling amount to charge the customer. This ONLY affects the next scheduled charge; all other rebillings will continue at the regular (rebill_amount) amount.
250
+ # Take a look above at the recurring_payment method for similar examples on how to use.
251
+ def update_recurring(options = {})
252
+ post = {}
253
+ requires!(options, :rebill_id)
254
+ post[:REBILL_ID] = options[:rebill_id]
255
+ post[:TRANS_TYPE] = 'SET'
256
+ post[:REB_AMOUNT] = amount(options[:rebill_amount]) if !options[:rebill_amount].nil?
257
+ post[:NEXT_DATE] = options[:rebill_next_date] if !options[:rebill_next_date].nil?
258
+ post[:REB_EXPR] = options[:rebill_expression] if !options[:rebill_expression].nil?
259
+ post[:REB_CYCLES] = options[:rebill_cycles] if !options[:rebill_cycles].nil?
260
+ post[:NEXT_AMOUNT] = options[:rebill_next_amount] if !options[:rebill_next_amount].nil?
261
+ commit('rebill', 'nil', post)
262
+ end
263
+
264
+ # Cancel a recurring payment.
265
+ #
266
+ # This transaction cancels an existing recurring billing.
267
+ #
268
+ # ==== Parameters
269
+ #
270
+ # * <tt>rebill_id</tt> -- A string containing the rebill_id of the recurring billing that you wish to cancel/stop (REQUIRED)
271
+ def cancel_recurring(rebill_id)
272
+ post = {}
273
+ requires!(rebill_id)
274
+ post[:REBILL_ID] = rebill_id
275
+ post[:TRANS_TYPE] = 'SET'
276
+ post[:STATUS] = 'stopped'
277
+ commit('rebill', 'nil', post)
278
+ end
279
+
280
+ private
281
+
282
+ def commit(action, money, fields)
283
+ fields[:AMOUNT] = amount(money) unless (fields[:TRANS_TYPE] == 'VOID' or action == 'rebill')
284
+ test? == true || @options[:test] == true ? fields[:MODE] = 'TEST' : fields[:MODE] = 'LIVE'
285
+ action == 'rebill' ? begin url = rebilling_url; fields[:TAMPER_PROOF_SEAL] = calc_rebill_tps(fields) end : begin url = live_url; fields[:TAMPER_PROOF_SEAL] = calc_tps(amount(money), fields) end
286
+ fields[:ACCOUNT_ID] = @options[:login]
287
+ data = ssl_post url, post_data(action, fields)
288
+ response = parse(data)
289
+ message = message_from(response)
290
+ test_mode = test? || fields[:MODE] == 'TEST'
291
+ if (response.has_key?('TRANS_ID'))
292
+ response_id = response['TRANS_ID'].to_s()
293
+ elsif (response.has_key?('rebill_id'))
294
+ response_id = response['rebill_id'][0]
295
+ else
296
+ response_id = response[TRANSACTION_ID]
297
+ end
298
+ response.has_key?('AVS') ? avs = response['AVS'] : avs = ''
299
+ response[AVS_RESULT_CODE] != '' ? avs = response[AVS_RESULT_CODE] : avs = ''
300
+ response.has_key?('CVV2') ? cvv2 = response['CVV2'] : cvv2 = ''
301
+ response[CARD_CODE_RESPONSE_CODE] != '' ? cvv2 = response[CARD_CODE_RESPONSE_CODE] : cvv2 = ''
302
+ Response.new(success?(response), message, response,
303
+ :test => test_mode,
304
+ :authorization => response_id,
305
+ :fraud_review => fraud_review?(response),
306
+ :avs_result => { :code => avs },
307
+ :cvv_result => cvv2
308
+ )
309
+ end
310
+
311
+ def success?(response)
312
+ if (response['STATUS'] == '1' || message_from(response) =~ /approved/ || response.has_key?('rebill_id') || response[RESPONSE_REASON_TEXT] =~ /approved/)
313
+ return true
314
+ else
315
+ return false
316
+ end
317
+ end
318
+
319
+ def fraud_review?(response)
320
+ response['STATUS'] == 'E' || response['STATUS'] == '0' || response[RESPONSE_REASON_TEXT] =~ /being reviewed/
321
+ end
322
+
323
+ def get_rebill_id(response)
324
+ return response['REBID'] if response_has.key?('REBID')
325
+ end
326
+
327
+ def parse(body)
328
+ fields = CGI::parse(body)
329
+ if fields.has_key?('MESSAGE') or fields.has_key?('rebill_id')
330
+ if fields.has_key?('MESSAGE')
331
+ fields['MESSAGE'][0] == "Missing ACCOUNT_ID" ? message = "The merchant login ID or password is invalid" : message = fields['MESSAGE']
332
+ fields['MESSAGE'][0] =~ /Approved/ ? message = "This transaction has been approved" : message = fields['MESSAGE'] if message == fields['MESSAGE']
333
+ fields['MESSAGE'][0] =~ /Expired/ ? message = "The credit card has expired" : message = fields['MESSAGE'] if message == fields['MESSAGE']
334
+ fields.delete('MESSAGE')
335
+ end
336
+ fields.has_key?('STATUS') ? begin status = fields['STATUS']; fields.delete('STATUS') end : status = ''
337
+ fields.has_key?('AVS') ? begin avs = fields['AVS']; fields.delete('AVS') end : avs = ''
338
+ fields.has_key?('CVV2') ? begin cvv2 = fields['CVV2']; fields.delete('CVV2') end : cvv2 = ''
339
+ fields.has_key?('MASTER_ID') ? begin trans_id = fields['MASTER_ID']; fields.delete('MASTER_ID') end : trans_id = ''
340
+ fields[:avs_result_code] = avs
341
+ fields[:card_code] = cvv2
342
+ fields[:response_code] = status
343
+ fields[:response_reason_code] = ''
344
+ fields[:response_reason_text] = message
345
+ fields[:transaction_id] = trans_id
346
+ return fields
347
+ end
348
+ # parse response if using other old API
349
+ hash = Hash.new
350
+ fields = fields.first[0].split(",")
351
+ fields.each_index do |x|
352
+ hash[x] = fields[x].tr('$','')
353
+ end
354
+ hash
355
+ end
356
+
357
+ def add_invoice(post, options)
358
+ post[:ORDER_ID] = options[:order_id] if options.has_key? :order_id
359
+ post[:INVOICE_ID] = options[:invoice] if options.has_key? :invoice
360
+ post[:invoice_num] = options[:order_id] if options.has_key? :order_id
361
+ post[:MEMO] = options[:description] if options.has_key? :description
362
+ post[:description] = options[:description] if options.has_key? :description
363
+ end
364
+
365
+ def add_creditcard(post, creditcard)
366
+ post[:PAYMENT_TYPE] = 'CREDIT'
367
+ post[:PAYMENT_ACCOUNT] = creditcard.number
368
+ post[:CARD_CVV2] = creditcard.verification_value if
369
+ creditcard.verification_value?
370
+ post[:CARD_EXPIRE] = expdate(creditcard)
371
+ post[:NAME1] = creditcard.first_name
372
+ post[:NAME2] = creditcard.last_name
373
+ end
374
+
375
+ def add_check(post, check)
376
+ post[:PAYMENT_TYPE] = 'ACH'
377
+ post[:PAYMENT_ACCOUNT] = check.account_type + ":" + check.routing_number + ":" + check.account_number
378
+ post[:NAME1] = check.first_name
379
+ post[:NAME2] = check.last_name
380
+ end
381
+
382
+ def add_customer_data(post, options)
383
+ post[:EMAIL] = options[:email] if options.has_key? :email
384
+ post[:CUSTOM_ID] = options[:customer] if options.has_key? :customer
385
+ end
386
+
387
+ def add_duplicate_window(post)
388
+ unless duplicate_window.nil?
389
+ post[:duplicate_window] = duplicate_window
390
+ post[:DUPLICATE_OVERRIDE] = duplicate_window
391
+ end
392
+ end
393
+
394
+ def add_address(post, options)
395
+ if address = options[:billing_address] || options[:address]
396
+ post[:NAME1] = address[:first_name]
397
+ post[:NAME2] = address[:last_name]
398
+ post[:ADDR1] = address[:address1]
399
+ post[:ADDR2] = address[:address2]
400
+ post[:COMPANY_NAME] = address[:company]
401
+ post[:PHONE] = address[:phone]
402
+ post[:CITY] = address[:city]
403
+ post[:STATE] = address[:state].blank? ? 'n/a' : address[:state]
404
+ post[:ZIP] = address[:zip]
405
+ post[:COUNTRY] = address[:country]
406
+ end
407
+ if address = options[:shipping_address]
408
+ post[:NAME1] = address[:first_name]
409
+ post[:NAME2] = address[:last_name]
410
+ post[:ADDR1] = address[:address1]
411
+ post[:ADDR1] = address[:address1]
412
+ post[:COMPANY_NAME] = address[:company]
413
+ post[:PHONE] = address[:phone]
414
+ post[:ZIP] = address[:zip]
415
+ post[:CITY] = address[:city]
416
+ post[:COUNTRY] = address[:country]
417
+ post[:STATE] = address[:state].blank? ? 'n/a' : address[:state]
418
+ end
419
+ end
420
+
421
+ def post_data(action, parameters = {})
422
+ post = {}
423
+ post[:version] = '3.0'
424
+ post[:login] = ''
425
+ post[:tran_key] = ''
426
+ post[:relay_response] = "FALSE"
427
+ post[:type] = action
428
+ post[:delim_data] = "TRUE"
429
+ post[:delim_char] = ","
430
+ post[:encap_char] = "$"
431
+ post[:card_num] = '4111111111111111'
432
+ post[:exp_date] = '1212'
433
+ post[:solution_ID] = application_id if application_id.present? && application_id != "ActiveMerchant"
434
+ request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
435
+ request
436
+ end
437
+
438
+ def message_from(results)
439
+ if results[:response_code] == 2
440
+ return CVVResult.messages[ results[:card_code] ] if CARD_CODE_ERRORS.include?(results[:card_code])
441
+ if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
442
+ return AVSResult.messages[ results[:avs_result_code] ]
443
+ end
444
+ return (results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
445
+ end
446
+ if results.has_key?(:response_reason_text)
447
+ return results[:response_reason_text].to_s()
448
+ end
449
+ if !results.has_key?('STATUS')
450
+ return results[RESPONSE_REASON_TEXT] ? results[RESPONSE_REASON_TEXT].chomp('.') : ''
451
+ end
452
+ end
453
+
454
+ def expdate(creditcard)
455
+ year = sprintf("%.4i", creditcard.year)
456
+ month = sprintf("%.2i", creditcard.month)
457
+
458
+ "#{month}#{year[-2..-1]}"
459
+ end
460
+
461
+ def calc_tps(amount, post)
462
+ post[:NAME1] = '' if post[:NAME1].nil?
463
+ digest = Digest::MD5.hexdigest(@options[:password] +
464
+ @options[:login] + post[:TRANS_TYPE] +
465
+ amount.to_s() + post[:MASTER_ID].to_s() +
466
+ post[:NAME1].to_s() + post[:PAYMENT_ACCOUNT].to_s())
467
+ return digest
468
+ end
469
+
470
+
471
+ def calc_rebill_tps(post)
472
+ digest = Digest::MD5.hexdigest(@options[:password] +
473
+ @options[:login] + post[:TRANS_TYPE] + post[:REBILL_ID][0].to_s())
474
+ return digest
475
+ end
476
+
477
+ def handle_response(response)
478
+ if ignore_http_status then
479
+ return response.body
480
+ else
481
+ case response.code.to_i
482
+ when 200...300
483
+ response.body
484
+ else
485
+ raise ResponseError.new(response)
486
+ end
487
+ end
488
+ end
489
+
490
+ end
491
+ end
492
+ end