fishman-activemerchant 1.18.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 (188) hide show
  1. data/CHANGELOG +733 -0
  2. data/CONTRIBUTORS +257 -0
  3. data/MIT-LICENSE +20 -0
  4. data/gem-public_cert.pem +20 -0
  5. data/lib/active_merchant.rb +47 -0
  6. data/lib/active_merchant/billing.rb +9 -0
  7. data/lib/active_merchant/billing/avs_result.rb +98 -0
  8. data/lib/active_merchant/billing/base.rb +57 -0
  9. data/lib/active_merchant/billing/check.rb +68 -0
  10. data/lib/active_merchant/billing/credit_card.rb +260 -0
  11. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  12. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  13. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  14. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  15. data/lib/active_merchant/billing/gateway.rb +170 -0
  16. data/lib/active_merchant/billing/gateways.rb +18 -0
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +693 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +858 -0
  19. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  20. data/lib/active_merchant/billing/gateways/beanstream.rb +139 -0
  21. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +282 -0
  22. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  23. data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
  24. data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
  25. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  26. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  27. data/lib/active_merchant/billing/gateways/braintree_blue.rb +303 -0
  28. data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
  29. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  30. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  31. data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
  32. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  33. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  34. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  35. data/lib/active_merchant/billing/gateways/epay.rb +274 -0
  36. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  37. data/lib/active_merchant/billing/gateways/eway_managed.rb +264 -0
  38. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  39. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  40. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  41. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  42. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
  43. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  44. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  45. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  46. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  47. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  48. data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
  49. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  50. data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
  51. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +156 -0
  52. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  53. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  54. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  55. data/lib/active_merchant/billing/gateways/moneris.rb +209 -0
  56. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  57. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  58. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  59. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  60. data/lib/active_merchant/billing/gateways/ogone.rb +292 -0
  61. data/lib/active_merchant/billing/gateways/optimal_payment.rb +274 -0
  62. data/lib/active_merchant/billing/gateways/orbital.rb +321 -0
  63. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  64. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  65. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  66. data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
  67. data/lib/active_merchant/billing/gateways/payflow.rb +253 -0
  68. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  69. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  70. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  71. data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
  72. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  73. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  74. data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
  75. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  76. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +354 -0
  77. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  78. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  79. data/lib/active_merchant/billing/gateways/paypal_express.rb +184 -0
  80. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
  81. data/lib/active_merchant/billing/gateways/paypal_express_de.rb +14 -0
  82. data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
  83. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  84. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  85. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  86. data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
  87. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  88. data/lib/active_merchant/billing/gateways/quickpay.rb +297 -0
  89. data/lib/active_merchant/billing/gateways/realex.rb +311 -0
  90. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  91. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  92. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  93. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  94. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  95. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  96. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  97. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  98. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +193 -0
  99. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  100. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  101. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  102. data/lib/active_merchant/billing/gateways/stripe.rb +212 -0
  103. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  104. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  105. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  106. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  107. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  108. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  109. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  110. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  111. data/lib/active_merchant/billing/integrations.rb +17 -0
  112. data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
  113. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  114. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  115. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  116. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  117. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  118. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  119. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  120. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  121. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  122. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  123. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  124. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  125. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  126. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  127. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  128. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  129. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  130. data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
  131. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +28 -0
  132. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +50 -0
  133. data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
  134. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  135. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  136. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  137. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  138. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  139. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  140. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  141. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  142. data/lib/active_merchant/billing/integrations/helper.rb +96 -0
  143. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  144. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  145. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  146. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  147. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  148. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  149. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  150. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  151. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  152. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  153. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  154. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  155. data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
  156. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +58 -0
  157. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
  158. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  159. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  160. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  161. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  162. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  163. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  164. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  165. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  166. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  167. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  168. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +111 -0
  169. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  170. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  171. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  172. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  173. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  174. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  175. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  176. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  177. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  178. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  179. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  180. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  181. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  182. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  183. data/lib/active_merchant/billing/response.rb +32 -0
  184. data/lib/active_merchant/version.rb +3 -0
  185. data/lib/activemerchant.rb +1 -0
  186. data/lib/support/gateway_support.rb +58 -0
  187. data/lib/support/outbound_hosts.rb +25 -0
  188. metadata +335 -0
@@ -0,0 +1,277 @@
1
+ require 'rexml/document'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # First, make sure you have everything setup correctly and all of your dependencies in place with:
6
+ #
7
+ # require 'rubygems'
8
+ # require 'active_merchant'
9
+ #
10
+ # ActiveMerchant expects the amounts to be given as an Integer in cents. In this case, $10 US becomes 1000.
11
+ #
12
+ # tendollar = 1000
13
+ #
14
+ # Next, create a credit card object using a TC approved test card.
15
+ #
16
+ # creditcard = ActiveMerchant::Billing::CreditCard.new(
17
+ # :number => '4111111111111111',
18
+ # :month => 8,
19
+ # :year => 2006,
20
+ # :first_name => 'Longbob',
21
+ # :last_name => 'Longsen'
22
+ # )
23
+ # options = {
24
+ # :order_id => '1230123',
25
+ # :email => 'bob@testbob.com',
26
+ # :address => { :address1 => '47 Bobway',
27
+ # :city => 'Bobville',
28
+ # :state => 'WA',
29
+ # :country => 'Australia',
30
+ # :zip => '2000'
31
+ # }
32
+ # :description => 'purchased items'
33
+ # }
34
+ #
35
+ # To finish setting up, create the active_merchant object you will be using, with the eWay gateway. If you have a
36
+ # functional eWay account, replace :login with your account info.
37
+ #
38
+ # gateway = ActiveMerchant::Billing::Base.gateway(:eway).new(:login => '87654321')
39
+ #
40
+ # Now we are ready to process our transaction
41
+ #
42
+ # response = gateway.purchase(tendollar, creditcard, options)
43
+ #
44
+ # Sending a transaction to TrustCommerce with active_merchant returns a Response object, which consistently allows you to:
45
+ #
46
+ # 1) Check whether the transaction was successful
47
+ #
48
+ # response.success?
49
+ #
50
+ # 2) Retrieve any message returned by eWay, either a "transaction was successful" note or an explanation of why the
51
+ # transaction was rejected.
52
+ #
53
+ # response.message
54
+ #
55
+ # 3) Retrieve and store the unique transaction ID returned by eWway, for use in referencing the transaction in the future.
56
+ #
57
+ # response.authorization
58
+ #
59
+ # This should be enough to get you started with eWay and active_merchant. For further information, review the methods
60
+ # below and the rest of active_merchant's documentation.
61
+
62
+ class EwayGateway < Gateway
63
+ TEST_URL = 'https://www.eway.com.au/gateway/xmltest/testpage.asp'
64
+ LIVE_URL = 'https://www.eway.com.au/gateway/xmlpayment.asp'
65
+
66
+ TEST_CVN_URL = 'https://www.eway.com.au/gateway_cvn/xmltest/testpage.asp'
67
+ LIVE_CVN_URL = 'https://www.eway.com.au/gateway_cvn/xmlpayment.asp'
68
+
69
+ MESSAGES = {
70
+ "00" => "Transaction Approved",
71
+ "01" => "Refer to Issuer",
72
+ "02" => "Refer to Issuer, special",
73
+ "03" => "No Merchant",
74
+ "04" => "Pick Up Card",
75
+ "05" => "Do Not Honour",
76
+ "06" => "Error",
77
+ "07" => "Pick Up Card, Special",
78
+ "08" => "Honour With Identification",
79
+ "09" => "Request In Progress",
80
+ "10" => "Approved For Partial Amount",
81
+ "11" => "Approved, VIP",
82
+ "12" => "Invalid Transaction",
83
+ "13" => "Invalid Amount",
84
+ "14" => "Invalid Card Number",
85
+ "15" => "No Issuer",
86
+ "16" => "Approved, Update Track 3",
87
+ "19" => "Re-enter Last Transaction",
88
+ "21" => "No Action Taken",
89
+ "22" => "Suspected Malfunction",
90
+ "23" => "Unacceptable Transaction Fee",
91
+ "25" => "Unable to Locate Record On File",
92
+ "30" => "Format Error",
93
+ "31" => "Bank Not Supported By Switch",
94
+ "33" => "Expired Card, Capture",
95
+ "34" => "Suspected Fraud, Retain Card",
96
+ "35" => "Card Acceptor, Contact Acquirer, Retain Card",
97
+ "36" => "Restricted Card, Retain Card",
98
+ "37" => "Contact Acquirer Security Department, Retain Card",
99
+ "38" => "PIN Tries Exceeded, Capture",
100
+ "39" => "No Credit Account",
101
+ "40" => "Function Not Supported",
102
+ "41" => "Lost Card",
103
+ "42" => "No Universal Account",
104
+ "43" => "Stolen Card",
105
+ "44" => "No Investment Account",
106
+ "51" => "Insufficient Funds",
107
+ "52" => "No Cheque Account",
108
+ "53" => "No Savings Account",
109
+ "54" => "Expired Card",
110
+ "55" => "Incorrect PIN",
111
+ "56" => "No Card Record",
112
+ "57" => "Function Not Permitted to Cardholder",
113
+ "58" => "Function Not Permitted to Terminal",
114
+ "59" => "Suspected Fraud",
115
+ "60" => "Acceptor Contact Acquirer",
116
+ "61" => "Exceeds Withdrawal Limit",
117
+ "62" => "Restricted Card",
118
+ "63" => "Security Violation",
119
+ "64" => "Original Amount Incorrect",
120
+ "66" => "Acceptor Contact Acquirer, Security",
121
+ "67" => "Capture Card",
122
+ "75" => "PIN Tries Exceeded",
123
+ "82" => "CVV Validation Error",
124
+ "90" => "Cutoff In Progress",
125
+ "91" => "Card Issuer Unavailable",
126
+ "92" => "Unable To Route Transaction",
127
+ "93" => "Cannot Complete, Violation Of The Law",
128
+ "94" => "Duplicate Transaction",
129
+ "96" => "System Error"
130
+ }
131
+
132
+ self.money_format = :cents
133
+ self.supported_countries = ['AU']
134
+ self.supported_cardtypes = [:visa, :master, :american_express]
135
+ self.homepage_url = 'http://www.eway.com.au/'
136
+ self.display_name = 'eWAY'
137
+
138
+ def initialize(options = {})
139
+ requires!(options, :login)
140
+ @options = options
141
+ super
142
+ end
143
+
144
+ # ewayCustomerEmail, ewayCustomerAddress, ewayCustomerPostcode
145
+ def purchase(money, creditcard, options = {})
146
+ requires!(options, :order_id)
147
+
148
+ post = {}
149
+ add_creditcard(post, creditcard)
150
+ add_address(post, options)
151
+ add_customer_data(post, options)
152
+ add_invoice_data(post, options)
153
+ # The request fails if all of the fields aren't present
154
+ add_optional_data(post)
155
+
156
+ commit(money, post)
157
+ end
158
+
159
+ def test?
160
+ @options[:test] || super
161
+ end
162
+
163
+ private
164
+ def add_creditcard(post, creditcard)
165
+ post[:CardNumber] = creditcard.number
166
+ post[:CardExpiryMonth] = sprintf("%.2i", creditcard.month)
167
+ post[:CardExpiryYear] = sprintf("%.4i", creditcard.year)[-2..-1]
168
+ post[:CustomerFirstName] = creditcard.first_name
169
+ post[:CustomerLastName] = creditcard.last_name
170
+ post[:CardHoldersName] = creditcard.name
171
+
172
+ post[:CVN] = creditcard.verification_value if creditcard.verification_value?
173
+ end
174
+
175
+ def add_address(post, options)
176
+ if address = options[:billing_address] || options[:address]
177
+ post[:CustomerAddress] = [ address[:address1], address[:address2], address[:city], address[:state], address[:country] ].compact.join(', ')
178
+ post[:CustomerPostcode] = address[:zip]
179
+ end
180
+ end
181
+
182
+ def add_customer_data(post, options)
183
+ post[:CustomerEmail] = options[:email]
184
+ end
185
+
186
+ def add_invoice_data(post, options)
187
+ post[:CustomerInvoiceRef] = options[:order_id]
188
+ post[:CustomerInvoiceDescription] = options[:description]
189
+ end
190
+
191
+ def add_optional_data(post)
192
+ post[:TrxnNumber] = nil
193
+ post[:Option1] = nil
194
+ post[:Option2] = nil
195
+ post[:Option3] = nil
196
+ end
197
+
198
+ def commit(money, parameters)
199
+ parameters[:TotalAmount] = amount(money)
200
+
201
+ response = parse( ssl_post(gateway_url(parameters[:CVN], test?), post_data(parameters)) )
202
+
203
+ Response.new(success?(response), message_from(response[:ewaytrxnerror]), response,
204
+ :authorization => response[:ewayauthcode],
205
+ :test => /\(Test( CVN)? Gateway\)/ === response[:ewaytrxnerror]
206
+ )
207
+ end
208
+
209
+ def success?(response)
210
+ response[:ewaytrxnstatus] == "True"
211
+ end
212
+
213
+ # Parse eway response xml into a convinient hash
214
+ def parse(xml)
215
+ # "<?xml version=\"1.0\"?>".
216
+ # <ewayResponse>
217
+ # <ewayTrxnError></ewayTrxnError>
218
+ # <ewayTrxnStatus>True</ewayTrxnStatus>
219
+ # <ewayTrxnNumber>10002</ewayTrxnNumber>
220
+ # <ewayTrxnOption1></ewayTrxnOption1>
221
+ # <ewayTrxnOption2></ewayTrxnOption2>
222
+ # <ewayTrxnOption3></ewayTrxnOption3>
223
+ # <ewayReturnAmount>10</ewayReturnAmount>
224
+ # <ewayAuthCode>123456</ewayAuthCode>
225
+ # <ewayTrxnReference>987654321</ewayTrxnReference>
226
+ # </ewayResponse>
227
+
228
+ response = {}
229
+ xml = REXML::Document.new(xml)
230
+ xml.elements.each('//ewayResponse/*') do |node|
231
+
232
+ response[node.name.downcase.to_sym] = normalize(node.text)
233
+
234
+ end unless xml.root.nil?
235
+
236
+ response
237
+ end
238
+
239
+ def post_data(parameters = {})
240
+ parameters[:CustomerID] = @options[:login]
241
+
242
+ xml = REXML::Document.new
243
+ root = xml.add_element("ewaygateway")
244
+
245
+ parameters.each do |key, value|
246
+ root.add_element("eway#{key}").text = value
247
+ end
248
+ xml.to_s
249
+ end
250
+
251
+ def message_from(message)
252
+ return '' if message.blank?
253
+ MESSAGES[message[0,2]] || message
254
+ end
255
+
256
+ # Make a ruby type out of the response string
257
+ def normalize(field)
258
+ case field
259
+ when "true" then true
260
+ when "false" then false
261
+ when "" then nil
262
+ when "null" then nil
263
+ else field
264
+ end
265
+ end
266
+
267
+ def gateway_url(cvn, test)
268
+ if cvn
269
+ test ? TEST_CVN_URL : LIVE_CVN_URL
270
+ else
271
+ test ? TEST_URL : LIVE_URL
272
+ end
273
+ end
274
+
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,264 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class EwayManagedGateway < Gateway
4
+ TEST_URL = 'https://www.eway.com.au/gateway/ManagedPaymentService/test/managedCreditCardPayment.asmx'
5
+ LIVE_URL = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx'
6
+
7
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
8
+ self.supported_countries = ['AU']
9
+
10
+ # The card types supported by the payment gateway
11
+ self.supported_cardtypes = [:visa, :master]
12
+
13
+ self.default_currency = 'AUD'
14
+
15
+ #accepted money format
16
+ self.money_format = :cents
17
+
18
+ # The homepage URL of the gateway
19
+ self.homepage_url = 'http://www.eway.com.au/'
20
+
21
+ # The name of the gateway
22
+ self.display_name = 'eWay Managed Payments'
23
+
24
+ def initialize(options = {})
25
+ requires!(options, :login, :username, :password)
26
+ @options = options
27
+
28
+ # eWay returns 500 code for faults, which AM snaffles.
29
+ # So, we tell it to allow them.
30
+ @options[:ignore_http_status]=true
31
+ super
32
+ end
33
+
34
+ # add a new customer CC to your eway account and return unique ManagedCustomerID
35
+ # supports storing details required by eway see "add_creditcard" and "add_address"
36
+ def store(creditcard, options = {})
37
+ post = {}
38
+
39
+ # Handle our required fields
40
+ requires!(options, :billing_address)
41
+
42
+ # Handle eWay specific required fields.
43
+ billing_address = options[:billing_address]
44
+ eway_requires!(billing_address)
45
+
46
+ add_creditcard(post, creditcard)
47
+ add_address(post, billing_address)
48
+ add_misc_fields(post, options)
49
+
50
+ commit("CreateCustomer", post)
51
+ end
52
+
53
+ def update(billing_id, creditcard, options={})
54
+ post = {}
55
+
56
+ # Handle our required fields
57
+ requires!(options, :billing_address)
58
+
59
+ # Handle eWay specific required fields.
60
+ billing_address = options[:billing_address]
61
+ eway_requires!(billing_address)
62
+
63
+ post[:managedCustomerID]=billing_id
64
+ add_creditcard(post, creditcard)
65
+ add_address(post, billing_address)
66
+ add_misc_fields(post, options)
67
+
68
+ commit("UpdateCustomer", post)
69
+ end
70
+
71
+ # Process a payment in the given amount against the stored credit card given by billing_id
72
+ #
73
+ # ==== Parameters
74
+ #
75
+ # * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
76
+ # * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
77
+ # * <tt>options</tt> -- A hash of optional parameters.
78
+ #
79
+ # ==== Options
80
+ #
81
+ # * <tt>:order_id</tt> -- The order number, passed to eWay as the "Invoice Reference"
82
+ # * <tt>:invoice</tt> -- The invoice number, passed to eWay as the "Invoice Reference" unless :order_id is also given
83
+ # * <tt>:description</tt> -- A description of the payment, passed to eWay as the "Invoice Description"
84
+ def purchase(money, billing_id, options={})
85
+ post = {}
86
+ post[:managedCustomerID] = billing_id.to_s
87
+ post[:amount]=money
88
+ add_invoice(post, options)
89
+
90
+ commit("ProcessPayment", post)
91
+ end
92
+
93
+ # TODO: eWay API also provides QueryCustomer
94
+ # TODO: eWay API also provides QueryPayment
95
+
96
+ def test?
97
+ @options[:test] || Base.gateway_mode == :test
98
+ end
99
+ private
100
+
101
+ def eway_requires!(hash)
102
+ raise ArgumentError.new("Missing eWay required parameter in `billing_address`: title") unless hash.has_key?(:title)
103
+ raise ArgumentError.new("Missing eWay required parameter in `billing_address`: country") unless hash.has_key?(:country)
104
+ end
105
+
106
+ def add_address(post, address)
107
+ post[:Address] = address[:address1].to_s
108
+ post[:Phone] = address[:phone].to_s
109
+ post[:PostCode] = address[:zip].to_s
110
+ post[:Suburb] = address[:city].to_s
111
+ post[:Country] = address[:country].to_s.downcase
112
+ post[:State] = address[:state].to_s
113
+ post[:Mobile] = address[:mobile].to_s
114
+ post[:Fax] = address[:fax].to_s
115
+ end
116
+
117
+ def add_misc_fields(post, options)
118
+ post[:CustomerRef]=options[:billing_address][:customer_ref] || options[:customer]
119
+ post[:Title]=options[:billing_address][:title]
120
+ post[:Company]=options[:billing_address][:company]
121
+ post[:JobDesc]=options[:billing_address][:job_desc]
122
+ post[:Email]=options[:billing_address][:email] || options[:email]
123
+ post[:URL]=options[:billing_address][:url]
124
+ post[:Comments]=options[:description]
125
+ end
126
+
127
+ def add_invoice(post, options)
128
+ post[:invoiceReference] = options[:order_id] || options[:invoice]
129
+ post[:invoiceDescription] = options[:description]
130
+ end
131
+
132
+
133
+ # add credit card details to be stored by eway. NOTE eway requires "title" field
134
+ def add_creditcard(post, creditcard)
135
+ post[:CCNumber] = creditcard.number
136
+ post[:CCExpiryMonth] = sprintf("%.2i", creditcard.month)
137
+ post[:CCExpiryYear] = sprintf("%.4i", creditcard.year)[-2..-1]
138
+ post[:CCNameOnCard] = creditcard.name
139
+ post[:FirstName] = creditcard.first_name
140
+ post[:LastName] = creditcard.last_name
141
+ end
142
+
143
+ def parse(body)
144
+ reply = {}
145
+ xml = REXML::Document.new(body)
146
+ if root = REXML::XPath.first(xml, "//soap:Fault") then
147
+ reply=parse_fault(root)
148
+ else
149
+ if root = REXML::XPath.first(xml, '//ProcessPaymentResponse/ewayResponse') then
150
+ # Successful payment
151
+ reply=parse_purchase(root)
152
+ else
153
+ if root = REXML::XPath.first(xml, '//CreateCustomerResult') then
154
+ reply[:message]='OK'
155
+ reply[:CreateCustomerResult]=root.text
156
+ reply[:success]=true
157
+ else
158
+ if root = REXML::XPath.first(xml, '//UpdateCustomerResult') then
159
+ if root.text.downcase == 'true' then
160
+ reply[:message]='OK'
161
+ reply[:success]=true
162
+ else
163
+ # ERROR: This state should never occur. If there is a problem,
164
+ # a soap:Fault will be returned. The presence of this
165
+ # element always means a success.
166
+ raise StandardError, "Unexpected \"false\" in UpdateCustomerResult"
167
+ end
168
+ else
169
+ # ERROR: This state should never occur currently. We have handled
170
+ # responses for all the methods which we support.
171
+ raise StandardError, "Unexpected response"
172
+ end
173
+ end
174
+ end
175
+ end
176
+ return reply
177
+ end
178
+
179
+ def parse_fault(node)
180
+ reply={}
181
+ reply[:message]=REXML::XPath.first(node, '//soap:Reason/soap:Text').text
182
+ reply[:success]=false
183
+ reply
184
+ end
185
+
186
+ def parse_purchase(node)
187
+ reply={}
188
+ reply[:message]=REXML::XPath.first(node, '//ewayTrxnError').text
189
+ reply[:success]=(REXML::XPath.first(node, '//ewayTrxnStatus').text == 'True')
190
+ reply[:auth_code]=REXML::XPath.first(node, '//ewayAuthCode').text
191
+ reply
192
+ end
193
+
194
+ def commit(action, post)
195
+ raw = begin
196
+ ssl_post(test? ? TEST_URL : LIVE_URL, soap_request(post, action), 'Content-Type' => 'application/soap+xml; charset=utf-8')
197
+ rescue ResponseError => e
198
+ e.response.body
199
+ end
200
+ response = parse(raw)
201
+
202
+ EwayResponse.new(response[:success], response[:message], response,
203
+ :test => test?,
204
+ :authorization => response[:auth_code]
205
+ )
206
+ end
207
+
208
+ # Where we build the full SOAP 1.2 request using builder
209
+ def soap_request(arguments, action)
210
+ # eWay demands all fields be sent, but contain an empty string if blank
211
+ post = case action
212
+ when 'ProcessPayment'
213
+ default_payment_fields.merge(arguments)
214
+ else
215
+ default_customer_fields.merge(arguments)
216
+ end
217
+
218
+ xml = Builder::XmlMarkup.new :indent => 2
219
+ xml.instruct!
220
+ xml.tag! 'soap12:Envelope', {'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema', 'xmlns:soap12' => 'http://www.w3.org/2003/05/soap-envelope'} do
221
+ xml.tag! 'soap12:Header' do
222
+ xml.tag! 'eWAYHeader', {'xmlns' => 'https://www.eway.com.au/gateway/managedpayment'} do
223
+ xml.tag! 'eWAYCustomerID', @options[:login]
224
+ xml.tag! 'Username', @options[:username]
225
+ xml.tag! 'Password', @options[:password]
226
+ end
227
+ end
228
+ xml.tag! 'soap12:Body' do |x|
229
+ x.tag! "#{action}", {'xmlns' => 'https://www.eway.com.au/gateway/managedpayment'} do |y|
230
+ post.each do |key, value|
231
+ y.tag! "#{key}", "#{value}"
232
+ end
233
+ end
234
+ end
235
+ end
236
+ xml.target!
237
+ end
238
+
239
+ def default_customer_fields
240
+ hash={}
241
+ %w( CustomerRef Title FirstName LastName Company JobDesc Email Address Suburb State PostCode Country Phone Mobile Fax URL Comments CCNumber CCNameOnCard CCExpiryMonth CCExpiryYear ).each do |field|
242
+ hash[field.to_sym]=''
243
+ end
244
+ return hash
245
+ end
246
+
247
+ def default_payment_fields
248
+ hash={}
249
+ %w( managedCustomerID amount invoiceReference invoiceDescription ).each do |field|
250
+ hash[field.to_sym]=''
251
+ end
252
+ return hash
253
+ end
254
+
255
+ class EwayResponse < Response
256
+ # add a method to response so we can easily get the eway token "ManagedCustomerID"
257
+ def token
258
+ @params['CreateCustomerResult']
259
+ end
260
+ end
261
+
262
+ end
263
+ end
264
+ end