activemerchant 1.2.1 → 1.3.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 (206) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +310 -294
  3. data/CONTRIBUTERS +13 -0
  4. data/README +55 -31
  5. data/Rakefile +21 -13
  6. data/lib/active_merchant.rb +7 -0
  7. data/lib/active_merchant/billing/avs_result.rb +95 -0
  8. data/lib/active_merchant/billing/base.rb +8 -3
  9. data/lib/active_merchant/billing/check.rb +61 -0
  10. data/lib/active_merchant/billing/credit_card.rb +104 -80
  11. data/lib/active_merchant/billing/credit_card_formatting.rb +11 -8
  12. data/lib/active_merchant/billing/credit_card_methods.rb +76 -32
  13. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  14. data/lib/active_merchant/billing/expiry_date.rb +28 -0
  15. data/lib/active_merchant/billing/gateway.rb +47 -111
  16. data/lib/active_merchant/billing/gateways/authorize_net.rb +508 -121
  17. data/lib/active_merchant/billing/gateways/bogus.rb +26 -32
  18. data/lib/active_merchant/billing/gateways/brain_tree.rb +82 -70
  19. data/lib/active_merchant/billing/gateways/card_stream.rb +43 -15
  20. data/lib/active_merchant/billing/gateways/cyber_source.rb +9 -29
  21. data/lib/active_merchant/billing/gateways/data_cash.rb +18 -38
  22. data/lib/active_merchant/billing/gateways/efsnet.rb +23 -50
  23. data/lib/active_merchant/billing/gateways/eway.rb +8 -19
  24. data/lib/active_merchant/billing/gateways/exact.rb +17 -25
  25. data/lib/active_merchant/billing/gateways/linkpoint.rb +18 -25
  26. data/lib/active_merchant/billing/gateways/moneris.rb +9 -39
  27. data/lib/active_merchant/billing/gateways/net_registry.rb +113 -182
  28. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  29. data/lib/active_merchant/billing/gateways/pay_junction.rb +52 -73
  30. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  31. data/lib/active_merchant/billing/gateways/payflow.rb +13 -14
  32. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +55 -37
  33. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +4 -0
  34. data/lib/active_merchant/billing/gateways/payflow_express.rb +2 -4
  35. data/lib/active_merchant/billing/gateways/payment_express.rb +11 -30
  36. data/lib/active_merchant/billing/gateways/paypal.rb +3 -14
  37. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +36 -16
  38. data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -2
  39. data/lib/active_merchant/billing/gateways/plugnpay.rb +7 -15
  40. data/lib/active_merchant/billing/gateways/protx.rb +24 -25
  41. data/lib/active_merchant/billing/gateways/psigate.rb +34 -71
  42. data/lib/active_merchant/billing/gateways/psl_card.rb +24 -19
  43. data/lib/active_merchant/billing/gateways/quickpay.rb +10 -24
  44. data/lib/active_merchant/billing/gateways/realex.rb +7 -19
  45. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  46. data/lib/active_merchant/billing/gateways/skip_jack.rb +437 -0
  47. data/lib/active_merchant/billing/gateways/trans_first.rb +5 -14
  48. data/lib/active_merchant/billing/gateways/trust_commerce.rb +100 -39
  49. data/lib/active_merchant/billing/gateways/usa_epay.rb +60 -55
  50. data/lib/active_merchant/billing/gateways/verifi.rb +32 -39
  51. data/lib/active_merchant/billing/gateways/viaklix.rb +31 -37
  52. data/lib/active_merchant/billing/integrations.rb +2 -0
  53. data/lib/active_merchant/billing/integrations/bogus.rb +5 -0
  54. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  55. data/lib/active_merchant/billing/integrations/chronopay.rb +5 -0
  56. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  57. data/lib/active_merchant/billing/integrations/gestpay.rb +5 -0
  58. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  59. data/lib/active_merchant/billing/integrations/hi_trust.rb +26 -0
  60. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  61. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +57 -0
  62. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  63. data/lib/active_merchant/billing/integrations/nochex.rb +5 -0
  64. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  65. data/lib/active_merchant/billing/integrations/paypal.rb +5 -0
  66. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  67. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  68. data/lib/active_merchant/billing/integrations/two_checkout.rb +5 -0
  69. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  70. data/lib/active_merchant/billing/response.rb +12 -8
  71. data/lib/active_merchant/lib/posts_data.rb +39 -7
  72. data/lib/active_merchant/lib/requires_parameters.rb +2 -3
  73. data/lib/active_merchant/lib/utils.rb +18 -0
  74. data/lib/active_merchant/lib/validateable.rb +3 -3
  75. data/lib/support/gateway_support.rb +22 -9
  76. data/script/destroy +14 -0
  77. data/script/generate +7 -7
  78. data/test/fixtures.yml +25 -3
  79. data/test/remote/gateways/remote_authorize_net_test.rb +145 -0
  80. data/test/remote/gateways/remote_brain_tree_test.rb +118 -0
  81. data/test/{remote_tests → remote/gateways}/remote_card_stream_test.rb +56 -68
  82. data/test/{remote_tests → remote/gateways}/remote_cyber_source_test.rb +21 -32
  83. data/test/{remote_tests → remote/gateways}/remote_data_cash_test.rb +2 -2
  84. data/test/{remote_tests → remote/gateways}/remote_efsnet_test.rb +22 -34
  85. data/test/{remote_tests → remote/gateways}/remote_eway_test.rb +18 -15
  86. data/test/{remote_tests → remote/gateways}/remote_exact_test.rb +20 -19
  87. data/test/{remote_tests → remote/gateways}/remote_linkpoint_test.rb +31 -63
  88. data/test/remote/gateways/remote_moneris_test.rb +82 -0
  89. data/test/{remote_tests → remote/gateways}/remote_net_registry_test.rb +19 -54
  90. data/test/remote/gateways/remote_netbilling_test.rb +70 -0
  91. data/test/{remote_tests → remote/gateways}/remote_pay_junction_test.rb +41 -60
  92. data/test/remote/gateways/remote_pay_secure_test.rb +39 -0
  93. data/test/{remote_tests → remote/gateways}/remote_payflow_express_test.rb +2 -2
  94. data/test/{remote_tests → remote/gateways}/remote_payflow_test.rb +34 -38
  95. data/test/{remote_tests → remote/gateways}/remote_payflow_uk_test.rb +13 -12
  96. data/test/{remote_tests → remote/gateways}/remote_payment_express_test.rb +26 -36
  97. data/test/{remote_tests → remote/gateways}/remote_paypal_express_test.rb +3 -3
  98. data/test/{remote_tests → remote/gateways}/remote_paypal_test.rb +25 -21
  99. data/test/{remote_tests → remote/gateways}/remote_plugnpay_test.rb +18 -16
  100. data/test/{remote_tests → remote/gateways}/remote_protx_test.rb +33 -33
  101. data/test/remote/gateways/remote_psigate_test.rb +50 -0
  102. data/test/{remote_tests → remote/gateways}/remote_psl_card_test.rb +27 -26
  103. data/test/{remote_tests → remote/gateways}/remote_quickpay_test.rb +48 -48
  104. data/test/{remote_tests → remote/gateways}/remote_realex_test.rb +30 -33
  105. data/test/remote/gateways/remote_secure_pay_tech_test.rb +37 -0
  106. data/test/remote/gateways/remote_secure_pay_test.rb +28 -0
  107. data/test/remote/gateways/remote_skipjack_test.rb +105 -0
  108. data/test/{remote_tests → remote/gateways}/remote_trans_first_test.rb +7 -10
  109. data/test/remote/gateways/remote_trust_commerce_test.rb +152 -0
  110. data/test/{remote_tests → remote/gateways}/remote_usa_epay_test.rb +11 -22
  111. data/test/{remote_tests → remote/gateways}/remote_verifi_test.rb +27 -27
  112. data/test/{remote_tests → remote/gateways}/remote_viaklix_test.rb +8 -18
  113. data/test/{remote_tests → remote/integrations}/remote_gestpay_integration_test.rb +1 -1
  114. data/test/{remote_tests → remote/integrations}/remote_paypal_integration_test.rb +1 -1
  115. data/test/test_helper.rb +102 -61
  116. data/test/unit/avs_result_test.rb +59 -0
  117. data/test/unit/base_test.rb +33 -39
  118. data/test/unit/check_test.rb +76 -0
  119. data/test/unit/credit_card_formatting_test.rb +10 -15
  120. data/test/unit/credit_card_methods_test.rb +132 -17
  121. data/test/unit/credit_card_test.rb +157 -228
  122. data/test/unit/cvv_result_test.rb +33 -0
  123. data/test/unit/expiry_date_test.rb +21 -0
  124. data/test/unit/gateways/authorize_net_test.rb +180 -40
  125. data/test/unit/gateways/bogus_test.rb +2 -3
  126. data/test/unit/gateways/brain_tree_test.rb +63 -29
  127. data/test/unit/gateways/card_stream_test.rb +59 -6
  128. data/test/unit/gateways/cyber_source_test.rb +59 -40
  129. data/test/unit/gateways/data_cash_test.rb +82 -1
  130. data/test/unit/gateways/efsnet_test.rb +97 -44
  131. data/test/unit/gateways/eway_test.rb +55 -42
  132. data/test/unit/gateways/exact_test.rb +93 -55
  133. data/test/unit/gateways/gateway_test.rb +7 -0
  134. data/test/unit/gateways/linkpoint_test.rb +60 -58
  135. data/test/unit/gateways/moneris_test.rb +67 -76
  136. data/test/unit/gateways/net_registry_test.rb +351 -419
  137. data/test/unit/gateways/netbilling_test.rb +54 -0
  138. data/test/unit/gateways/pay_junction_test.rb +108 -46
  139. data/test/unit/gateways/pay_secure_test.rb +71 -0
  140. data/test/unit/gateways/payflow_express_test.rb +0 -8
  141. data/test/unit/gateways/payflow_test.rb +136 -65
  142. data/test/unit/gateways/payflow_uk_test.rb +0 -38
  143. data/test/unit/gateways/payment_express_test.rb +31 -51
  144. data/test/unit/gateways/paypal_express_test.rb +8 -2
  145. data/test/unit/gateways/paypal_test.rb +213 -54
  146. data/test/unit/gateways/plugnpay_test.rb +39 -32
  147. data/test/unit/gateways/protx_test.rb +45 -33
  148. data/test/unit/gateways/psigate_test.rb +146 -87
  149. data/test/unit/gateways/psl_card_test.rb +37 -24
  150. data/test/unit/gateways/quickpay_test.rb +33 -46
  151. data/test/unit/gateways/realex_test.rb +32 -31
  152. data/test/unit/gateways/secure_pay_tech_test.rb +44 -0
  153. data/test/unit/gateways/secure_pay_test.rb +35 -26
  154. data/test/unit/gateways/skip_jack_test.rb +125 -0
  155. data/test/unit/gateways/trans_first_test.rb +24 -37
  156. data/test/unit/gateways/trust_commerce_test.rb +47 -26
  157. data/test/unit/gateways/usa_epay_test.rb +52 -41
  158. data/test/unit/gateways/verifi_test.rb +41 -35
  159. data/test/unit/gateways/viaklix_test.rb +38 -32
  160. data/test/unit/generators/test_gateway_generator.rb +46 -0
  161. data/test/unit/generators/test_generator_helper.rb +20 -0
  162. data/test/unit/generators/test_integration_generator.rb +53 -0
  163. data/test/unit/integrations/action_view_helper_test.rb +7 -14
  164. data/test/unit/integrations/bogus_module_test.rb +4 -0
  165. data/test/unit/integrations/chronopay_module_test.rb +4 -0
  166. data/test/unit/integrations/gestpay_module_test.rb +4 -0
  167. data/test/unit/integrations/helpers/hi_trust_helper_test.rb +16 -0
  168. data/test/unit/integrations/hi_trust_module_test.rb +13 -0
  169. data/test/unit/integrations/nochex_module_test.rb +4 -0
  170. data/test/unit/integrations/notifications/hi_trust_notification_test.rb +38 -0
  171. data/test/unit/integrations/paypal_module_test.rb +4 -0
  172. data/test/unit/integrations/returns/chronopay_return_test.rb +11 -0
  173. data/test/unit/integrations/returns/gestpay_return_test.rb +10 -0
  174. data/test/unit/integrations/returns/hi_trust_return_test.rb +24 -0
  175. data/test/unit/integrations/returns/nochex_return_test.rb +10 -0
  176. data/test/unit/integrations/returns/paypal_return_test.rb +10 -0
  177. data/test/unit/integrations/returns/return_test.rb +11 -0
  178. data/test/unit/integrations/returns/two_checkout_return_test.rb +24 -0
  179. data/test/unit/integrations/two_checkout_module_test.rb +4 -0
  180. data/test/unit/posts_data_test.rb +86 -0
  181. data/test/unit/response_test.rb +15 -1
  182. data/test/unit/utils_test.rb +7 -0
  183. data/test/unit/validateable_test.rb +10 -6
  184. metadata +180 -142
  185. metadata.gz.sig +0 -0
  186. data/lib/active_merchant/billing/gateways/paypal/api_cert_chain.crt +0 -35
  187. data/script/generator/base.rb +0 -45
  188. data/script/generator/generator.rb +0 -24
  189. data/script/generator/generators/gateway/gateway_generator.rb +0 -14
  190. data/script/generator/generators/gateway/templates/gateway.rb +0 -73
  191. data/script/generator/generators/gateway/templates/gateway_test.rb +0 -41
  192. data/script/generator/generators/gateway/templates/remote_gateway_test.rb +0 -56
  193. data/script/generator/generators/integration/integration_generator.rb +0 -25
  194. data/script/generator/generators/integration/templates/helper.rb +0 -34
  195. data/script/generator/generators/integration/templates/helper_test.rb +0 -54
  196. data/script/generator/generators/integration/templates/integration.rb +0 -18
  197. data/script/generator/generators/integration/templates/module_test.rb +0 -9
  198. data/script/generator/generators/integration/templates/notification.rb +0 -100
  199. data/script/generator/generators/integration/templates/notification_test.rb +0 -41
  200. data/script/generator/manifest.rb +0 -20
  201. data/test/remote_tests/remote_authorize_net_test.rb +0 -113
  202. data/test/remote_tests/remote_brain_tree_test.rb +0 -78
  203. data/test/remote_tests/remote_moneris_test.rb +0 -110
  204. data/test/remote_tests/remote_psigate_test.rb +0 -87
  205. data/test/remote_tests/remote_secure_pay_test.rb +0 -36
  206. data/test/remote_tests/remote_trust_commerce_test.rb +0 -136
@@ -2,10 +2,6 @@ module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class TransFirstGateway < Gateway
4
4
  URL = 'https://webservices.primerchants.com/creditcard.asmx/CCSale'
5
-
6
- attr_reader :url
7
- attr_reader :response
8
- attr_reader :options
9
5
 
10
6
  self.supported_countries = ['US']
11
7
  self.supported_cardtypes = [:visa, :master, :american_express, :discover]
@@ -94,18 +90,13 @@ module ActiveMerchant #:nodoc:
94
90
  end
95
91
 
96
92
  def commit(params)
97
- if result = test_result_from_cc_number(params[:CardNumber])
98
- return result
99
- end
100
-
101
- data = ssl_post URL, post_data(params)
102
-
103
- @response = parse(data)
104
- success = @response[:status] == "Authorized"
93
+ response = parse( ssl_post(URL, post_data(params)) )
105
94
 
106
- Response.new(success, message_from(@response), @response,
95
+ Response.new(response[:status] == "Authorized", message_from(response), response,
107
96
  :test => test?,
108
- :authorization => @response[:trans_id]
97
+ :authorization => response[:trans_id],
98
+ :avs_result => { :code => response[:avs_code] },
99
+ :cvv_result => response[:cvv2_code]
109
100
  )
110
101
  end
111
102
 
@@ -1,16 +1,11 @@
1
1
  begin
2
2
  require 'tclink'
3
3
  rescue LoadError
4
- # Ignore, but we will fail hard if someone actually tries to use this gateway
4
+ # Falls back to an SSL post to TrustCommerce
5
5
  end
6
6
 
7
7
  module ActiveMerchant #:nodoc:
8
8
  module Billing #:nodoc:
9
-
10
- # To get started using TrustCommerce with active_merchant, download the tclink library from http://www.trustcommerce.com/tclink.html,
11
- # following the instructions available there to get it working on your system. Once it is installed, you should be able to make sure
12
- # that it is visible to your ruby install by opening irb and typing "require 'tclink'", which should return "true".
13
- #
14
9
  # TO USE:
15
10
  # First, make sure you have everything setup correctly and all of your dependencies in place with:
16
11
  #
@@ -56,10 +51,22 @@ module ActiveMerchant #:nodoc:
56
51
  #
57
52
  # response.params["transid"]
58
53
  #
54
+ # For higher performance and failover with the TrustCommerceGateway you can install the TCLink library from http://www.trustcommerce.com/tclink.html.
55
+ # Follow the instructions available there to get it working on your system. ActiveMerchant will automatically use tclink if available.
56
+ #
57
+ # The TCLink library has the following added benefits:
58
+ # * Good transaction times. Transaction duration under 1.2 seconds are common.
59
+ # * Fail-over to geographically distributed servers for extreme reliability
60
+ #
61
+ # Once it is installed, you should be able to make sure
62
+ # that it is visible to your ruby install by opening irb and typing "require 'tclink'", which should return "true".
63
+ #
59
64
  # This should be enough to get you started with Trust Commerce and active_merchant. For further information, review the methods
60
65
  # below and the rest of active_merchant's documentation, as well as Trust Commerce's user and developer documentation.
61
66
 
62
67
  class TrustCommerceGateway < Gateway
68
+ URL = 'https://vault.trustcommerce.com/trans/'
69
+
63
70
  SUCCESS_TYPES = ["approved", "accepted"]
64
71
 
65
72
  DECLINE_CODES = {
@@ -94,17 +101,16 @@ module ActiveMerchant #:nodoc:
94
101
  "failtoprocess" => "The bank servers are offline and unable to authorize transactions"
95
102
  }
96
103
 
97
- # URL
98
- attr_reader :url
99
- attr_reader :response
100
- attr_reader :options
101
-
102
104
  self.money_format = :cents
103
105
  self.supported_cardtypes = [:visa, :master, :discover, :american_express, :diners_club, :jcb]
104
106
  self.supported_countries = ['US']
105
107
  self.homepage_url = 'http://www.trustcommerce.com/'
106
108
  self.display_name = 'TrustCommerce'
107
109
 
110
+ def self.tclink?
111
+ defined?(TCLink)
112
+ end
113
+
108
114
  # Creates a new TrustCommerceGateway
109
115
  #
110
116
  # The gateway requires that a valid login and password be passed
@@ -126,8 +132,12 @@ module ActiveMerchant #:nodoc:
126
132
  super
127
133
  end
128
134
 
135
+ def tclink?
136
+ self.class.tclink?
137
+ end
138
+
129
139
  def test?
130
- @options[:test] || Base.gateway_mode == :test
140
+ @options[:test] || super
131
141
  end
132
142
 
133
143
  # authorize() is the first half of the preauth(authorize)/postauth(capture) model. The TC API docs call this
@@ -140,28 +150,30 @@ module ActiveMerchant #:nodoc:
140
150
  :amount => amount(money),
141
151
  }
142
152
 
153
+ add_order_id(parameters, options)
154
+ add_customer_data(parameters, options)
143
155
  add_payment_source(parameters, creditcard_or_billing_id)
144
- add_address(parameters, options)
156
+ add_addresses(parameters, options)
145
157
  commit('preauth', parameters)
146
158
  end
147
159
 
148
160
  # purchase() is a simple sale. This is one of the most common types of transactions, and is extremely simple. All that you need
149
161
  # to process a purchase are an amount in cents or a money object and a creditcard object or billingid string.
150
-
151
162
  def purchase(money, creditcard_or_billing_id, options = {})
152
163
  parameters = {
153
164
  :amount => amount(money),
154
165
  }
155
166
 
167
+ add_order_id(parameters, options)
168
+ add_customer_data(parameters, options)
156
169
  add_payment_source(parameters, creditcard_or_billing_id)
157
- add_address(parameters, options)
170
+ add_addresses(parameters, options)
158
171
  commit('sale', parameters)
159
172
  end
160
173
 
161
174
  # capture() is the second half of the preauth(authorize)/postauth(capture) model. The TC API docs call this
162
175
  # postauth, we preserve active_merchant's nomenclature of capture() for consistency with the rest of the library. To process
163
176
  # a postauthorization with TC, you need an amount in cents or a money object, and a TC transid.
164
-
165
177
  def capture(money, authorization, options = {})
166
178
  parameters = {
167
179
  :amount => amount(money),
@@ -173,7 +185,6 @@ module ActiveMerchant #:nodoc:
173
185
 
174
186
  # credit() allows you to return money to a card that was previously billed. You need to supply the amount, in cents or a money object,
175
187
  # that you want to refund, and a TC transid for the transaction that you are refunding.
176
-
177
188
  def credit(money, identification, options = {})
178
189
  parameters = {
179
190
  :amount => amount(money),
@@ -183,6 +194,28 @@ module ActiveMerchant #:nodoc:
183
194
  commit('credit', parameters)
184
195
  end
185
196
 
197
+ # void() clears an existing authorization and releases the reserved fund
198
+ # s back to the cardholder. The TC API refers to this transaction as a
199
+ # reversal. After voiding, you will no longer be able to capture funds
200
+ # from this authorization. TrustCommerce seems to always return a status
201
+ # of "accepted" even if the transid you are trying to deauthorize has
202
+ # already been captured. Note: Your account needs to be configured by
203
+ # TrustCommerce to allow for reversal transactions before you can use this
204
+ # method.
205
+ #
206
+ # NOTE: AMEX preauth's cannot be reversed. If you want to clear it more
207
+ # quickly than the automatic expiration (7-10 days), you will have to
208
+ # capture it and then immediately issue a credit for the same amount
209
+ # which should clear the customers credit card with 48 hours according to
210
+ # TC.
211
+ def void(authorization, options = {})
212
+ parameters = {
213
+ :transid => authorization,
214
+ }
215
+
216
+ commit('reversal', parameters)
217
+ end
218
+
186
219
  # recurring() a TrustCommerce account that is activated for Citatdel, TrustCommerce's
187
220
  # hosted customer billing info database.
188
221
  #
@@ -194,7 +227,6 @@ module ActiveMerchant #:nodoc:
194
227
  # gateway.recurring(tendollar, creditcard, :periodicity => :weekly)
195
228
  #
196
229
  # You can optionally specify how long you want payments to continue using 'payments'
197
-
198
230
  def recurring(money, creditcard, options = {})
199
231
  requires!(options, [:periodicity, :bimonthly, :monthly, :biweekly, :weekly, :yearly, :daily] )
200
232
 
@@ -237,7 +269,7 @@ module ActiveMerchant #:nodoc:
237
269
  }
238
270
 
239
271
  add_creditcard(parameters, creditcard)
240
- add_address(parameters, options)
272
+ add_addresses(parameters, options)
241
273
  commit('store', parameters)
242
274
  end
243
275
 
@@ -275,11 +307,20 @@ module ActiveMerchant #:nodoc:
275
307
  params[:cvv] = creditcard.verification_value if creditcard.verification_value?
276
308
  end
277
309
 
310
+ def add_order_id(params, options)
311
+ params[:ticket] = options[:order_id] unless options[:order_id].blank?
312
+ end
313
+
278
314
  def add_billing_id(params, billingid)
279
315
  params[:billingid] = billingid
280
316
  end
281
317
 
282
- def add_address(params, options)
318
+ def add_customer_data(params, options)
319
+ params[:email] = options[:email] unless options[:email].blank?
320
+ params[:ip] = options[:ip] unless options[:ip].blank?
321
+ end
322
+
323
+ def add_addresses(params, options)
283
324
  address = options[:billing_address] || options[:address]
284
325
 
285
326
  if address
@@ -290,7 +331,17 @@ module ActiveMerchant #:nodoc:
290
331
  params[:zip] = address[:zip] unless address[:zip].blank?
291
332
  params[:country] = address[:country] unless address[:country].blank?
292
333
  params[:avs] = 'n'
293
- end
334
+ end
335
+
336
+ if shipping_address = options[:shipping_address]
337
+ params[:shipto_name] = shipping_address[:name] unless shipping_address[:name].blank?
338
+ params[:shipto_address1] = shipping_address[:address1] unless shipping_address[:address1].blank?
339
+ params[:shipto_address2] = shipping_address[:address2] unless shipping_address[:address2].blank?
340
+ params[:shipto_city] = shipping_address[:city] unless shipping_address[:city].blank?
341
+ params[:shipto_state] = shipping_address[:state] unless shipping_address[:state].blank?
342
+ params[:shipto_zip] = shipping_address[:zip] unless shipping_address[:zip].blank?
343
+ params[:shipto_country] = shipping_address[:country] unless shipping_address[:country].blank?
344
+ end
294
345
  end
295
346
 
296
347
  def clean_and_stringify_params(parameters)
@@ -304,35 +355,45 @@ module ActiveMerchant #:nodoc:
304
355
  parameters.delete(key)
305
356
  end
306
357
  end
358
+
359
+ def post_data(parameters)
360
+ parameters.collect { |key, value| "#{key}=#{ CGI.escape(value.to_s)}" }.join("&")
361
+ end
307
362
 
308
363
  def commit(action, parameters)
309
- test = test? || parameters[:test_request]
310
364
  parameters[:custid] = @options[:login]
311
365
  parameters[:password] = @options[:password]
312
- parameters[:demo] = test ? 'y' : 'n'
366
+ parameters[:demo] = test? ? 'y' : 'n'
313
367
  parameters[:action] = action
314
368
 
315
- if result = test_result_from_cc_number(parameters[:cc])
316
- return result
369
+ clean_and_stringify_params(parameters)
370
+
371
+ data = if tclink?
372
+ TCLink.send(parameters)
373
+ else
374
+ parse( ssl_post(URL, post_data(parameters)) )
317
375
  end
318
376
 
319
- begin
320
- clean_and_stringify_params(parameters)
377
+ # to be considered successful, transaction status must be either "approved" or "accepted"
378
+ success = SUCCESS_TYPES.include?(data["status"])
379
+ message = message_from(data)
380
+ Response.new(success, message, data,
381
+ :test => test?,
382
+ :authorization => data["transid"],
383
+ :cvv_result => data["cvv"],
384
+ :avs_result => { :code => data["avs"] }
385
+ )
386
+ end
387
+
388
+ def parse(body)
389
+ results = {}
321
390
 
322
- data = TCLink.send(parameters)
323
- # to be considered successful, transaction status must be either "approved" or "accepted"
324
- success = SUCCESS_TYPES.include?(data["status"])
325
- message = message_from(data)
326
-
327
- Response.new(success, message, data, :test => test, :authorization => data["transid"] )
328
- rescue NameError => e
329
- if e.message =~ /constant TCLink/
330
- raise 'Trust Commerce requires "tclink" library from http://www.trustcommerce.com/tclink.html'
331
- else
332
- raise
333
- end
391
+ body.split(/\n/).each do |pair|
392
+ key,val = pair.split(/=/)
393
+ results[key] = val
334
394
  end
335
395
 
396
+ results
336
397
  end
337
398
 
338
399
  def message_from(data)
@@ -2,54 +2,67 @@ module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
 
4
4
  class UsaEpayGateway < Gateway
5
- GATEWAY_URL = 'https://www.usaepay.com/gate.php'
6
- POST_HEADERS = { 'Content-Type' => 'application/x-www-form-urlencoded' }
7
-
8
- attr_reader :url
9
- attr_reader :response
10
- attr_reader :options
5
+ URL = 'https://www.usaepay.com/gate.php'
11
6
 
12
7
  self.supported_cardtypes = [:visa, :master, :american_express]
13
8
  self.supported_countries = ['US']
14
- self.homepage_url = 'http://www.usa_epay.com/'
9
+ self.homepage_url = 'http://www.usaepay.com/'
15
10
  self.display_name = 'USA ePay'
16
11
 
12
+ TRANSACTIONS = {
13
+ :authorization => 'authonly',
14
+ :purchase => 'sale',
15
+ :capture => 'capture'
16
+ }
17
+
17
18
  def initialize(options = {})
18
19
  requires!(options, :login)
19
20
  @options = options
20
21
  super
21
22
  end
22
23
 
23
- def authorize(money, creditcard, options = {})
24
+ def authorize(money, credit_card, options = {})
24
25
  post = {}
26
+
27
+ add_amount(post, money)
25
28
  add_invoice(post, options)
26
- add_creditcard(post, creditcard)
27
- add_address(post, creditcard, options)
29
+ add_credit_card(post, credit_card)
30
+ add_address(post, credit_card, options)
28
31
  add_customer_data(post, options)
29
32
 
30
- commit('authonly', money, post)
33
+ commit(:authorization, post)
31
34
  end
32
35
 
33
- def purchase(money, creditcard, options = {})
36
+ def purchase(money, credit_card, options = {})
34
37
  post = {}
38
+
39
+ add_amount(post, money)
35
40
  add_invoice(post, options)
36
- add_creditcard(post, creditcard)
37
- add_address(post, creditcard, options)
41
+ add_credit_card(post, credit_card)
42
+ add_address(post, credit_card, options)
38
43
  add_customer_data(post, options)
39
44
 
40
- commit('sale', money, post)
45
+ commit(:purchase, post)
41
46
  end
42
47
 
43
48
  def capture(money, authorization, options = {})
44
- post = {:refNum => authorization}
45
- commit('capture', money, post)
49
+ post = {
50
+ :refNum => authorization
51
+ }
52
+
53
+ add_amount(post, money)
54
+ commit(:capture, post)
46
55
  end
47
56
 
48
57
  private
49
58
 
50
- def expdate(creditcard)
51
- year = format(creditcard.year, :two_digits)
52
- month = format(creditcard.month, :two_digits)
59
+ def add_amount(post, money)
60
+ post[:amount] = amount(money)
61
+ end
62
+
63
+ def expdate(credit_card)
64
+ year = format(credit_card.year, :two_digits)
65
+ month = format(credit_card.month, :two_digits)
53
66
 
54
67
  "#{month}#{year}"
55
68
  end
@@ -73,19 +86,18 @@ module ActiveMerchant #:nodoc:
73
86
  end
74
87
  end
75
88
 
76
- def add_address(post, creditcard, options)
89
+ def add_address(post, credit_card, options)
77
90
  billing_address = options[:billing_address] || options[:address]
78
- shipping_address = options[:shipping_address] || billing_address
79
91
 
80
- add_address_for_type(:billing, post, creditcard, billing_address) unless billing_address.nil?
81
- add_address_for_type(:shipping, post, creditcard, shipping_address) unless shipping_address.nil?
92
+ add_address_for_type(:billing, post, credit_card, billing_address) if billing_address
93
+ add_address_for_type(:shipping, post, credit_card, options[:shipping_address]) if options[:shipping_address]
82
94
  end
83
95
 
84
- def add_address_for_type(type, post, creditcard, address)
96
+ def add_address_for_type(type, post, credit_card, address)
85
97
  prefix = address_key_prefix(type)
86
98
 
87
- post[address_key(prefix, 'fname')] = creditcard.first_name
88
- post[address_key(prefix, 'lname')] = creditcard.last_name
99
+ post[address_key(prefix, 'fname')] = credit_card.first_name
100
+ post[address_key(prefix, 'lname')] = credit_card.last_name
89
101
  post[address_key(prefix, 'company')] = address[:company] unless address[:company].blank?
90
102
  post[address_key(prefix, 'street')] = address[:address1] unless address[:address1].blank?
91
103
  post[address_key(prefix, 'street2')] = address[:address2] unless address[:address2].blank?
@@ -111,11 +123,11 @@ module ActiveMerchant #:nodoc:
111
123
  post[:invoice] = options[:order_id]
112
124
  end
113
125
 
114
- def add_creditcard(post, creditcard)
115
- post[:card] = creditcard.number
116
- post[:cvv2] = creditcard.verification_value if creditcard.verification_value?
117
- post[:expir] = expdate(creditcard)
118
- post[:name] = creditcard.name
126
+ def add_credit_card(post, credit_card)
127
+ post[:card] = credit_card.number
128
+ post[:cvv2] = credit_card.verification_value if credit_card.verification_value?
129
+ post[:expir] = expdate(credit_card)
130
+ post[:name] = credit_card.name
119
131
  end
120
132
 
121
133
  def parse(body)
@@ -144,24 +156,18 @@ module ActiveMerchant #:nodoc:
144
156
  end
145
157
 
146
158
 
147
- def commit(action, money, parameters)
148
- parameters[:software] = 'Active Merchant'
149
- parameters[:amount] = amount(money)
150
- parameters[:testmode] = test? ? 1 : 0
151
-
152
- if result = test_result_from_cc_number(parameters[:card])
153
- return result
154
- end
155
-
156
- data = ssl_post(GATEWAY_URL, post_data(action, parameters), POST_HEADERS)
159
+ def commit(action, parameters)
160
+ response = parse( ssl_post(URL, post_data(action, parameters)) )
157
161
 
158
- @response = parse(data)
159
- success = @response[:status] == 'Approved'
160
- message = message_from(@response)
161
-
162
- Response.new(success, message, @response,
163
- :test => test?,
164
- :authorization => @response[:ref_num]
162
+ Response.new(response[:status] == 'Approved', message_from(response), response,
163
+ :test => @options[:test] || test?,
164
+ :authorization => response[:ref_num],
165
+ :cvv_result => response[:cvv2_result_code],
166
+ :avs_result => {
167
+ :street_match => response[:avs_result_code].to_s[0,1],
168
+ :postal_match => response[:avs_result_code].to_s[1,1],
169
+ :code => response[:avs_result_code].to_s[2,1]
170
+ }
165
171
  )
166
172
  end
167
173
 
@@ -175,13 +181,12 @@ module ActiveMerchant #:nodoc:
175
181
  end
176
182
 
177
183
  def post_data(action, parameters = {})
178
- post = {}
179
-
180
- post[:command] = action
181
- post[:key] = @options[:login]
184
+ parameters[:command] = TRANSACTIONS[action]
185
+ parameters[:key] = @options[:login]
186
+ parameters[:software] = 'Active Merchant'
187
+ parameters[:testmode] = @options[:test] ? 1 : 0
182
188
 
183
- request = post.merge(parameters).collect { |key, value| "UM#{key}=#{CGI.escape(value.to_s)}" }.join("&")
184
- request
189
+ parameters.collect { |key, value| "UM#{key}=#{CGI.escape(value.to_s)}" }.join("&")
185
190
  end
186
191
  end
187
192
  end