start_activemerchant 1.50.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 (218) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1769 -0
  3. data/CONTRIBUTORS +540 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +226 -0
  6. data/lib/active_merchant.rb +67 -0
  7. data/lib/active_merchant/billing.rb +15 -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 +404 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +195 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +291 -0
  18. data/lib/active_merchant/billing/gateways.rb +14 -0
  19. data/lib/active_merchant/billing/gateways/allied_wallet.rb +203 -0
  20. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  21. data/lib/active_merchant/billing/gateways/authorize_net.rb +510 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  24. data/lib/active_merchant/billing/gateways/axcessms.rb +181 -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 +192 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +389 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +58 -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 +211 -0
  37. data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  39. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  40. data/lib/active_merchant/billing/gateways/braintree_blue.rb +574 -0
  41. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  42. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  43. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  44. data/lib/active_merchant/billing/gateways/card_stream.rb +238 -0
  45. data/lib/active_merchant/billing/gateways/cashnet.rb +202 -0
  46. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  47. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  48. data/lib/active_merchant/billing/gateways/cenpos.rb +262 -0
  49. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  50. data/lib/active_merchant/billing/gateways/checkout.rb +216 -0
  51. data/lib/active_merchant/billing/gateways/checkout_v2.rb +200 -0
  52. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  53. data/lib/active_merchant/billing/gateways/conekta.rb +210 -0
  54. data/lib/active_merchant/billing/gateways/cyber_source.rb +720 -0
  55. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  56. data/lib/active_merchant/billing/gateways/dibs.rb +206 -0
  57. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  58. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  59. data/lib/active_merchant/billing/gateways/epay.rb +274 -0
  60. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  61. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  62. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  63. data/lib/active_merchant/billing/gateways/eway_rapid.rb +522 -0
  64. data/lib/active_merchant/billing/gateways/exact.rb +227 -0
  65. data/lib/active_merchant/billing/gateways/ezic.rb +206 -0
  66. data/lib/active_merchant/billing/gateways/fat_zebra.rb +213 -0
  67. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  68. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  69. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  70. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  71. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +413 -0
  72. data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
  73. data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
  74. data/lib/active_merchant/billing/gateways/garanti.rb +261 -0
  75. data/lib/active_merchant/billing/gateways/global_transport.rb +179 -0
  76. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  77. data/lib/active_merchant/billing/gateways/hps.rb +287 -0
  78. data/lib/active_merchant/billing/gateways/iats_payments.rb +277 -0
  79. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  80. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  81. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  82. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  83. data/lib/active_merchant/billing/gateways/inspire.rb +219 -0
  84. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  85. data/lib/active_merchant/billing/gateways/ipp.rb +175 -0
  86. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  87. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  88. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  89. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  90. data/lib/active_merchant/billing/gateways/litle.rb +345 -0
  91. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  92. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  93. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  94. data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
  95. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  96. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  97. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  98. data/lib/active_merchant/billing/gateways/mercury.rb +326 -0
  99. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  100. data/lib/active_merchant/billing/gateways/migs.rb +280 -0
  101. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  102. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  103. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  104. data/lib/active_merchant/billing/gateways/monei.rb +307 -0
  105. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  106. data/lib/active_merchant/billing/gateways/moneris_us.rb +298 -0
  107. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  108. data/lib/active_merchant/billing/gateways/nab_transact.rb +290 -0
  109. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  110. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  111. data/lib/active_merchant/billing/gateways/netbilling.rb +224 -0
  112. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  113. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  114. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  115. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  116. data/lib/active_merchant/billing/gateways/omise.rb +319 -0
  117. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  118. data/lib/active_merchant/billing/gateways/optimal_payment.rb +314 -0
  119. data/lib/active_merchant/billing/gateways/orbital.rb +834 -0
  120. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  121. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  122. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  123. data/lib/active_merchant/billing/gateways/pay_conex.rb +246 -0
  124. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
  125. data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
  126. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  127. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  128. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  129. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  130. data/lib/active_merchant/billing/gateways/payflow.rb +308 -0
  131. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +220 -0
  132. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  133. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  134. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  135. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  136. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  137. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  138. data/lib/active_merchant/billing/gateways/paymill.rb +282 -0
  139. data/lib/active_merchant/billing/gateways/paypal.rb +129 -0
  140. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +679 -0
  141. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  142. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  143. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  144. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  145. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  146. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  147. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  148. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  149. data/lib/active_merchant/billing/gateways/payu_in.rb +247 -0
  150. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  151. data/lib/active_merchant/billing/gateways/pin.rb +207 -0
  152. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  153. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  154. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  155. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  156. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  157. data/lib/active_merchant/billing/gateways/quickbooks.rb +280 -0
  158. data/lib/active_merchant/billing/gateways/quickpay.rb +26 -0
  159. data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +188 -0
  160. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +240 -0
  161. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +227 -0
  162. data/lib/active_merchant/billing/gateways/qvalent.rb +179 -0
  163. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  164. data/lib/active_merchant/billing/gateways/redsys.rb +406 -0
  165. data/lib/active_merchant/billing/gateways/s5.rb +226 -0
  166. data/lib/active_merchant/billing/gateways/sage.rb +173 -0
  167. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +89 -0
  168. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +115 -0
  169. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  170. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  171. data/lib/active_merchant/billing/gateways/sage_pay.rb +399 -0
  172. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  173. data/lib/active_merchant/billing/gateways/secure_net.rb +263 -0
  174. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  175. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  176. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  177. data/lib/active_merchant/billing/gateways/skip_jack.rb +451 -0
  178. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  179. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  180. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  181. data/lib/active_merchant/billing/gateways/stripe.rb +489 -0
  182. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  183. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  184. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  185. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  186. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  187. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  188. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  189. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  190. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +259 -0
  191. data/lib/active_merchant/billing/gateways/vanco.rb +280 -0
  192. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  193. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  194. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  195. data/lib/active_merchant/billing/gateways/wepay.rb +205 -0
  196. data/lib/active_merchant/billing/gateways/wirecard.rb +420 -0
  197. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  198. data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +204 -0
  199. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  200. data/lib/active_merchant/billing/model.rb +30 -0
  201. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +24 -0
  202. data/lib/active_merchant/billing/payment_token.rb +21 -0
  203. data/lib/active_merchant/billing/rails.rb +3 -0
  204. data/lib/active_merchant/billing/response.rb +92 -0
  205. data/lib/active_merchant/connection.rb +172 -0
  206. data/lib/active_merchant/country.rb +332 -0
  207. data/lib/active_merchant/empty.rb +20 -0
  208. data/lib/active_merchant/errors.rb +35 -0
  209. data/lib/active_merchant/network_connection_retries.rb +79 -0
  210. data/lib/active_merchant/post_data.rb +24 -0
  211. data/lib/active_merchant/posts_data.rb +84 -0
  212. data/lib/active_merchant/version.rb +3 -0
  213. data/lib/activemerchant.rb +1 -0
  214. data/lib/certs/cacert.pem +3866 -0
  215. data/lib/support/gateway_support.rb +71 -0
  216. data/lib/support/outbound_hosts.rb +28 -0
  217. data/lib/support/ssl_verify.rb +93 -0
  218. metadata +387 -0
@@ -0,0 +1,181 @@
1
+ require "nokogiri"
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class WorldpayUsGateway < Gateway
6
+ self.display_name = "Worldpay US"
7
+ self.homepage_url = "http://www.worldpay.com/us"
8
+
9
+ # No sandbox, just use test cards.
10
+ self.live_url = 'https://trans.worldpay.us/cgi-bin/process.cgi'
11
+
12
+ self.supported_countries = ['US']
13
+ self.default_currency = 'USD'
14
+ self.money_format = :dollars
15
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb]
16
+
17
+ def initialize(options={})
18
+ requires!(options, :acctid, :subid, :merchantpin)
19
+ super
20
+ end
21
+
22
+ def purchase(money, payment_method, options={})
23
+ post = {}
24
+ add_invoice(post, money, options)
25
+ add_payment_method(post, payment_method)
26
+ add_customer_data(post, options)
27
+
28
+ commit('purchase', post)
29
+ end
30
+
31
+ def authorize(money, payment, options={})
32
+ post = {}
33
+ add_invoice(post, money, options)
34
+ add_payment_method(post, payment)
35
+ add_customer_data(post, options)
36
+
37
+ commit('authorize', post)
38
+ end
39
+
40
+ def capture(amount, authorization, options={})
41
+ post = {}
42
+ add_invoice(post, amount, options)
43
+ add_reference(post, authorization)
44
+ add_customer_data(post, options)
45
+
46
+ commit('capture', post)
47
+ end
48
+
49
+ def refund(amount, authorization, options={})
50
+ post = {}
51
+ add_invoice(post, amount, options)
52
+ add_reference(post, authorization)
53
+ add_customer_data(post, options)
54
+
55
+ commit("refund", post)
56
+ end
57
+
58
+ def void(authorization, options={})
59
+ post = {}
60
+ add_reference(post, authorization)
61
+
62
+ commit('void', post)
63
+ end
64
+
65
+ def verify(credit_card, options={})
66
+ MultiResponse.run(:use_first_response) do |r|
67
+ r.process { authorize(100, credit_card, options) }
68
+ r.process(:ignore_result) { void(r.authorization, options) }
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def add_customer_data(post, options)
75
+ if(billing_address = (options[:billing_address] || options[:address]))
76
+ post[:ci_companyname] = billing_address[:company]
77
+ post[:ci_billaddr1] = billing_address[:address1]
78
+ post[:ci_billaddr2] = billing_address[:address2]
79
+ post[:ci_billcity] = billing_address[:city]
80
+ post[:ci_billstate] = billing_address[:state]
81
+ post[:ci_billzip] = billing_address[:zip]
82
+ post[:ci_billcountry] = billing_address[:country]
83
+
84
+ post[:ci_phone] = billing_address[:phone]
85
+ post[:ci_email] = billing_address[:email]
86
+ post[:ci_ipaddress] = billing_address[:ip]
87
+ end
88
+
89
+ if(shipping_address = options[:shipping_address])
90
+ post[:ci_shipaddr1] = shipping_address[:address1]
91
+ post[:ci_shipaddr2] = shipping_address[:address2]
92
+ post[:ci_shipcity] = shipping_address[:city]
93
+ post[:ci_shipstate] = shipping_address[:state]
94
+ post[:ci_shipzip] = shipping_address[:zip]
95
+ post[:ci_shipcountry] = shipping_address[:country]
96
+ end
97
+ end
98
+
99
+ def add_invoice(post, money, options)
100
+ post[:amount] = amount(money)
101
+ post[:currencycode] = (options[:currency] || currency(money))
102
+ post[:merchantordernumber] = options[:order_id] if options[:order_id]
103
+ end
104
+
105
+ def add_payment_method(post, payment_method)
106
+ post[:ccname] = payment_method.name
107
+ post[:ccnum] = payment_method.number
108
+ post[:cvv2] = payment_method.verification_value
109
+ post[:expyear] = format(payment_method.year, :four_digits)
110
+ post[:expmon] = format(payment_method.month, :two_digits)
111
+ end
112
+
113
+ def split_authorization(authorization)
114
+ historyid, orderid = authorization.split("|")
115
+ [historyid, orderid]
116
+ end
117
+
118
+ def add_reference(post, authorization)
119
+ historyid, orderid = split_authorization(authorization)
120
+ post[:postonly] = historyid
121
+ post[:historykeyid] = historyid
122
+ post[:orderkeyid] = orderid
123
+ end
124
+
125
+ def parse(xml)
126
+ response = {}
127
+ doc = Nokogiri::XML(xml)
128
+ message = doc.xpath("//plaintext")
129
+ message.text.split(/\r?\n/).each do |line|
130
+ key, value = line.split(%r{=})
131
+ response[key] = value if key
132
+ end
133
+ response
134
+ end
135
+
136
+ ACTIONS = {
137
+ "purchase" => "ns_quicksale_cc",
138
+ "refund" => "ns_credit",
139
+ "authorize" => "ns_quicksale_cc",
140
+ "capture" => "ns_quicksale_cc",
141
+ "void" => "ns_void",
142
+ }
143
+
144
+ def commit(action, post)
145
+ post[:action] = ACTIONS[action] if ACTIONS[action]
146
+ post[:acctid] = @options[:acctid]
147
+ post[:subid] = @options[:subid]
148
+ post[:merchantpin] = @options[:merchantpin]
149
+
150
+ post[:authonly] = '1' if action == 'authorize'
151
+
152
+ raw = parse(ssl_post(live_url, post.to_query))
153
+
154
+ succeeded = success_from(raw['transresult'])
155
+ Response.new(
156
+ succeeded,
157
+ message_from(succeeded, raw),
158
+ raw,
159
+ :authorization => authorization_from(raw),
160
+ :test => test?
161
+ )
162
+ end
163
+
164
+ def success_from(result)
165
+ result == 'APPROVED'
166
+ end
167
+
168
+ def message_from(succeeded, response)
169
+ if succeeded
170
+ "Succeeded"
171
+ else
172
+ (response['transresult'] || response['Reason'] || "Unable to read error message")
173
+ end
174
+ end
175
+
176
+ def authorization_from(response)
177
+ [response['historyid'], response['orderid']].join("|")
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,30 @@
1
+ require "active_merchant/billing/compatibility"
2
+ require "active_merchant/empty"
3
+
4
+ module ActiveMerchant
5
+ module Billing
6
+ class Model
7
+ include Compatibility::Model
8
+ include Empty
9
+
10
+ def initialize(attributes = {})
11
+ attributes.each do |key, value|
12
+ send("#{key}=", value)
13
+ end
14
+ end
15
+
16
+ def validate
17
+ {}
18
+ end
19
+
20
+ private
21
+
22
+ def errors_hash(array)
23
+ array.inject({}) do |hash, (attribute, error)|
24
+ (hash[attribute] ||= []) << error
25
+ hash
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class NetworkTokenizationCreditCard < CreditCard
4
+ # A +NetworkTokenizationCreditCard+ object represents a tokenized credit card
5
+ # using the EMV Network Tokenization specification, http://www.emvco.com/specifications.aspx?id=263.
6
+ #
7
+ # It includes all fields of the +CreditCard+ class with additional fields for
8
+ # verification data that must be given to gateways through existing fields (3DS / EMV).
9
+ #
10
+ # The only tested usage of this at the moment is with an Apple Pay decrypted PKPaymentToken,
11
+ # https://developer.apple.com/library/ios/documentation/PassKit/Reference/PaymentTokenJSON/PaymentTokenJSON.html
12
+
13
+ # These are not relevant (verification) or optional (name) for Apple Pay
14
+ self.require_verification_value = false
15
+ self.require_name = false
16
+
17
+ attr_accessor :payment_cryptogram, :eci, :transaction_id
18
+
19
+ def type
20
+ "network_tokenization"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ # Base class representation of cryptographic payment data tokens that may be used for EMV-style transactions
4
+ # like Apple Pay. Payment data may be transmitted via any data type, and may also be padded
5
+ # with metadata specific to the cryptographer. This metadata should be parsed and interpreted in concrete
6
+ # implementations of your given cryptographer. Like credit cards, you must also return a string representing
7
+ # the token's type, like 'apple_pay' or 'stripe' should your target payment gateway process these tokens.
8
+ class PaymentToken
9
+ attr_reader :payment_data
10
+
11
+ def initialize(payment_data, options = {})
12
+ @payment_data = payment_data
13
+ @metadata = options.with_indifferent_access
14
+ end
15
+
16
+ def type
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ require "active_merchant/billing/compatibility"
2
+
3
+ ActiveMerchant::Billing::Compatibility.rails_required!
@@ -0,0 +1,92 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class Error < ActiveMerchantError #:nodoc:
4
+ end
5
+
6
+ class Response
7
+ attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result, :error_code, :emv_authorization
8
+
9
+ def success?
10
+ @success
11
+ end
12
+
13
+ def test?
14
+ @test
15
+ end
16
+
17
+ def fraud_review?
18
+ @fraud_review
19
+ end
20
+
21
+ def initialize(success, message, params = {}, options = {})
22
+ @success, @message, @params = success, message, params.stringify_keys
23
+ @test = options[:test] || false
24
+ @authorization = options[:authorization]
25
+ @fraud_review = options[:fraud_review]
26
+ @error_code = options[:error_code]
27
+ @emv_authorization = options[:emv_authorization]
28
+
29
+ @avs_result = if options[:avs_result].kind_of?(AVSResult)
30
+ options[:avs_result].to_hash
31
+ else
32
+ AVSResult.new(options[:avs_result]).to_hash
33
+ end
34
+
35
+ @cvv_result = if options[:cvv_result].kind_of?(CVVResult)
36
+ options[:cvv_result].to_hash
37
+ else
38
+ CVVResult.new(options[:cvv_result]).to_hash
39
+ end
40
+ end
41
+ end
42
+
43
+ class MultiResponse < Response
44
+ def self.run(use_first_response = false, &block)
45
+ new(use_first_response).tap(&block)
46
+ end
47
+
48
+ attr_reader :responses, :primary_response
49
+
50
+ def initialize(use_first_response = false)
51
+ @responses = []
52
+ @use_first_response = use_first_response
53
+ @primary_response = nil
54
+ end
55
+
56
+ def process(ignore_result=false)
57
+ return unless success?
58
+
59
+ response = yield
60
+ self << response
61
+
62
+ unless ignore_result
63
+ if(@use_first_response && response.success?)
64
+ @primary_response ||= response
65
+ else
66
+ @primary_response = response
67
+ end
68
+ end
69
+ end
70
+
71
+ def <<(response)
72
+ if response.is_a?(MultiResponse)
73
+ response.responses.each{|r| @responses << r}
74
+ else
75
+ @responses << response
76
+ end
77
+ end
78
+
79
+ def success?
80
+ (primary_response ? primary_response.success? : true)
81
+ end
82
+
83
+ %w(params message test authorization avs_result cvv_result error_code emv_authorization test? fraud_review?).each do |m|
84
+ class_eval %(
85
+ def #{m}
86
+ (@responses.empty? ? nil : primary_response.#{m})
87
+ end
88
+ )
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,172 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'net/https'
4
+ require 'benchmark'
5
+
6
+ module ActiveMerchant
7
+ class Connection
8
+ include NetworkConnectionRetries
9
+
10
+ MAX_RETRIES = 3
11
+ OPEN_TIMEOUT = 60
12
+ READ_TIMEOUT = 60
13
+ VERIFY_PEER = true
14
+ CA_FILE = File.expand_path('../certs/cacert.pem', File.dirname(__FILE__))
15
+ CA_PATH = nil
16
+ RETRY_SAFE = false
17
+ RUBY_184_POST_HEADERS = { "Content-Type" => "application/x-www-form-urlencoded" }
18
+
19
+ attr_accessor :endpoint
20
+ attr_accessor :open_timeout
21
+ attr_accessor :read_timeout
22
+ attr_accessor :verify_peer
23
+ attr_accessor :ssl_version
24
+ attr_accessor :ca_file
25
+ attr_accessor :ca_path
26
+ attr_accessor :pem
27
+ attr_accessor :pem_password
28
+ attr_accessor :wiredump_device
29
+ attr_accessor :logger
30
+ attr_accessor :tag
31
+ attr_accessor :ignore_http_status
32
+ attr_accessor :max_retries
33
+ attr_accessor :proxy_address
34
+ attr_accessor :proxy_port
35
+
36
+ def initialize(endpoint)
37
+ @endpoint = endpoint.is_a?(URI) ? endpoint : URI.parse(endpoint)
38
+ @open_timeout = OPEN_TIMEOUT
39
+ @read_timeout = READ_TIMEOUT
40
+ @retry_safe = RETRY_SAFE
41
+ @verify_peer = VERIFY_PEER
42
+ @ca_file = CA_FILE
43
+ @ca_path = CA_PATH
44
+ @max_retries = MAX_RETRIES
45
+ @ignore_http_status = false
46
+ @ssl_version = nil
47
+ @proxy_address = nil
48
+ @proxy_port = nil
49
+ end
50
+
51
+ def request(method, body, headers = {})
52
+ request_start = Time.now.to_f
53
+
54
+ retry_exceptions(:max_retries => max_retries, :logger => logger, :tag => tag) do
55
+ begin
56
+ info "connection_http_method=#{method.to_s.upcase} connection_uri=#{endpoint}", tag
57
+
58
+ result = nil
59
+
60
+ realtime = Benchmark.realtime do
61
+ result = case method
62
+ when :get
63
+ raise ArgumentError, "GET requests do not support a request body" if body
64
+ http.get(endpoint.request_uri, headers)
65
+ when :post
66
+ debug body
67
+ http.post(endpoint.request_uri, body, RUBY_184_POST_HEADERS.merge(headers))
68
+ when :put
69
+ debug body
70
+ http.put(endpoint.request_uri, body, headers)
71
+ when :patch
72
+ debug body
73
+ http.patch(endpoint.request_uri, body, headers)
74
+ when :delete
75
+ # It's kind of ambiguous whether the RFC allows bodies
76
+ # for DELETE requests. But Net::HTTP's delete method
77
+ # very unambiguously does not.
78
+ raise ArgumentError, "DELETE requests do not support a request body" if body
79
+ http.delete(endpoint.request_uri, headers)
80
+ else
81
+ raise ArgumentError, "Unsupported request method #{method.to_s.upcase}"
82
+ end
83
+ end
84
+
85
+ info "--> %d %s (%d %.4fs)" % [result.code, result.message, result.body ? result.body.length : 0, realtime], tag
86
+ debug result.body
87
+ result
88
+ end
89
+ end
90
+
91
+ ensure
92
+ info "connection_request_total_time=%.4fs" % [Time.now.to_f - request_start], tag
93
+ end
94
+
95
+ private
96
+ def http
97
+ http = Net::HTTP.new(endpoint.host, endpoint.port, proxy_address, proxy_port)
98
+ configure_debugging(http)
99
+ configure_timeouts(http)
100
+ configure_ssl(http)
101
+ configure_cert(http)
102
+ http
103
+ end
104
+
105
+ def configure_debugging(http)
106
+ http.set_debug_output(wiredump_device)
107
+ end
108
+
109
+ def configure_timeouts(http)
110
+ http.open_timeout = open_timeout
111
+ http.read_timeout = read_timeout
112
+ end
113
+
114
+ def configure_ssl(http)
115
+ return unless endpoint.scheme == "https"
116
+
117
+ http.use_ssl = true
118
+ http.ssl_version = ssl_version if ssl_version
119
+
120
+ if verify_peer
121
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
122
+ http.ca_file = ca_file
123
+ http.ca_path = ca_path
124
+ else
125
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
126
+ end
127
+
128
+ end
129
+
130
+ def configure_cert(http)
131
+ return if pem.blank?
132
+
133
+ http.cert = OpenSSL::X509::Certificate.new(pem)
134
+
135
+ if pem_password
136
+ http.key = OpenSSL::PKey::RSA.new(pem, pem_password)
137
+ else
138
+ http.key = OpenSSL::PKey::RSA.new(pem)
139
+ end
140
+ end
141
+
142
+ def handle_response(response)
143
+ if @ignore_http_status then
144
+ return response.body
145
+ else
146
+ case response.code.to_i
147
+ when 200...300
148
+ response.body
149
+ else
150
+ raise ResponseError.new(response)
151
+ end
152
+ end
153
+ end
154
+
155
+ def debug(message, tag = nil)
156
+ log(:debug, message, tag)
157
+ end
158
+
159
+ def info(message, tag = nil)
160
+ log(:info, message, tag)
161
+ end
162
+
163
+ def error(message, tag = nil)
164
+ log(:error, message, tag)
165
+ end
166
+
167
+ def log(level, message, tag)
168
+ message = "[#{tag}] #{message}" if tag
169
+ logger.send(level, message) if logger
170
+ end
171
+ end
172
+ end