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,288 @@
1
+ require "nokogiri"
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class HpsGateway < Gateway
6
+ self.live_url = 'https://posgateway.secureexchange.net/Hps.Exchange.PosGateway/PosGatewayService.asmx?wsdl'
7
+ self.test_url = 'https://posgateway.cert.secureexchange.net/Hps.Exchange.PosGateway/PosGatewayService.asmx?wsdl'
8
+
9
+ self.supported_countries = ['US']
10
+ self.default_currency = 'USD'
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jbc, :diners_club]
12
+
13
+ self.homepage_url = 'http://developer.heartlandpaymentsystems.com/SecureSubmit/'
14
+ self.display_name = 'Heartland Payment Systems'
15
+
16
+ self.money_format = :dollars
17
+
18
+ def initialize(options={})
19
+ requires!(options, :secret_api_key)
20
+ super
21
+ end
22
+
23
+ def authorize(money, card_or_token, options={})
24
+ commit('CreditAuth') do |xml|
25
+ add_amount(xml, money)
26
+ add_allow_dup(xml)
27
+ add_customer_data(xml, card_or_token, options)
28
+ add_details(xml, options)
29
+ add_payment(xml, card_or_token, options)
30
+ end
31
+ end
32
+
33
+ def capture(money, transaction_id, options={})
34
+ commit('CreditAddToBatch') do |xml|
35
+ add_amount(xml, money)
36
+ add_reference(xml, transaction_id)
37
+ end
38
+ end
39
+
40
+ def purchase(money, card_or_token, options={})
41
+ commit('CreditSale') do |xml|
42
+ add_amount(xml, money)
43
+ add_allow_dup(xml)
44
+ add_customer_data(xml, card_or_token,options)
45
+ add_details(xml, options)
46
+ add_payment(xml, card_or_token, options)
47
+ end
48
+ end
49
+
50
+ def refund(money, transaction_id, options={})
51
+ commit('CreditReturn') do |xml|
52
+ add_amount(xml, money)
53
+ add_allow_dup(xml)
54
+ add_reference(xml, transaction_id)
55
+ add_customer_data(xml, transaction_id,options)
56
+ add_details(xml, options)
57
+ end
58
+ end
59
+
60
+ def verify(card_or_token, options={})
61
+ commit('CreditAccountVerify') do |xml|
62
+ add_customer_data(xml, card_or_token, options)
63
+ add_payment(xml, card_or_token, options)
64
+ end
65
+ end
66
+
67
+ def void(transaction_id, options={})
68
+ commit('CreditVoid') do |xml|
69
+ add_reference(xml, transaction_id)
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def add_reference(xml, transaction_id)
76
+ xml.hps :GatewayTxnId, transaction_id
77
+ end
78
+
79
+ def add_amount(xml, money)
80
+ xml.hps :Amt, amount(money) if money
81
+ end
82
+
83
+ def add_customer_data(xml, credit_card, options)
84
+ xml.hps :CardHolderData do
85
+ if credit_card.respond_to?(:number)
86
+ xml.hps :CardHolderFirstName, credit_card.first_name if credit_card.first_name
87
+ xml.hps :CardHolderLastName, credit_card.last_name if credit_card.last_name
88
+ end
89
+
90
+ xml.hps :CardHolderEmail, options[:email] if options[:email]
91
+ xml.hps :CardHolderPhone, options[:phone] if options[:phone]
92
+
93
+ if(billing_address = (options[:billing_address] || options[:address]))
94
+ xml.hps :CardHolderAddr, billing_address[:address1] if billing_address[:address1]
95
+ xml.hps :CardHolderCity, billing_address[:city] if billing_address[:city]
96
+ xml.hps :CardHolderState, billing_address[:state] if billing_address[:state]
97
+ xml.hps :CardHolderZip, billing_address[:zip] if billing_address[:zip]
98
+ end
99
+ end
100
+ end
101
+
102
+ def add_payment(xml, card_or_token, options)
103
+ xml.hps :CardData do
104
+ if card_or_token.respond_to?(:number)
105
+ if card_or_token.track_data
106
+ xml.tag!("hps:TrackData", 'method'=>'swipe') do
107
+ xml.text! card_or_token.track_data
108
+ end
109
+ if options[:encryption_type]
110
+ xml.hps :EncryptionData do
111
+ xml.hps :Version, options[:encryption_type]
112
+ if options[:encryption_type] == '02'
113
+ xml.hps :EncryptedTrackNumber, options[:encrypted_track_number]
114
+ xml.hps :KTB, options[:ktb]
115
+ end
116
+ end
117
+ end
118
+ else
119
+ xml.hps :ManualEntry do
120
+ xml.hps :CardNbr, card_or_token.number
121
+ xml.hps :ExpMonth, card_or_token.month
122
+ xml.hps :ExpYear, card_or_token.year
123
+ xml.hps :CVV2, card_or_token.verification_value if card_or_token.verification_value
124
+ xml.hps :CardPresent, 'N'
125
+ xml.hps :ReaderPresent, 'N'
126
+ end
127
+ end
128
+ else
129
+ xml.hps :TokenData do
130
+ xml.hps :TokenValue, card_or_token
131
+ end
132
+ end
133
+ xml.hps :TokenRequest, (options[:store] ? 'Y' : 'N')
134
+ end
135
+ end
136
+
137
+ def add_details(xml, options)
138
+ xml.hps :AdditionalTxnFields do
139
+ xml.hps :Description, options[:description] if options[:description]
140
+ xml.hps :InvoiceNbr, options[:order_id] if options[:order_id]
141
+ xml.hps :CustomerID, options[:customer_id] if options[:customer_id]
142
+ end
143
+ end
144
+
145
+ def add_allow_dup(xml)
146
+ xml.hps :AllowDup, 'Y'
147
+ end
148
+
149
+ def build_request(action)
150
+ xml = Builder::XmlMarkup.new(encoding: 'UTF-8')
151
+ xml.instruct!(:xml, encoding: 'UTF-8')
152
+ xml.SOAP :Envelope, {
153
+ 'xmlns:SOAP' => 'http://schemas.xmlsoap.org/soap/envelope/',
154
+ 'xmlns:hps' => 'http://Hps.Exchange.PosGateway' } do
155
+ xml.SOAP :Body do
156
+ xml.hps :PosRequest do
157
+ xml.hps 'Ver1.0'.to_sym do
158
+ xml.hps :Header do
159
+ xml.hps :SecretAPIKey, @options[:secret_api_key]
160
+ xml.hps :DeveloperID, @options[:developer_id] if @options[:developer_id]
161
+ xml.hps :VersionNbr, @options[:version_number] if @options[:version_number]
162
+ xml.hps :SiteTrace, @options[:site_trace] if @options[:site_trace]
163
+ end
164
+ xml.hps :Transaction do
165
+ xml.hps action.to_sym do
166
+ if %w(CreditVoid CreditAddToBatch).include?(action)
167
+ yield(xml)
168
+ else
169
+ xml.hps :Block1 do
170
+ yield(xml)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ xml.target!
180
+ end
181
+
182
+ def parse(raw)
183
+ response = {}
184
+
185
+ doc = Nokogiri::XML(raw)
186
+ doc.remove_namespaces!
187
+ if(header = doc.xpath("//Header").first)
188
+ header.elements.each do |node|
189
+ if (node.elements.size == 0)
190
+ response[node.name] = node.text
191
+ else
192
+ node.elements.each do |childnode|
193
+ response[childnode.name] = childnode.text
194
+ end
195
+ end
196
+ end
197
+ end
198
+ if(transaction = doc.xpath("//Transaction/*[1]").first)
199
+ transaction.elements.each do |node|
200
+ response[node.name] = node.text
201
+ end
202
+ end
203
+ if(fault = doc.xpath("//Fault/Reason/Text").first)
204
+ response["Fault"] = fault.text
205
+ end
206
+
207
+ response
208
+ end
209
+
210
+ def commit(action, &request)
211
+ data = build_request(action, &request)
212
+
213
+ response = begin
214
+ parse(ssl_post((test? ? test_url : live_url), data, 'Content-type' => 'text/xml'))
215
+ rescue ResponseError => e
216
+ parse(e.response.body)
217
+ end
218
+
219
+ ActiveMerchant::Billing::Response.new(
220
+ successful?(response),
221
+ message_from(response),
222
+ response,
223
+ test: test?,
224
+ authorization: authorization_from(response),
225
+ avs_result: {
226
+ code: response['AVSRsltCode'],
227
+ message: response['AVSRsltText']
228
+ },
229
+ cvv_result: response['CVVRsltCode']
230
+ )
231
+ end
232
+
233
+ def successful?(response)
234
+ (
235
+ (response["GatewayRspCode"] == "0") &&
236
+ ((response["RspCode"] || "00") == "00" || response["RspCode"] == "85")
237
+ )
238
+ end
239
+
240
+ def message_from(response)
241
+ if(response["Fault"])
242
+ response["Fault"]
243
+ elsif(response["GatewayRspCode"] == "0")
244
+ if(response["RspCode"] != "00" && response["RspCode"] != "85")
245
+ issuer_message(response["RspCode"])
246
+ else
247
+ response['GatewayRspMsg']
248
+ end
249
+ else
250
+ (GATEWAY_MESSAGES[response["GatewayRspCode"]] || response["GatewayRspMsg"])
251
+ end
252
+ end
253
+
254
+ def authorization_from(response)
255
+ response['GatewayTxnId']
256
+ end
257
+
258
+ def test?
259
+ (@options[:secret_api_key] && @options[:secret_api_key].include?('_cert_'))
260
+ end
261
+
262
+ ISSUER_MESSAGES = {
263
+ "13" => "Must be greater than or equal 0.",
264
+ "14" => "The card number is incorrect.",
265
+ "54" => "The card has expired.",
266
+ "55" => "The 4-digit pin is invalid.",
267
+ "75" => "Maximum number of pin retries exceeded.",
268
+ "80" => "Card expiration date is invalid.",
269
+ "80" => "Card expiration date is invalid.",
270
+ "86" => "Can't verify card pin number."
271
+ }
272
+ def issuer_message(code)
273
+ return "The card was declined." if %w(02 03 04 05 41 43 44 51 56 61 62 63 65 78).include?(code)
274
+ return "An error occurred while processing the card." if %w(06 07 12 15 19 12 52 53 57 58 76 77 91 96 EC).include?(code)
275
+ return "The card's security code is incorrect." if %w(EB N7).include?(code)
276
+ ISSUER_MESSAGES[code]
277
+ end
278
+
279
+ GATEWAY_MESSAGES = {
280
+ "-2" => "Authentication error. Please double check your service configuration.",
281
+ "12" => "Invalid CPC data.",
282
+ "13" => "Invalid card data.",
283
+ "14" => "The card number is not a valid credit card number.",
284
+ "30" => "Gateway timed out."
285
+ }
286
+ end
287
+ end
288
+ end
@@ -0,0 +1,251 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class IatsPaymentsGateway < Gateway
4
+ class_attribute :live_na_url, :live_uk_url
5
+
6
+ self.live_na_url = 'https://www.iatspayments.com/NetGate'
7
+ self.live_uk_url = 'https://www.uk.iatspayments.com/NetGate'
8
+
9
+ self.supported_countries = %w(AU BR CA CH DE DK ES FI FR GR HK IE IT NL NO PT SE SG TR GB US)
10
+ self.default_currency = 'USD'
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
12
+
13
+ self.homepage_url = 'http://home.iatspayments.com/'
14
+ self.display_name = 'iATS Payments'
15
+
16
+ ACTIONS = {
17
+ purchase: "ProcessCreditCardV1",
18
+ refund: "ProcessCreditCardRefundWithTransactionIdV1",
19
+ store: "CreateCreditCardCustomerCodeV1",
20
+ unstore: "DeleteCustomerCodeV1"
21
+ }
22
+
23
+ def initialize(options={})
24
+ if(options[:login])
25
+ ActiveMerchant.deprecated("The 'login' option is deprecated in favor of 'agent_code' and will be removed in a future version.")
26
+ options[:agent_code] = options[:login]
27
+ end
28
+
29
+ options[:region] = 'na' unless options[:region]
30
+
31
+ requires!(options, :agent_code, :password, :region)
32
+ super
33
+ end
34
+
35
+ def purchase(money, payment, options={})
36
+ post = {}
37
+ add_invoice(post, money, options)
38
+ add_payment(post, payment)
39
+ add_address(post, options)
40
+ add_ip(post, options)
41
+ add_description(post, options)
42
+
43
+ commit(:purchase, post)
44
+ end
45
+
46
+ def refund(money, authorization, options={})
47
+ post = {}
48
+ post[:transaction_id] = authorization
49
+ add_invoice(post, -money, options)
50
+ add_ip(post, options)
51
+ add_description(post, options)
52
+
53
+ commit(:refund, post)
54
+ end
55
+
56
+ def store(credit_card, options = {})
57
+ post = {}
58
+ add_payment(post, credit_card)
59
+ add_address(post, options)
60
+ add_ip(post, options)
61
+ add_description(post, options)
62
+ add_store_defaults(post)
63
+
64
+ commit(:store, post)
65
+ end
66
+
67
+ def unstore(authorization, options = {})
68
+ post = {}
69
+ post[:customer_code] = authorization
70
+ add_ip(post, options)
71
+
72
+ commit(:unstore, post)
73
+ end
74
+
75
+ private
76
+
77
+ def add_ip(post, options)
78
+ post[:customer_ip_address] = options[:ip] if options.has_key?(:ip)
79
+ end
80
+
81
+ def add_address(post, options)
82
+ billing_address = options[:billing_address] || options[:address]
83
+ if(billing_address)
84
+ post[:address] = billing_address[:address1]
85
+ post[:city] = billing_address[:city]
86
+ post[:state] = billing_address[:state]
87
+ post[:zip_code] = billing_address[:zip]
88
+ end
89
+ end
90
+
91
+ def add_invoice(post, money, options)
92
+ post[:invoice_num] = options[:order_id] if options[:order_id]
93
+ post[:total] = amount(money)
94
+ end
95
+
96
+ def add_description(post, options)
97
+ post[:comment] = options[:description] if options[:description]
98
+ end
99
+
100
+ def add_payment(post, payment)
101
+ post[:first_name] = payment.first_name
102
+ post[:last_name] = payment.last_name
103
+ post[:credit_card_num] = payment.number
104
+ post[:credit_card_expiry] = expdate(payment)
105
+ post[:cvv2] = payment.verification_value if payment.verification_value?
106
+ post[:mop] = creditcard_brand(payment.brand)
107
+ end
108
+
109
+ def add_store_defaults(post)
110
+ post[:recurring] = false
111
+ post[:begin_date] = Time.now.xmlschema
112
+ post[:end_date] = Time.now.xmlschema
113
+ post[:amount] = 0
114
+ end
115
+
116
+ def expdate(creditcard)
117
+ year = sprintf("%.4i", creditcard.year)
118
+ month = sprintf("%.2i", creditcard.month)
119
+
120
+ "#{month}/#{year[-2..-1]}"
121
+ end
122
+
123
+ def creditcard_brand(brand)
124
+ case brand
125
+ when "visa" then "VISA"
126
+ when "master" then "MC"
127
+ when "discover" then "DSC"
128
+ when "american_express" then "AMX"
129
+ when "maestro" then "MAESTR"
130
+ else
131
+ raise "Unhandled credit card brand #{brand}"
132
+ end
133
+ end
134
+
135
+ def commit(action, parameters)
136
+ response = parse(ssl_post(url(action), post_data(action, parameters),
137
+ { 'Content-Type' => 'application/soap+xml; charset=utf-8'}))
138
+
139
+ Response.new(
140
+ success_from(response),
141
+ message_from(response),
142
+ response,
143
+ authorization: authorization_from(action, response),
144
+ test: test?
145
+ )
146
+ end
147
+
148
+ def endpoints
149
+ {
150
+ purchase: "ProcessLink.asmx",
151
+ refund: "ProcessLink.asmx",
152
+ store: "CustomerLink.asmx",
153
+ unstore: "CustomerLink.asmx"
154
+ }
155
+ end
156
+
157
+ def url(action)
158
+ base_url = @options[:region] == 'uk' ? live_uk_url : live_na_url
159
+ "#{base_url}/#{endpoints[action]}?op=#{ACTIONS[action]}"
160
+ end
161
+
162
+ def parse(body)
163
+ response = {}
164
+ hashify_xml!(body, response)
165
+ response
166
+ end
167
+
168
+ def dexmlize_param_name(name)
169
+ names = {
170
+ 'AUTHORIZATIONRESULT' => :authorization_result,
171
+ 'SETTLEMENTBATCHDATE' => :settlement_batch_date,
172
+ 'SETTLEMENTDATE' => :settlement_date,
173
+ 'TRANSACTIONID' => :transaction_id
174
+ }
175
+ names[name] || name.to_s.downcase.intern
176
+ end
177
+
178
+ def hashify_xml!(xml, response)
179
+ xml = REXML::Document.new(xml)
180
+
181
+ xml.elements.each("//IATSRESPONSE/*") do |node|
182
+ recursively_parse_element(node, response)
183
+ end
184
+ end
185
+
186
+ def recursively_parse_element(node, response)
187
+ if(node.has_elements?)
188
+ node.elements.each { |n| recursively_parse_element(n, response) }
189
+ else
190
+ response[dexmlize_param_name(node.name)] = (node.text ? node.text.strip : nil)
191
+ end
192
+ end
193
+
194
+ def successful_result_message?(response)
195
+ response[:authorization_result].start_with?('OK')
196
+ end
197
+
198
+ def success_from(response)
199
+ response[:status] == "Success" && successful_result_message?(response)
200
+ end
201
+
202
+ def message_from(response)
203
+ if(!successful_result_message?(response))
204
+ return response[:authorization_result].strip
205
+ elsif(response[:status] == 'Failure')
206
+ return response[:errors]
207
+ else
208
+ response[:status]
209
+ end
210
+ end
211
+
212
+ def authorization_from(action, response)
213
+ if [:store, :unstore].include?(action)
214
+ response[:customercode]
215
+ else
216
+ response[:transaction_id]
217
+ end
218
+ end
219
+
220
+ def envelope_namespaces
221
+ {
222
+ "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
223
+ "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
224
+ "xmlns:soap12" => "http://www.w3.org/2003/05/soap-envelope"
225
+ }
226
+ end
227
+
228
+ def post_data(action, parameters = {})
229
+ xml = Builder::XmlMarkup.new
230
+ xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
231
+ xml.tag! 'soap12:Envelope', envelope_namespaces do
232
+ xml.tag! 'soap12:Body' do
233
+ xml.tag! ACTIONS[action], { "xmlns" => "https://www.iatspayments.com/NetGate/" } do
234
+ xml.tag!('agentCode', @options[:agent_code])
235
+ xml.tag!('password', @options[:password])
236
+ parameters.each do |name, value|
237
+ xml.tag!(xmlize_param_name(name), value)
238
+ end
239
+ end
240
+ end
241
+ end
242
+ xml.target!
243
+ end
244
+
245
+ def xmlize_param_name(name)
246
+ names = { customer_ip_address: 'customerIPAddress' }
247
+ names[name] || name.to_s.camelcase(:lower)
248
+ end
249
+ end
250
+ end
251
+ end