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,256 @@
1
+ require 'json'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # For more information on Balanced visit https://www.balancedpayments.com
6
+ # or visit #balanced on irc.freenode.net
7
+ #
8
+ # Instantiate a instance of BalancedGateway by passing through your
9
+ # Balanced API key secret.
10
+ #
11
+ # ==== To obtain an API key of your own
12
+ #
13
+ # 1. Visit https://www.balancedpayments.com
14
+ # 2. Click "Get started"
15
+ # 3. The next screen will give you a test API key of your own
16
+ # 4. When you're ready to generate a production API key click the "Go
17
+ # live" button on the Balanced dashboard and fill in your marketplace
18
+ # details.
19
+ class BalancedGateway < Gateway
20
+ VERSION = "2.0.0"
21
+
22
+ self.live_url = 'https://api.balancedpayments.com'
23
+
24
+ self.supported_countries = ['US']
25
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
26
+ self.homepage_url = 'https://www.balancedpayments.com/'
27
+ self.display_name = 'Balanced'
28
+ self.money_format = :cents
29
+
30
+ # Creates a new BalancedGateway
31
+ #
32
+ # ==== Options
33
+ #
34
+ # * <tt>:login</tt> -- The Balanced API Secret (REQUIRED)
35
+ def initialize(options = {})
36
+ requires!(options, :login)
37
+ super
38
+ end
39
+
40
+ def purchase(money, payment_method, options = {})
41
+ post = {}
42
+ add_amount(post, money)
43
+ post[:description] = options[:description]
44
+ add_common_params(post, options)
45
+
46
+ MultiResponse.run do |r|
47
+ identifier = if(payment_method.respond_to?(:number))
48
+ r.process{store(payment_method, options)}
49
+ r.authorization
50
+ else
51
+ payment_method
52
+ end
53
+ r.process{commit("debits", "cards/#{card_identifier_from(identifier)}/debits", post)}
54
+ end
55
+ end
56
+
57
+ def authorize(money, payment_method, options = {})
58
+ post = {}
59
+ add_amount(post, money)
60
+ post[:description] = options[:description]
61
+ add_common_params(post, options)
62
+
63
+ MultiResponse.run do |r|
64
+ identifier = if(payment_method.respond_to?(:number))
65
+ r.process{store(payment_method, options)}
66
+ r.authorization
67
+ else
68
+ payment_method
69
+ end
70
+ r.process{commit("card_holds", "cards/#{card_identifier_from(identifier)}/card_holds", post)}
71
+ end
72
+ end
73
+
74
+ def capture(money, identifier, options = {})
75
+ post = {}
76
+ add_amount(post, money)
77
+ post[:description] = options[:description] if options[:description]
78
+ add_common_params(post, options)
79
+
80
+ commit("debits", "card_holds/#{reference_identifier_from(identifier)}/debits", post)
81
+ end
82
+
83
+ def void(identifier, options = {})
84
+ post = {}
85
+ post[:is_void] = true
86
+ add_common_params(post, options)
87
+
88
+ commit("card_holds", "card_holds/#{reference_identifier_from(identifier)}", post, :put)
89
+ end
90
+
91
+ def refund(money, identifier, options = {})
92
+ post = {}
93
+ add_amount(post, money)
94
+ post[:description] = options[:description]
95
+ add_common_params(post, options)
96
+
97
+ commit("refunds", "debits/#{reference_identifier_from(identifier)}/refunds", post)
98
+ end
99
+
100
+ def store(credit_card, options={})
101
+ post = {}
102
+
103
+ post[:number] = credit_card.number
104
+ post[:expiration_month] = credit_card.month
105
+ post[:expiration_year] = credit_card.year
106
+ post[:cvv] = credit_card.verification_value if credit_card.verification_value?
107
+ post[:name] = credit_card.name if credit_card.name
108
+
109
+ add_address(post, options)
110
+
111
+ commit("cards", "cards", post)
112
+ end
113
+
114
+ private
115
+
116
+ def reference_identifier_from(identifier)
117
+ case identifier
118
+ when %r{\|}
119
+ uri = identifier.
120
+ split("|").
121
+ detect{|part| part.size > 0}
122
+ uri.split("/")[2]
123
+ when %r{\/}
124
+ identifier.split("/")[5]
125
+ else
126
+ identifier
127
+ end
128
+ end
129
+
130
+ def card_identifier_from(identifier)
131
+ identifier.split("/").last
132
+ end
133
+
134
+ def add_amount(post, money)
135
+ post[:amount] = amount(money) if money
136
+ end
137
+
138
+ def add_address(post, options)
139
+ address = (options[:billing_address] || options[:address])
140
+ if(address && address[:zip].present?)
141
+ post[:address] = {}
142
+ post[:address][:line1] = address[:address1] if address[:address1]
143
+ post[:address][:line2] = address[:address2] if address[:address2]
144
+ post[:address][:city] = address[:city] if address[:city]
145
+ post[:address][:state] = address[:state] if address[:state]
146
+ post[:address][:postal_code] = address[:zip] if address[:zip]
147
+ post[:address][:country_code] = address[:country] if address[:country]
148
+ end
149
+ end
150
+
151
+ def add_common_params(post, options)
152
+ post[:appears_on_statement_as] = options[:appears_on_statement_as]
153
+ post[:on_behalf_of_uri] = options[:on_behalf_of_uri]
154
+ post[:meta] = options[:meta]
155
+ end
156
+
157
+ def commit(entity_name, path, post, method=:post)
158
+ raw_response = begin
159
+ parse(ssl_request(
160
+ method,
161
+ live_url + "/#{path}",
162
+ post_data(post),
163
+ headers
164
+ ))
165
+ rescue ResponseError => e
166
+ raise unless(e.response.code.to_s =~ /4\d\d/)
167
+ parse(e.response.body)
168
+ end
169
+
170
+ Response.new(
171
+ success_from(entity_name, raw_response),
172
+ message_from(raw_response),
173
+ raw_response,
174
+ authorization: authorization_from(entity_name, raw_response),
175
+ test: test?,
176
+ )
177
+ end
178
+
179
+ def success_from(entity_name, raw_response)
180
+ entity = (raw_response[entity_name] || []).first
181
+ if(!entity)
182
+ false
183
+ elsif((entity_name == "refunds") && entity.include?("status"))
184
+ %w(succeeded pending).include?(entity["status"])
185
+ elsif(entity.include?("status"))
186
+ (entity["status"] == "succeeded")
187
+ elsif(entity_name == "cards")
188
+ !!entity["id"]
189
+ else
190
+ false
191
+ end
192
+ end
193
+
194
+ def message_from(raw_response)
195
+ if(raw_response["errors"])
196
+ error = raw_response["errors"].first
197
+ (error["additional"] || error["message"] || error["description"])
198
+ else
199
+ "Success"
200
+ end
201
+ end
202
+
203
+ def authorization_from(entity_name, raw_response)
204
+ entity = (raw_response[entity_name] || []).first
205
+ (entity && entity["id"])
206
+ end
207
+
208
+ def parse(body)
209
+ JSON.parse(body)
210
+ rescue JSON::ParserError
211
+ message = 'Invalid response received from the Balanced API. Please contact support@balancedpayments.com if you continue to receive this message.'
212
+ message += " (The raw response returned by the API was #{raw_response.inspect})"
213
+ {
214
+ "errors" => [{
215
+ "message" => message
216
+ }]
217
+ }
218
+ end
219
+
220
+ def post_data(params)
221
+ return nil unless params
222
+
223
+ params.map do |key, value|
224
+ next if value.blank?
225
+ if value.is_a?(Hash)
226
+ h = {}
227
+ value.each do |k, v|
228
+ h["#{key}[#{k}]"] = v unless v.blank?
229
+ end
230
+ post_data(h)
231
+ else
232
+ "#{key}=#{CGI.escape(value.to_s)}"
233
+ end
234
+ end.compact.join("&")
235
+ end
236
+
237
+ def headers
238
+ @@ua ||= JSON.dump(
239
+ bindings_version: ActiveMerchant::VERSION,
240
+ lang: 'ruby',
241
+ lang_version: "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})",
242
+ lib_version: BalancedGateway::VERSION,
243
+ platform: RUBY_PLATFORM,
244
+ publisher: 'active_merchant'
245
+ )
246
+
247
+ {
248
+ "Authorization" => "Basic " + Base64.encode64(@options[:login].to_s + ":").strip,
249
+ "User-Agent" => "Balanced/v1.1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
250
+ "Accept" => "application/vnd.api+json;revision=1.1",
251
+ "X-Balanced-User-Agent" => @@ua,
252
+ }
253
+ end
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,225 @@
1
+ require 'nokogiri'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # For more information visit {Bank Frick Acquiring Services}[http://www.bankfrickacquiring.com/merchantsolutions_en.html]
6
+ #
7
+ # Written by Piers Chambers (Varyonic.com)
8
+ class BankFrickGateway < Gateway
9
+ self.test_url = 'https://test.ctpe.io/payment/ctpe'
10
+ self.live_url = 'https://ctpe.io/payment/ctpe'
11
+
12
+ self.supported_countries = ['LI','US']
13
+ self.default_currency = 'EUR'
14
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
15
+
16
+ self.homepage_url = 'http://www.bankfrickacquiring.com/'
17
+ self.display_name = 'Bank Frick'
18
+
19
+ # The set of supported transactions for this gateway.
20
+ # More operations are supported by the gateway itself, but
21
+ # are not supported in this library.
22
+ SUPPORTED_TRANSACTIONS = {
23
+ 'sale' => 'CC.DB',
24
+ 'authonly' => 'CC.PA',
25
+ 'capture' => 'CC.CP',
26
+ 'refund' => 'CC.RF',
27
+ 'void' => 'CC.RV',
28
+ }
29
+
30
+ def initialize(options={})
31
+ requires!(options, :sender, :channel, :userid, :userpwd)
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, payment, options)
40
+ add_customer_data(post, options)
41
+
42
+ commit('sale', post)
43
+ end
44
+
45
+ def authorize(money, payment, options={})
46
+ post = {}
47
+ add_invoice(post, money, options)
48
+ add_payment(post, payment)
49
+ add_address(post, payment, options)
50
+ add_customer_data(post, options)
51
+
52
+ commit('authonly', post)
53
+ end
54
+
55
+ def capture(money, authorization, options={})
56
+ post = {}
57
+ post[:authorization] = authorization
58
+ add_invoice(post, money, options)
59
+
60
+ commit('capture', post)
61
+ end
62
+
63
+ def refund(money, authorization, options={})
64
+ post = {}
65
+ post[:authorization] = authorization
66
+ add_invoice(post, money, options)
67
+
68
+ commit('refund', post)
69
+ end
70
+
71
+ def void(authorization, options={})
72
+ post = {}
73
+ post[:authorization] = authorization
74
+
75
+ commit('void', post)
76
+ end
77
+
78
+ def verify(credit_card, options={})
79
+ MultiResponse.run(:use_first_response) do |r|
80
+ r.process { authorize(100, credit_card, options) }
81
+ r.process(:ignore_result) { void(r.authorization, options) }
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def add_customer_data(post, options)
88
+ post[:email] = options[:email] || 'noone@example.com'
89
+ post[:ip] = options[:ip] || '0.0.0.0'
90
+ end
91
+
92
+ def add_address(post, creditcard, options)
93
+ if address = options[:billing_address] || options[:address]
94
+ post[:address] = address[:address1].to_s
95
+ post[:company] = address[:company].to_s
96
+ post[:phone] = address[:phone].to_s.gsub(/[^0-9]/, '') || "0000000"
97
+ post[:zip] = address[:zip].to_s
98
+ post[:city] = address[:city].to_s
99
+ post[:country] = address[:country].to_s
100
+ post[:state] = address[:state].blank? ? 'n/a' : address[:state]
101
+ end
102
+ end
103
+
104
+ def add_invoice(post, money, options)
105
+ post[:order_id] = options[:order_id] if post.has_key? :order_id
106
+ post[:amount] = amount(money)
107
+ post[:currency] = (options[:currency] || currency(money))
108
+ post[:description] = options[:description]
109
+ end
110
+
111
+ def add_payment(post, payment)
112
+ post[:first_name] = payment.first_name
113
+ post[:last_name] = payment.last_name
114
+ post[:brand] = payment.brand
115
+ post[:card_num] = payment.number
116
+ post[:card_code] = payment.verification_value if payment.verification_value?
117
+ post[:exp_year] = payment.year
118
+ post[:exp_month] = payment.month
119
+ end
120
+
121
+ def parse(body)
122
+ results = {}
123
+ xml = Nokogiri::XML(body)
124
+ resp = xml.xpath("//Response/Transaction/Identification")
125
+ resp.children.each do |element|
126
+ results[element.name.downcase.to_sym] = element.text
127
+ end
128
+ resp = xml.xpath("//Response/Transaction/Processing")
129
+ resp.children.each do |element|
130
+ results[element.name.downcase.to_sym] = element.text
131
+ end
132
+ results
133
+ end
134
+
135
+ def commit(action, parameters)
136
+ url = (test? ? test_url : live_url)
137
+ headers = {
138
+ 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
139
+ }
140
+ response = parse(ssl_post(url, post_data(action, parameters), headers))
141
+
142
+ Response.new(
143
+ success_from(response),
144
+ message_from(response),
145
+ response,
146
+ authorization: authorization_from(response),
147
+ test: test?
148
+ )
149
+ end
150
+
151
+ def success_from(response)
152
+ response[:result] == 'ACK'
153
+ end
154
+
155
+ def message_from(response)
156
+ response[:return]
157
+ end
158
+
159
+ def authorization_from(response)
160
+ response[:uniqueid]
161
+ end
162
+
163
+ def post_data(action, parameters = {})
164
+ xml = build_xml_request(action, parameters)
165
+ "load=#{CGI.escape(xml)}"
166
+ end
167
+
168
+ def build_xml_request(action, data)
169
+ xml = Builder::XmlMarkup.new :indent => 2
170
+ xml.Request(version: '1.0') do
171
+ xml.Header do
172
+ xml.Security(sender: @options[:sender], type: 'MERCHANT')
173
+ end
174
+ xml.Transaction(response: 'SYNC', channel: @options[:channel], mode: 'LIVE') do
175
+ xml.User(pwd: @options[:userpwd], login: @options[:userid])
176
+ xml.Identification do
177
+ xml.TransactionID data[:order_id] if data.has_key? :order_id
178
+ xml.ReferenceID data[:authorization] if data.has_key? :authorization
179
+ end
180
+ xml.Account do
181
+ xml.Holder "#{data[:first_name]} #{data[:last_name]}"
182
+ xml.Brand data[:brand]
183
+ xml.Number data[:card_num]
184
+ xml.Bank data[:bankname]
185
+ xml.Country data[:country]
186
+ xml.Authorization data[:authorization]
187
+ xml.Verification data[:card_code]
188
+ xml.Year data[:exp_year]
189
+ xml.Month data[:exp_month]
190
+ end if data.has_key? :card_num
191
+ xml.Payment(code: SUPPORTED_TRANSACTIONS[action]) do
192
+ xml.Presentation do
193
+ xml.Amount data[:amount]
194
+ xml.Currency data[:currency]
195
+ xml.Usage data[:description]
196
+ end
197
+ end
198
+ xml.Customer do
199
+ xml.Contact do
200
+ xml.Email data[:email]
201
+ xml.Mobile data[:mobile]
202
+ xml.Ip data[:ip]
203
+ xml.Phone data[:phone]
204
+ end
205
+ xml.Address do
206
+ xml.Street data[:address]
207
+ xml.Zip data[:zip]
208
+ xml.City data[:city]
209
+ xml.State data[:state]
210
+ xml.Country data[:country]
211
+ end
212
+ xml.Name do
213
+ xml.Salutation data[:salutation]
214
+ xml.Title data[:title]
215
+ xml.Given data[:first_name]
216
+ xml.Family data[:last_name]
217
+ xml.Company data[:company]
218
+ end
219
+ end if data.has_key? :last_name
220
+ end
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end