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,30 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ module PaypalExpressCommon
4
+ def self.included(base)
5
+ if base.respond_to?(:class_attribute)
6
+ base.class_attribute :test_redirect_url
7
+ base.class_attribute :live_redirect_url
8
+ else
9
+ base.class_inheritable_accessor :test_redirect_url
10
+ base.class_inheritable_accessor :live_redirect_url
11
+ end
12
+ base.live_redirect_url = 'https://www.paypal.com/cgi-bin/webscr'
13
+ end
14
+
15
+ def redirect_url
16
+ test? ? test_redirect_url : live_redirect_url
17
+ end
18
+
19
+ def redirect_url_for(token, options = {})
20
+ options = {:review => true, :mobile => false}.update(options)
21
+
22
+ cmd = options[:mobile] ? '_express-checkout-mobile' : '_express-checkout'
23
+ url = "#{redirect_url}?cmd=#{cmd}&token=#{token}"
24
+ url += '&useraction=commit' unless options[:review]
25
+
26
+ url
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,162 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PayscoutGateway < Gateway
4
+ self.live_url = self.test_url = 'https://secure.payscout.com/api/transact.php'
5
+
6
+ self.supported_countries = ['US']
7
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
8
+ self.default_currency = 'USD'
9
+ self.homepage_url = 'http://www.payscout.com/'
10
+ self.display_name = 'Payscout'
11
+
12
+ def initialize(options = {})
13
+ requires!(options, :username, :password)
14
+ super
15
+ end
16
+
17
+ def authorize(money, creditcard, options = {})
18
+ post = {}
19
+ add_invoice(post, options)
20
+ add_creditcard(post, creditcard)
21
+ add_currency(post, money, options)
22
+ add_address(post, options)
23
+
24
+ commit('auth', money, post)
25
+ end
26
+
27
+ def purchase(money, creditcard, options = {})
28
+ post = {}
29
+ add_invoice(post, options)
30
+ add_creditcard(post, creditcard)
31
+ add_currency(post, money, options)
32
+ add_address(post, options)
33
+
34
+ commit('sale', money, post)
35
+ end
36
+
37
+ def capture(money, authorization, options = {})
38
+ post = {}
39
+ post[:transactionid] = authorization
40
+
41
+ commit('capture', money, post)
42
+ end
43
+
44
+
45
+ def refund(money, authorization, options = {})
46
+ post = {}
47
+ post[:transactionid] = authorization
48
+
49
+ commit('refund', money, post)
50
+ end
51
+
52
+ def void(authorization, options = {})
53
+ post = {}
54
+ post[:transactionid] = authorization
55
+
56
+ commit('void', nil, post)
57
+ end
58
+
59
+ private
60
+
61
+ def add_address(post, options)
62
+ if address = options[:billing_address] || options[:address]
63
+ post[:address1] = address[:address1].to_s
64
+ post[:address2] = address[:address2].to_s
65
+ post[:city] = address[:city].to_s
66
+ post[:state] = (address[:state].blank? ? 'n/a' : address[:state])
67
+ post[:zip] = address[:zip].to_s
68
+ post[:country] = address[:country].to_s
69
+ post[:phone] = address[:phone].to_s
70
+ post[:fax] = address[:fax].to_s
71
+ post[:email] = address[:email].to_s
72
+ end
73
+
74
+ if address = options[:shipping_address]
75
+ post[:shipping_firstname] = address[:first_name].to_s
76
+ post[:shipping_lastname] = address[:last_name].to_s
77
+ post[:shipping_company] = address[:company].to_s
78
+ post[:shipping_address1] = address[:address1].to_s
79
+ post[:shipping_address2] = address[:address2].to_s
80
+ post[:shipping_city] = address[:city].to_s
81
+ post[:shipping_country] = address[:country].to_s
82
+ post[:shipping_state] = (address[:state].blank? ? 'n/a' : address[:state])
83
+ post[:shipping_zip] = address[:zip].to_s
84
+ post[:shipping_email] = address[:email].to_s
85
+ end
86
+ end
87
+
88
+ def add_currency(post, money, options)
89
+ post[:currency] = options[:currency] || currency(money)
90
+ end
91
+
92
+ def add_invoice(post, options)
93
+ post[:orderdescription] = options[:description]
94
+ post[:orderid] = options[:order_id]
95
+ end
96
+
97
+ def add_creditcard(post, creditcard)
98
+ post[:ccnumber] = creditcard.number
99
+ post[:cvv] = creditcard.verification_value if creditcard.verification_value?
100
+ post[:ccexp] = expdate(creditcard)
101
+ post[:firstname] = creditcard.first_name
102
+ post[:lastname] = creditcard.last_name
103
+ end
104
+
105
+ def parse(body)
106
+ Hash[body.split('&').map{|x|x.split('=')}]
107
+ end
108
+
109
+ def commit(action, money, parameters)
110
+ parameters[:amount] = amount(money) unless action == 'void'
111
+ url = (test? ? self.test_url : self.live_url)
112
+ data = ssl_post(url, post_data(action, parameters))
113
+
114
+ response = parse(data)
115
+ response[:action] = action
116
+
117
+ message = message_from(response)
118
+ test_mode = (test? || message =~ /TESTMODE/)
119
+ Response.new(success?(response), message, response,
120
+ :test => test_mode,
121
+ :authorization => response['transactionid'],
122
+ :fraud_review => fraud_review?(response),
123
+ :avs_result => { :code => response['avsresponse'] },
124
+ :cvv_result => response['cvvresponse']
125
+ )
126
+ end
127
+
128
+ def message_from(response)
129
+ case response['response']
130
+ when '1'
131
+ 'The transaction has been approved'
132
+ when '2'
133
+ 'The transaction has been declined'
134
+ when '3'
135
+ response['responsetext']
136
+ else
137
+ 'There was an error processing the transaction'
138
+ end
139
+ end
140
+
141
+ def fraud_review?(response)
142
+ false
143
+ end
144
+
145
+ def success?(response)
146
+ (response['response'] == '1')
147
+ end
148
+
149
+ def post_data(action, parameters = {})
150
+ post = {}
151
+
152
+ post[:username] = @options[:username]
153
+ post[:password] = @options[:password]
154
+ post[:type] = action
155
+
156
+ request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
157
+ request
158
+ end
159
+ end
160
+ end
161
+ end
162
+
@@ -0,0 +1,199 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class PaystationGateway < Gateway
4
+
5
+ self.live_url = self.test_url = "https://www.paystation.co.nz/direct/paystation.dll"
6
+
7
+ # an "error code" of "0" means "No error - transaction successful"
8
+ SUCCESSFUL_RESPONSE_CODE = '0'
9
+
10
+ # an "error code" of "34" means "Future Payment Stored OK"
11
+ SUCCESSFUL_FUTURE_PAYMENT = '34'
12
+
13
+ # TODO: check this with paystation
14
+ self.supported_countries = ['NZ']
15
+
16
+ # TODO: check this with paystation (amex and diners need to be enabled)
17
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club ]
18
+
19
+ self.homepage_url = 'http://paystation.co.nz'
20
+ self.display_name = 'Paystation'
21
+
22
+ self.default_currency = 'NZD'
23
+ self.money_format = :cents
24
+
25
+ def initialize(options = {})
26
+ requires!(options, :paystation_id, :gateway_id)
27
+ super
28
+ end
29
+
30
+ def authorize(money, credit_card, options = {})
31
+ post = new_request
32
+
33
+ add_invoice(post, options)
34
+ add_amount(post, money, options)
35
+
36
+ add_credit_card(post, credit_card)
37
+
38
+ add_authorize_flag(post, options)
39
+
40
+ commit(post)
41
+ end
42
+
43
+ def capture(money, authorization_token, options = {})
44
+ post = new_request
45
+
46
+ add_invoice(post, options)
47
+ add_amount(post, money, options)
48
+
49
+ add_authorization_token(post, authorization_token, options[:credit_card_verification])
50
+
51
+ commit(post)
52
+ end
53
+
54
+ def purchase(money, payment_source, options = {})
55
+ post = new_request
56
+
57
+ add_invoice(post, options)
58
+ add_amount(post, money, options)
59
+
60
+ if payment_source.is_a?(String)
61
+ add_token(post, payment_source)
62
+ else
63
+ add_credit_card(post, payment_source)
64
+ end
65
+
66
+ add_customer_data(post, options) if options.has_key?(:customer)
67
+
68
+ commit(post)
69
+ end
70
+
71
+ def store(credit_card, options = {})
72
+ post = new_request
73
+
74
+ add_invoice(post, options)
75
+ add_credit_card(post, credit_card)
76
+ store_credit_card(post, options)
77
+
78
+ commit(post)
79
+ end
80
+
81
+ private
82
+
83
+ def new_request
84
+ {
85
+ :pi => @options[:paystation_id], # paystation account id
86
+ :gi => @options[:gateway_id], # paystation gateway id
87
+ "2p" => "t", # two-party transaction type
88
+ :nr => "t", # -- redirect??
89
+ :df => "yymm" # date format: optional sometimes, required others
90
+ }
91
+ end
92
+
93
+ def add_customer_data(post, options)
94
+ post[:mc] = options[:customer]
95
+ end
96
+
97
+ def add_invoice(post, options)
98
+ requires!(options, :order_id)
99
+
100
+ post[:ms] = options[:order_id] # "Merchant Session", must be unique per request
101
+ post[:mo] = options[:invoice] # "Order Details", displayed in Paystation Admin
102
+ post[:mr] = options[:description] # "Merchant Reference Code", seen from Paystation Admin
103
+ end
104
+
105
+ def add_credit_card(post, credit_card)
106
+
107
+ post[:cn] = credit_card.number
108
+ post[:ct] = credit_card.brand
109
+ post[:ex] = format_date(credit_card.month, credit_card.year)
110
+ post[:cc] = credit_card.verification_value if credit_card.verification_value?
111
+
112
+ end
113
+
114
+ # bill a token (stored via "store") rather than a Credit Card
115
+ def add_token(post, token)
116
+ post[:fp] = "t" # turn on "future payments" - what paystation calls Token Billing
117
+ post[:ft] = token
118
+ end
119
+
120
+ def store_credit_card(post, options)
121
+
122
+ post[:fp] = "t" # turn on "future payments" - what paystation calls Token Billing
123
+ post[:fs] = "t" # tells paystation to store right now, not bill
124
+ post[:ft] = options[:token] if options[:token] # specify a token to use that, or let Paystation generate one
125
+
126
+ end
127
+
128
+ def add_authorize_flag(post, options)
129
+ post[:pa] = "t" # tells Paystation that this is a pre-auth authorisation payment (account must be in pre-auth mode)
130
+ end
131
+
132
+ def add_authorization_token(post, auth_token, verification_value = nil)
133
+ post[:cp] = "t" # Capture Payment flag – tells Paystation this transaction should be treated as a capture payment
134
+ post[:cx] = auth_token
135
+ post[:cc] = verification_value
136
+ end
137
+
138
+ def add_amount(post, money, options)
139
+
140
+ post[:am] = amount(money)
141
+ post[:cu] = options[:currency] || currency(money)
142
+
143
+ end
144
+
145
+ def parse(xml_response)
146
+ response = {}
147
+
148
+ xml = REXML::Document.new(xml_response)
149
+
150
+ # for normal payments, the root node is <Response>
151
+ # for "future payments", it's <PaystationFuturePaymentResponse>
152
+ xml.elements.each("#{xml.root.name}/*") do |element|
153
+ response[element.name.underscore.to_sym] = element.text
154
+ end
155
+
156
+ response
157
+ end
158
+
159
+ def commit(post)
160
+
161
+ post[:tm] = "T" if test? # test mode
162
+
163
+ pstn_prefix_params = post.collect { |key, value| "pstn_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
164
+
165
+ # need include paystation param as "initiator flag for payment engine"
166
+ data = ssl_post(self.live_url, "#{pstn_prefix_params}&paystation=_empty")
167
+ response = parse(data)
168
+ message = message_from(response)
169
+
170
+ PaystationResponse.new(success?(response), message, response,
171
+ :test => (response[:tm] && response[:tm].downcase == "t"),
172
+ :authorization => response[:paystation_transaction_id]
173
+ )
174
+ end
175
+
176
+ def success?(response)
177
+ (response[:ec] == SUCCESSFUL_RESPONSE_CODE) || (response[:ec] == SUCCESSFUL_FUTURE_PAYMENT)
178
+ end
179
+
180
+ def message_from(response)
181
+ response[:em]
182
+ end
183
+
184
+ def format_date(month, year)
185
+ "#{format(year, :two_digits)}#{format(month, :two_digits)}"
186
+ end
187
+
188
+ end
189
+
190
+ class PaystationResponse < Response
191
+ # add a method to response so we can easily get the token
192
+ # for Validate transactions
193
+ def token
194
+ @params["future_payment_token"]
195
+ end
196
+ end
197
+ end
198
+ end
199
+
@@ -0,0 +1,207 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ class PaywayGateway < Gateway
4
+ self.live_url = self.test_url = 'https://ccapi.client.qvalent.com/payway/ccapi'
5
+
6
+ self.supported_countries = [ 'AU' ]
7
+ self.supported_cardtypes = [ :visa, :master, :diners_club, :american_express, :bankcard ]
8
+ self.display_name = 'Pay Way'
9
+ self.homepage_url = 'http://www.payway.com.au'
10
+ self.default_currency = 'AUD'
11
+ self.money_format = :cents
12
+
13
+ SUMMARY_CODES = {
14
+ '0' => 'Approved',
15
+ '1' => 'Declined',
16
+ '2' => 'Erred',
17
+ '3' => 'Rejected'
18
+ }
19
+
20
+ RESPONSE_CODES= {
21
+ '00' => 'Completed Successfully',
22
+ '01' => 'Refer to card issuer',
23
+ '03' => 'Invalid merchant',
24
+ '04' => 'Pick-up card',
25
+ '05' => 'Do not honour',
26
+ '08' => 'Honour only with identification',
27
+ '12' => 'Invalid transaction',
28
+ '13' => 'Invalid amount',
29
+ '14' => 'Invalid card number (no such number)',
30
+ '30' => 'Format error',
31
+ '36' => 'Restricted card',
32
+ '41' => 'Lost card',
33
+ '42' => 'No universal card',
34
+ '43' => 'Stolen card',
35
+ '51' => 'Not sufficient funds',
36
+ '54' => 'Expired card',
37
+ '61' => 'Exceeds withdrawal amount limits',
38
+ '62' => 'Restricted card',
39
+ '65' => 'Exceeds withdrawal frequency limit',
40
+ '91' => 'Issuer or switch is inoperative',
41
+ '92' => 'Financial institution or intermediate network facility cannot be found for routing',
42
+ '94' => 'Duplicate transmission',
43
+ 'Q1' => 'Unknown Buyer',
44
+ 'Q2' => 'Transaction Pending',
45
+ 'Q3' => 'Payment Gateway Connection Error',
46
+ 'Q4' => 'Payment Gateway Unavailable',
47
+ 'Q5' => 'Invalid Transaction',
48
+ 'Q6' => 'Duplicate Transaction - requery to determine status',
49
+ 'QA' => 'Invalid parameters or Initialisation failed',
50
+ 'QB' => 'Order type not currently supported',
51
+ 'QC' => 'Invalid Order Type',
52
+ 'QD' => 'Invalid Payment Amount - Payment amount less than minimum/exceeds maximum allowed limit',
53
+ 'QE' => 'Internal Error',
54
+ 'QF' => 'Transaction Failed',
55
+ 'QG' => 'Unknown Customer Order Number',
56
+ 'QH' => 'Unknown Customer Username or Password',
57
+ 'QI' => 'Transaction incomplete - contact Westpac to confirm reconciliation',
58
+ 'QJ' => 'Invalid Client Certificate',
59
+ 'QK' => 'Unknown Customer Merchant',
60
+ 'QL' => 'Business Group not configured for customer',
61
+ 'QM' => 'Payment Instrument not configured for customer',
62
+ 'QN' => 'Configuration Error',
63
+ 'QO' => 'Missing Payment Instrument',
64
+ 'QP' => 'Missing Supplier Account',
65
+ 'QQ' => 'Invalid Credit Card Verification Number',
66
+ 'QR' => 'Transaction Retry',
67
+ 'QS' => 'Transaction Successful',
68
+ 'QT' => 'Invalid currency',
69
+ 'QU' => 'Unknown Customer IP Address',
70
+ 'QV' => 'Invalid Original Order Number specified for Refund, Refund amount exceeds capture amount, or Previous capture was not approved',
71
+ 'QW' => 'Invalid Reference Number',
72
+ 'QX' => 'Network Error has occurred',
73
+ 'QY' => 'Card Type Not Accepted',
74
+ 'QZ' => 'Zero value transaction'
75
+ }
76
+
77
+ TRANSACTIONS = {
78
+ :authorize => 'preauth',
79
+ :purchase => 'capture',
80
+ :capture => 'captureWithoutAuth',
81
+ :status => 'query',
82
+ :refund => 'refund',
83
+ :store => 'registerAccount'
84
+ }
85
+
86
+ def initialize(options={})
87
+ @options = options
88
+
89
+ @options[:merchant] ||= 'TEST' if test?
90
+ requires!(options, :username, :password, :merchant, :pem)
91
+
92
+ @options[:eci] ||= 'SSL'
93
+ end
94
+
95
+ def authorize(amount, payment_method, options={})
96
+ requires!(options, :order_id)
97
+
98
+ post = {}
99
+ add_payment_method(post, payment_method)
100
+ add_order(post, amount, options)
101
+ commit(:authorize, post)
102
+ end
103
+
104
+ def capture(amount, authorization, options={})
105
+ requires!(options, :order_id)
106
+
107
+ post = {}
108
+ add_reference(post, authorization)
109
+ add_order(post, amount, options)
110
+ commit(:capture, post)
111
+ end
112
+
113
+ def purchase(amount, payment_method, options={})
114
+ requires!(options, :order_id)
115
+
116
+ post = {}
117
+ add_payment_method(post, payment_method)
118
+ add_order(post, amount, options)
119
+ commit(:purchase, post)
120
+ end
121
+
122
+ def refund(amount, authorization, options={})
123
+ requires!(options, :order_id)
124
+
125
+ post = {}
126
+ add_reference(post, authorization)
127
+ add_order(post, amount, options)
128
+ commit(:refund, post)
129
+ end
130
+
131
+ def store(credit_card, options={})
132
+ requires!(options, :billing_id)
133
+
134
+ post = {}
135
+ add_payment_method(post, credit_card)
136
+ add_payment_method(post, options[:billing_id])
137
+ commit(:store, post)
138
+ end
139
+
140
+ def status(options={})
141
+ requires!(options, :order_id)
142
+
143
+ commit(:status, 'customer.orderNumber' => options[:order_id])
144
+ end
145
+
146
+ private
147
+
148
+ def add_payment_method(post, payment_method)
149
+ if payment_method.respond_to?(:number)
150
+ post['card.cardHolderName'] = "#{payment_method.first_name} #{payment_method.last_name}"
151
+ post['card.PAN'] = payment_method.number
152
+ post['card.CVN'] = payment_method.verification_value
153
+ post['card.expiryYear'] = payment_method.year.to_s[-2,2]
154
+ post['card.expiryMonth'] = sprintf('%02d', payment_method.month)
155
+ else
156
+ post['customer.customerReferenceNumber'] = payment_method
157
+ end
158
+ end
159
+
160
+ def add_reference(post, reference)
161
+ post['customer.originalOrderNumber'] = reference
162
+ end
163
+
164
+ def add_order(post, amount, options)
165
+ post['order.ECI'] = @options[:eci]
166
+ post['order.amount'] = amount
167
+ post['card.currency'] = (options[:currency] || currency(amount))
168
+ post['customer.orderNumber'] = options[:order_id][0...20]
169
+ end
170
+
171
+ def add_auth(post)
172
+ post['customer.username'] = @options[:username]
173
+ post['customer.password'] = @options[:password]
174
+ post['customer.merchant'] = @options[:merchant]
175
+ end
176
+
177
+ # Creates the request and returns the summarized result
178
+ def commit(action, post)
179
+ add_auth(post)
180
+ post.merge!('order.type' => TRANSACTIONS[action])
181
+
182
+ request = post.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
183
+ response = ssl_post(self.live_url, request)
184
+
185
+ params = {}
186
+ CGI.parse(response).each_pair do |key, value|
187
+ actual_key = key.split(".").last
188
+ params[actual_key.underscore.to_sym] = value[0]
189
+ end
190
+
191
+ message = "#{SUMMARY_CODES[params[:summary_code]]} - #{RESPONSE_CODES[params[:response_code]]}"
192
+
193
+ success = (params[:summary_code] ? (params[:summary_code] == "0") : (params[:response_code] == "00"))
194
+
195
+ Response.new(success, message, params,
196
+ :test => (@options[:merchant].to_s == "TEST"),
197
+ :authorization => post[:order_number]
198
+ )
199
+ rescue ActiveMerchant::ResponseError => e
200
+ raise unless e.response.code == '403'
201
+ return Response.new(false, "Invalid credentials", {}, :test => test?)
202
+ rescue ActiveMerchant::ClientCertificateError
203
+ return Response.new(false, "Invalid certificate", {}, :test => test?)
204
+ end
205
+ end
206
+ end
207
+ end