aktivemerchant 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1596 -0
  3. data/CONTRIBUTORS +511 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +18 -0
  6. data/lib/active_merchant.rb +108 -0
  7. data/lib/active_merchant/billing.rb +13 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/avs_result.rb +98 -0
  10. data/lib/active_merchant/billing/base.rb +72 -0
  11. data/lib/active_merchant/billing/check.rb +76 -0
  12. data/lib/active_merchant/billing/compatibility.rb +120 -0
  13. data/lib/active_merchant/billing/credit_card.rb +352 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +268 -0
  18. data/lib/active_merchant/billing/gateways.rb +17 -0
  19. data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
  20. data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
  21. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  24. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  25. data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
  28. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
  35. data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
  36. data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
  37. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  38. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  42. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  43. data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
  44. data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
  45. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  46. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  47. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  48. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  49. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  50. data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
  51. data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
  52. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  53. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  54. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  55. data/lib/active_merchant/billing/gateways/epay.rb +275 -0
  56. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  57. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  58. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  59. data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
  60. data/lib/active_merchant/billing/gateways/exact.rb +218 -0
  61. data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
  62. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  63. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  64. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  65. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  66. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
  67. data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
  68. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  69. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  70. data/lib/active_merchant/billing/gateways/hps.rb +288 -0
  71. data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
  72. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  73. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  74. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  75. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  76. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  77. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  78. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  79. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  80. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  81. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  82. data/lib/active_merchant/billing/gateways/litle.rb +346 -0
  83. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  84. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  85. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  86. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  87. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  88. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  89. data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
  90. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  91. data/lib/active_merchant/billing/gateways/migs.rb +265 -0
  92. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  93. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  94. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  95. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  96. data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
  97. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  98. data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
  99. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  100. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  101. data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
  102. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  103. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  104. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  105. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  106. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  107. data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
  108. data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
  109. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  110. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  111. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  112. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
  113. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  114. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  115. data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
  116. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  117. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
  119. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
  120. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  121. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  122. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  123. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  124. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  125. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  126. data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
  127. data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
  128. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
  129. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  130. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  131. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  132. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  133. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  134. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  135. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  136. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  137. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  138. data/lib/active_merchant/billing/gateways/pin.rb +197 -0
  139. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  140. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  141. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  142. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  143. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  144. data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
  145. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  146. data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
  147. data/lib/active_merchant/billing/gateways/sage.rb +175 -0
  148. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
  149. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
  150. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  151. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
  152. data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
  153. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  154. data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
  155. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  156. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  157. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  158. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  159. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  160. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  161. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  162. data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
  163. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  164. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  165. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  166. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  167. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  168. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  169. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  170. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  171. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
  172. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  173. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  174. data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
  175. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  176. data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
  177. data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
  178. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  179. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  180. data/lib/active_merchant/billing/model.rb +30 -0
  181. data/lib/active_merchant/billing/payment_token.rb +21 -0
  182. data/lib/active_merchant/billing/rails.rb +3 -0
  183. data/lib/active_merchant/billing/response.rb +91 -0
  184. data/lib/active_merchant/country.rb +332 -0
  185. data/lib/active_merchant/empty.rb +20 -0
  186. data/lib/active_merchant/errors.rb +29 -0
  187. data/lib/active_merchant/offsite_payments_shim.rb +19 -0
  188. data/lib/active_merchant/version.rb +3 -0
  189. data/lib/activemerchant.rb +1 -0
  190. data/lib/support/gateway_support.rb +71 -0
  191. data/lib/support/outbound_hosts.rb +25 -0
  192. data/lib/support/ssl_verify.rb +93 -0
  193. metadata +400 -0
@@ -0,0 +1,214 @@
1
+ require 'rexml/document'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # Public: For more information on the Eway Gateway please visit their
6
+ # {Developers Area}[http://www.eway.com.au/developers/api/direct-payments]
7
+ class EwayGateway < Gateway
8
+ self.live_url = 'https://www.eway.com.au'
9
+
10
+ self.money_format = :cents
11
+ self.supported_countries = ['AU']
12
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
13
+ self.homepage_url = 'http://www.eway.com.au/'
14
+ self.display_name = 'eWAY'
15
+
16
+ # Public: Create a new Eway Gateway.
17
+ # options - A hash of options:
18
+ # :login - Your Customer ID.
19
+ # :password - Your XML Refund Password that you
20
+ # specified on the Eway site. (optional)
21
+ def initialize(options = {})
22
+ requires!(options, :login)
23
+ super
24
+ end
25
+
26
+ def purchase(money, creditcard, options = {})
27
+ requires_address!(options)
28
+
29
+ post = {}
30
+ add_creditcard(post, creditcard)
31
+ add_address(post, options)
32
+ add_customer_id(post)
33
+ add_invoice_data(post, options)
34
+ add_non_optional_data(post)
35
+ add_amount(post, money)
36
+ post[:CustomerEmail] = options[:email]
37
+
38
+ commit(purchase_url(post[:CVN]), money, post)
39
+ end
40
+
41
+ def refund(money, authorization, options={})
42
+ post = {}
43
+
44
+ add_customer_id(post)
45
+ add_amount(post, money)
46
+ add_non_optional_data(post)
47
+ post[:OriginalTrxnNumber] = authorization
48
+ post[:RefundPassword] = @options[:password]
49
+ post[:CardExpiryMonth] = nil
50
+ post[:CardExpiryYear] = nil
51
+
52
+ commit(refund_url, money, post)
53
+ end
54
+
55
+ private
56
+ def requires_address!(options)
57
+ raise ArgumentError.new("Missing eWay required parameters: address or billing_address") unless (options.has_key?(:address) or options.has_key?(:billing_address))
58
+ end
59
+
60
+ def add_creditcard(post, creditcard)
61
+ post[:CardNumber] = creditcard.number
62
+ post[:CardExpiryMonth] = sprintf("%.2i", creditcard.month)
63
+ post[:CardExpiryYear] = sprintf("%.4i", creditcard.year)[-2..-1]
64
+ post[:CustomerFirstName] = creditcard.first_name
65
+ post[:CustomerLastName] = creditcard.last_name
66
+ post[:CardHoldersName] = creditcard.name
67
+
68
+ post[:CVN] = creditcard.verification_value if creditcard.verification_value?
69
+ end
70
+
71
+ def add_address(post, options)
72
+ if address = options[:billing_address] || options[:address]
73
+ post[:CustomerAddress] = [ address[:address1], address[:address2], address[:city], address[:state], address[:country] ].compact.join(', ')
74
+ post[:CustomerPostcode] = address[:zip]
75
+ end
76
+ end
77
+
78
+ def add_customer_id(post)
79
+ post[:CustomerID] = @options[:login]
80
+ end
81
+
82
+ def add_invoice_data(post, options)
83
+ post[:CustomerInvoiceRef] = options[:order_id]
84
+ post[:CustomerInvoiceDescription] = options[:description]
85
+ end
86
+
87
+ def add_amount(post, money)
88
+ post[:TotalAmount] = amount(money)
89
+ end
90
+
91
+ def add_non_optional_data(post)
92
+ post[:Option1] = nil
93
+ post[:Option2] = nil
94
+ post[:Option3] = nil
95
+ post[:TrxnNumber] = nil
96
+ end
97
+
98
+ def commit(url, money, parameters)
99
+ raw_response = ssl_post(url, post_data(parameters))
100
+ response = parse(raw_response)
101
+
102
+ Response.new(success?(response),
103
+ message_from(response[:ewaytrxnerror]),
104
+ response,
105
+ :authorization => response[:ewaytrxnnumber],
106
+ :test => test?
107
+ )
108
+ end
109
+
110
+ def success?(response)
111
+ response[:ewaytrxnstatus] == "True"
112
+ end
113
+
114
+ def parse(xml)
115
+ response = {}
116
+ xml = REXML::Document.new(xml)
117
+ xml.elements.each('//ewayResponse/*') do |node|
118
+ response[node.name.downcase.to_sym] = normalize(node.text)
119
+ end unless xml.root.nil?
120
+
121
+ response
122
+ end
123
+
124
+ def post_data(parameters = {})
125
+ xml = REXML::Document.new
126
+ root = xml.add_element("ewaygateway")
127
+
128
+ parameters.each do |key, value|
129
+ root.add_element("eway#{key}").text = value
130
+ end
131
+ xml.to_s
132
+ end
133
+
134
+ def message_from(message)
135
+ return '' if message.blank?
136
+ MESSAGES[message[0,2]] || message
137
+ end
138
+
139
+ def purchase_url(cvn)
140
+ suffix = test? ? 'xmltest/testpage.asp' : 'xmlpayment.asp'
141
+ gateway_part = cvn ? 'gateway_cvn' : 'gateway'
142
+ "#{live_url}/#{gateway_part}/#{suffix}"
143
+ end
144
+
145
+ def refund_url
146
+ suffix = test? ? 'xmltest/refund_test.asp' : 'xmlpaymentrefund.asp'
147
+ "#{live_url}/gateway/#{suffix}"
148
+ end
149
+
150
+ MESSAGES = {
151
+ "00" => "Transaction Approved",
152
+ "01" => "Refer to Issuer",
153
+ "02" => "Refer to Issuer, special",
154
+ "03" => "No Merchant",
155
+ "04" => "Pick Up Card",
156
+ "05" => "Do Not Honour",
157
+ "06" => "Error",
158
+ "07" => "Pick Up Card, Special",
159
+ "08" => "Honour With Identification",
160
+ "09" => "Request In Progress",
161
+ "10" => "Approved For Partial Amount",
162
+ "11" => "Approved, VIP",
163
+ "12" => "Invalid Transaction",
164
+ "13" => "Invalid Amount",
165
+ "14" => "Invalid Card Number",
166
+ "15" => "No Issuer",
167
+ "16" => "Approved, Update Track 3",
168
+ "19" => "Re-enter Last Transaction",
169
+ "21" => "No Action Taken",
170
+ "22" => "Suspected Malfunction",
171
+ "23" => "Unacceptable Transaction Fee",
172
+ "25" => "Unable to Locate Record On File",
173
+ "30" => "Format Error",
174
+ "31" => "Bank Not Supported By Switch",
175
+ "33" => "Expired Card, Capture",
176
+ "34" => "Suspected Fraud, Retain Card",
177
+ "35" => "Card Acceptor, Contact Acquirer, Retain Card",
178
+ "36" => "Restricted Card, Retain Card",
179
+ "37" => "Contact Acquirer Security Department, Retain Card",
180
+ "38" => "PIN Tries Exceeded, Capture",
181
+ "39" => "No Credit Account",
182
+ "40" => "Function Not Supported",
183
+ "41" => "Lost Card",
184
+ "42" => "No Universal Account",
185
+ "43" => "Stolen Card",
186
+ "44" => "No Investment Account",
187
+ "51" => "Insufficient Funds",
188
+ "52" => "No Cheque Account",
189
+ "53" => "No Savings Account",
190
+ "54" => "Expired Card",
191
+ "55" => "Incorrect PIN",
192
+ "56" => "No Card Record",
193
+ "57" => "Function Not Permitted to Cardholder",
194
+ "58" => "Function Not Permitted to Terminal",
195
+ "59" => "Suspected Fraud",
196
+ "60" => "Acceptor Contact Acquirer",
197
+ "61" => "Exceeds Withdrawal Limit",
198
+ "62" => "Restricted Card",
199
+ "63" => "Security Violation",
200
+ "64" => "Original Amount Incorrect",
201
+ "66" => "Acceptor Contact Acquirer, Security",
202
+ "67" => "Capture Card",
203
+ "75" => "PIN Tries Exceeded",
204
+ "82" => "CVV Validation Error",
205
+ "90" => "Cutoff In Progress",
206
+ "91" => "Card Issuer Unavailable",
207
+ "92" => "Unable To Route Transaction",
208
+ "93" => "Cannot Complete, Violation Of The Law",
209
+ "94" => "Duplicate Transaction",
210
+ "96" => "System Error"
211
+ }
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,291 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class EwayManagedGateway < Gateway
4
+ self.test_url = 'https://www.eway.com.au/gateway/ManagedPaymentService/test/managedCreditCardPayment.asmx'
5
+ self.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
+
27
+ # eWay returns 500 code for faults, which AM snaffles.
28
+ # So, we tell it to allow them.
29
+ options[:ignore_http_status] = true
30
+ super
31
+ end
32
+
33
+ # add a new customer CC to your eway account and return unique ManagedCustomerID
34
+ # supports storing details required by eway see "add_creditcard" and "add_address"
35
+ def store(creditcard, options = {})
36
+ post = {}
37
+
38
+ # Handle our required fields
39
+ requires!(options, :billing_address)
40
+
41
+ # Handle eWay specific required fields.
42
+ billing_address = options[:billing_address]
43
+ eway_requires!(billing_address)
44
+
45
+ add_creditcard(post, creditcard)
46
+ add_address(post, billing_address)
47
+ add_misc_fields(post, options)
48
+
49
+ commit("CreateCustomer", post)
50
+ end
51
+
52
+ def update(billing_id, creditcard, options={})
53
+ post = {}
54
+
55
+ # Handle our required fields
56
+ requires!(options, :billing_address)
57
+
58
+ # Handle eWay specific required fields.
59
+ billing_address = options[:billing_address]
60
+ eway_requires!(billing_address)
61
+
62
+ post[:managedCustomerID]=billing_id
63
+ add_creditcard(post, creditcard)
64
+ add_address(post, billing_address)
65
+ add_misc_fields(post, options)
66
+
67
+ commit("UpdateCustomer", post)
68
+ end
69
+
70
+ # Process a payment in the given amount against the stored credit card given by billing_id
71
+ #
72
+ # ==== Parameters
73
+ #
74
+ # * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
75
+ # * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
76
+ # * <tt>options</tt> -- A hash of optional parameters.
77
+ #
78
+ # ==== Options
79
+ #
80
+ # * <tt>:order_id</tt> -- The order number, passed to eWay as the "Invoice Reference"
81
+ # * <tt>:invoice</tt> -- The invoice number, passed to eWay as the "Invoice Reference" unless :order_id is also given
82
+ # * <tt>:description</tt> -- A description of the payment, passed to eWay as the "Invoice Description"
83
+ def purchase(money, billing_id, options={})
84
+ post = {}
85
+ post[:managedCustomerID] = billing_id.to_s
86
+ post[:amount]=money
87
+ add_invoice(post, options)
88
+
89
+ commit("ProcessPayment", post)
90
+ end
91
+
92
+ # Get customer's stored credit card details given by billing_id
93
+ #
94
+ # ==== Parameters
95
+ #
96
+ # * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
97
+ def retrieve(billing_id)
98
+ post = {}
99
+ post[:managedCustomerID] = billing_id.to_s
100
+
101
+ commit("QueryCustomer", post)
102
+ end
103
+
104
+ # TODO: eWay API also provides QueryPayment
105
+
106
+ private
107
+
108
+ def eway_requires!(hash)
109
+ raise ArgumentError.new("Missing eWay required parameter in `billing_address`: title") unless hash.has_key?(:title)
110
+ raise ArgumentError.new("Missing eWay required parameter in `billing_address`: country") unless hash.has_key?(:country)
111
+ end
112
+
113
+ def add_address(post, address)
114
+ post[:Address] = address[:address1].to_s
115
+ post[:Phone] = address[:phone].to_s
116
+ post[:PostCode] = address[:zip].to_s
117
+ post[:Suburb] = address[:city].to_s
118
+ post[:Country] = address[:country].to_s.downcase
119
+ post[:State] = address[:state].to_s
120
+ post[:Mobile] = address[:mobile].to_s
121
+ post[:Fax] = address[:fax].to_s
122
+ end
123
+
124
+ def add_misc_fields(post, options)
125
+ post[:CustomerRef]=options[:billing_address][:customer_ref] || options[:customer]
126
+ post[:Title]=options[:billing_address][:title]
127
+ post[:Company]=options[:billing_address][:company]
128
+ post[:JobDesc]=options[:billing_address][:job_desc]
129
+ post[:Email]=options[:billing_address][:email] || options[:email]
130
+ post[:URL]=options[:billing_address][:url]
131
+ post[:Comments]=options[:description]
132
+ end
133
+
134
+ def add_invoice(post, options)
135
+ post[:invoiceReference] = options[:order_id] || options[:invoice]
136
+ post[:invoiceDescription] = options[:description]
137
+ end
138
+
139
+
140
+ # add credit card details to be stored by eway. NOTE eway requires "title" field
141
+ def add_creditcard(post, creditcard)
142
+ post[:CCNumber] = creditcard.number
143
+ post[:CCExpiryMonth] = sprintf("%.2i", creditcard.month)
144
+ post[:CCExpiryYear] = sprintf("%.4i", creditcard.year)[-2..-1]
145
+ post[:CCNameOnCard] = creditcard.name
146
+ post[:FirstName] = creditcard.first_name
147
+ post[:LastName] = creditcard.last_name
148
+ end
149
+
150
+ def parse(body)
151
+ reply = {}
152
+ xml = REXML::Document.new(body)
153
+ if root = REXML::XPath.first(xml, "//soap:Fault") then
154
+ reply=parse_fault(root)
155
+ else
156
+ if root = REXML::XPath.first(xml, '//ProcessPaymentResponse/ewayResponse') then
157
+ # Successful payment
158
+ reply=parse_purchase(root)
159
+ else
160
+ if root = REXML::XPath.first(xml, '//QueryCustomerResult') then
161
+ reply=parse_query_customer(root)
162
+ else
163
+ if root = REXML::XPath.first(xml, '//CreateCustomerResult') then
164
+ reply[:message]='OK'
165
+ reply[:CreateCustomerResult]=root.text
166
+ reply[:success]=true
167
+ else
168
+ if root = REXML::XPath.first(xml, '//UpdateCustomerResult') then
169
+ if root.text.downcase == 'true' then
170
+ reply[:message]='OK'
171
+ reply[:success]=true
172
+ else
173
+ # ERROR: This state should never occur. If there is a problem,
174
+ # a soap:Fault will be returned. The presence of this
175
+ # element always means a success.
176
+ raise StandardError, "Unexpected \"false\" in UpdateCustomerResult"
177
+ end
178
+ else
179
+ # ERROR: This state should never occur currently. We have handled
180
+ # responses for all the methods which we support.
181
+ raise StandardError, "Unexpected response"
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ return reply
188
+ end
189
+
190
+ def parse_fault(node)
191
+ reply={}
192
+ reply[:message]=REXML::XPath.first(node, '//soap:Reason/soap:Text').text
193
+ reply[:success]=false
194
+ reply
195
+ end
196
+
197
+ def parse_purchase(node)
198
+ reply={}
199
+ reply[:message]=REXML::XPath.first(node, '//ewayTrxnError').text
200
+ reply[:success]=(REXML::XPath.first(node, '//ewayTrxnStatus').text == 'True')
201
+ reply[:auth_code]=REXML::XPath.first(node, '//ewayAuthCode').text
202
+ reply[:transaction_number]=REXML::XPath.first(node, '//ewayTrxnNumber').text
203
+ reply
204
+ end
205
+
206
+ def parse_query_customer(node)
207
+ reply={}
208
+ reply[:message]='OK'
209
+ reply[:success]=true
210
+ reply[:CCNumber]=REXML::XPath.first(node, '//CCNumber').text
211
+ reply[:CCName]=REXML::XPath.first(node, '//CCName').text
212
+ reply[:CCExpiryMonth]=REXML::XPath.first(node, '//CCExpiryMonth').text
213
+ reply[:CCExpiryYear]=REXML::XPath.first(node, '//CCExpiryYear').text
214
+ reply
215
+ end
216
+
217
+ def commit(action, post)
218
+ raw = begin
219
+ ssl_post(test? ? self.test_url : self.live_url, soap_request(post, action), 'Content-Type' => 'application/soap+xml; charset=utf-8')
220
+ rescue ResponseError => e
221
+ e.response.body
222
+ end
223
+ response = parse(raw)
224
+
225
+ EwayResponse.new(response[:success], response[:message], response,
226
+ :test => test?,
227
+ :authorization => response[:auth_code]
228
+ )
229
+ end
230
+
231
+ # Where we build the full SOAP 1.2 request using builder
232
+ def soap_request(arguments, action)
233
+ # eWay demands all fields be sent, but contain an empty string if blank
234
+ post = case action
235
+ when 'QueryCustomer'
236
+ arguments
237
+ when 'ProcessPayment'
238
+ default_payment_fields.merge(arguments)
239
+ when 'CreateCustomer'
240
+ default_customer_fields.merge(arguments)
241
+ when 'UpdateCustomer'
242
+ default_customer_fields.merge(arguments)
243
+ end
244
+
245
+ xml = Builder::XmlMarkup.new :indent => 2
246
+ xml.instruct!
247
+ 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
248
+ xml.tag! 'soap12:Header' do
249
+ xml.tag! 'eWAYHeader', {'xmlns' => 'https://www.eway.com.au/gateway/managedpayment'} do
250
+ xml.tag! 'eWAYCustomerID', @options[:login]
251
+ xml.tag! 'Username', @options[:username]
252
+ xml.tag! 'Password', @options[:password]
253
+ end
254
+ end
255
+ xml.tag! 'soap12:Body' do |x|
256
+ x.tag! "#{action}", {'xmlns' => 'https://www.eway.com.au/gateway/managedpayment'} do |y|
257
+ post.each do |key, value|
258
+ y.tag! "#{key}", "#{value}"
259
+ end
260
+ end
261
+ end
262
+ end
263
+ xml.target!
264
+ end
265
+
266
+ def default_customer_fields
267
+ hash={}
268
+ %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|
269
+ hash[field.to_sym]=''
270
+ end
271
+ return hash
272
+ end
273
+
274
+ def default_payment_fields
275
+ hash={}
276
+ %w( managedCustomerID amount invoiceReference invoiceDescription ).each do |field|
277
+ hash[field.to_sym]=''
278
+ end
279
+ return hash
280
+ end
281
+
282
+ class EwayResponse < Response
283
+ # add a method to response so we can easily get the eway token "ManagedCustomerID"
284
+ def token
285
+ @params['CreateCustomerResult']
286
+ end
287
+ end
288
+
289
+ end
290
+ end
291
+ end