start_activemerchant 1.50.0

Sign up to get free protection for your applications and to get access to all the features.
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,319 @@
1
+ require 'active_merchant/billing/rails'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class OmiseGateway < Gateway
6
+ API_VERSION = '1.0'
7
+ API_URL = 'https://api.omise.co/'
8
+ VAULT_URL = 'https://vault.omise.co/'
9
+
10
+ STANDARD_ERROR_CODE_MAPPING = {
11
+ 'invalid_security_code' => STANDARD_ERROR_CODE[:invalid_cvc],
12
+ 'failed_capture' => STANDARD_ERROR_CODE[:card_declined]
13
+ }
14
+
15
+ self.live_url = self.test_url = API_URL
16
+
17
+ # Currency supported by Omise
18
+ # * Thai Baht with Satang, ie. 9000 => 90 THB
19
+ self.default_currency = 'THB'
20
+ self.money_format = :cents
21
+
22
+ #Country supported by Omise
23
+ # * Thailand
24
+ self.supported_countries = %w( TH )
25
+
26
+ # Credit cards supported by Omise
27
+ # * VISA
28
+ # * MasterCard
29
+ self.supported_cardtypes = [:visa, :master]
30
+
31
+ # Omise main page
32
+ self.homepage_url = 'https://www.omise.co/'
33
+ self.display_name = 'Omise'
34
+
35
+ # Creates a new OmiseGateway.
36
+ #
37
+ # Omise requires public_key for token creation.
38
+ # And it requires secret_key for other transactions.
39
+ # These keys can be found in https://dashboard.omise.co/test/api-keys
40
+ #
41
+ # ==== Options
42
+ #
43
+ # * <tt>:public_key</tt> -- Omise's public key (REQUIRED).
44
+ # * <tt>:secret_key</tt> -- Omise's secret key (REQUIRED).
45
+
46
+ def initialize(options={})
47
+ requires!(options, :public_key, :secret_key)
48
+ @public_key = options[:public_key]
49
+ @secret_key = options[:secret_key]
50
+ super
51
+ end
52
+
53
+ # Perform a purchase (with auto capture)
54
+ #
55
+ # ==== Parameters
56
+ #
57
+ # * <tt>money</tt> -- The purchasing amount in Thai Baht Satang
58
+ # * <tt>payment_method</tt> -- The CreditCard object
59
+ # * <tt>options</tt> -- An optional parameters, such as token from Omise.js
60
+ #
61
+ # ==== Options
62
+ # * <tt>token_id</tt> -- token id, use Omise.js library to retrieve a token id
63
+ # if this is passed as an option, it will ignore tokenizing via Omisevaultgateway object
64
+ #
65
+ # === Example
66
+ # To create a charge on a card
67
+ #
68
+ # purchase(money, Creditcard_object)
69
+ #
70
+ # To create a charge on a token
71
+ #
72
+ # purchase(money, nil, { :token_id => token_id, ... })
73
+ #
74
+ # To create a charge on a customer
75
+ #
76
+ # purchase(money, nil, { :customer_id => customer_id })
77
+
78
+ def purchase(money, payment_method, options={})
79
+ create_charge(money, payment_method, options)
80
+ end
81
+
82
+ # Authorize a charge.
83
+ #
84
+ # ==== Parameters
85
+ #
86
+ # * <tt>money</tt> -- The purchasing amount in Thai Baht Satang
87
+ # * <tt>payment_method</tt> -- The CreditCard object
88
+ # * <tt>options</tt> -- An optional parameters, such as token or capture
89
+
90
+ def authorize(money, payment_method, options={})
91
+ options[:capture] = 'false'
92
+ create_charge(money, payment_method, options)
93
+ end
94
+
95
+ # Capture an authorized charge.
96
+ #
97
+ # ==== Parameters
98
+ #
99
+ # * <tt>money</tt> -- An amount in Thai Baht Satang
100
+ # * <tt>charge_id</tt> -- The CreditCard object
101
+ # * <tt>options</tt> -- An optional parameters, such as token or capture
102
+
103
+ def capture(money, charge_id, options={})
104
+ post = {}
105
+ add_amount(post, money, options)
106
+ commit(:post, "charges/#{CGI.escape(charge_id)}/capture", post, options)
107
+ end
108
+
109
+ # Refund a charge.
110
+ #
111
+ # ==== Parameters
112
+ #
113
+ # * <tt>money</tt> -- An amount of money to charge in Satang.
114
+ # * <tt>charge_id</tt> -- The CreditCard object
115
+ # * <tt>options</tt> -- An optional parameters, such as token or capture
116
+
117
+ def refund(money, charge_id, options={})
118
+ options[:amount] = money if money
119
+ commit(:post, "charges/#{CGI.escape(charge_id)}/refunds", options)
120
+ end
121
+
122
+ # Store a card details as customer
123
+ #
124
+ # ==== Parameters
125
+ #
126
+ # * <tt>payment_method</tt> -- The CreditCard.
127
+ # * <tt>options</tt> -- Optional Customer information:
128
+ # 'email' (A customer email)
129
+ # 'description' (A customer description)
130
+
131
+ def store(payment_method, options={})
132
+ post, card_params = {}, {}
133
+ add_customer_data(post, options)
134
+ add_token(card_params, payment_method, options)
135
+ commit(:post, 'customers', post.merge(card_params), options)
136
+ end
137
+
138
+ # Delete a customer and all associated credit cards.
139
+ #
140
+ # ==== Parameters
141
+ #
142
+ # * <tt>customer_id</tt> -- The Customer identifier (REQUIRED).
143
+
144
+ def unstore(customer_id, options={})
145
+ commit(:delete, "customers/#{CGI.escape(customer_id)}")
146
+ end
147
+
148
+ # Enable scrubbling sensitive information
149
+ def supports_scrubbing?
150
+ true
151
+ end
152
+
153
+ # Scrub sensitive information out of HTTP transcripts
154
+ #
155
+ # ==== Parameters
156
+ #
157
+ # * <tt>transcript</tt> -- The HTTP transcripts
158
+
159
+ def scrub(transcript)
160
+ transcript.
161
+ gsub(/(Authorization: Basic )\w+/i, '\1[FILTERED]').
162
+ gsub(/(\\"number\\":)\\"\d+\\"/, '\1[FILTERED]').
163
+ gsub(/(\\"security_code\\":)\\"\d+\\"/,'\1[FILTERED]')
164
+ end
165
+
166
+ private
167
+
168
+ def create_charge(money, payment_method, options)
169
+ post = {}
170
+ add_token(post, payment_method, options)
171
+ add_amount(post, money, options)
172
+ add_customer(post, options)
173
+ post[:capture] = options[:capture] if options[:capture]
174
+ commit(:post, 'charges', post, options)
175
+ end
176
+
177
+ def headers(options={})
178
+ key = options[:key] || @secret_key
179
+ {
180
+ 'Content-Type' => 'application/json;utf-8',
181
+ 'User-Agent' => "Omise/v#{API_VERSION} ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
182
+ 'Authorization' => 'Basic ' + Base64.encode64(key.to_s + ':').strip,
183
+ 'Accept-Encoding' => 'utf-8'
184
+ }
185
+ end
186
+
187
+ def url_for(endpoint)
188
+ (endpoint == 'tokens' ? VAULT_URL : API_URL) + endpoint
189
+ end
190
+
191
+ def post_data(parameters)
192
+ parameters.present? ? parameters.to_json : nil
193
+ end
194
+
195
+ def https_request(method, endpoint, parameters=nil, options={})
196
+ raw_response = response = nil
197
+ begin
198
+ raw_response = ssl_request(method, url_for(endpoint), post_data(parameters), headers(options))
199
+ response = parse(raw_response)
200
+ rescue ResponseError => e
201
+ raw_response = e.response.body
202
+ response = parse(raw_response)
203
+ rescue JSON::ParserError
204
+ response = json_error(raw_response)
205
+ end
206
+ response
207
+ end
208
+
209
+ def parse(body)
210
+ JSON.parse(body)
211
+ end
212
+
213
+ def json_error(raw_response)
214
+ msg = "Invalid response received from Omise API. Please contact support@omise.co if you continue to receive this message."
215
+ msg += "The raw response returned by the API was #{raw_response.inspect})"
216
+ { message: msg }
217
+ end
218
+
219
+ def commit(method, endpoint, params=nil, options={})
220
+ response = https_request(method, endpoint, params, options)
221
+ Response.new(
222
+ successful?(response),
223
+ message_from(response),
224
+ response,
225
+ {
226
+ authorization: authorization_from(response),
227
+ test: test?,
228
+ error_code: successful?(response) ? nil : standard_error_code_mapping(response)
229
+ }
230
+ )
231
+ end
232
+
233
+ def standard_error_code_mapping(response)
234
+ STANDARD_ERROR_CODE_MAPPING[error_code_from(response)] || message_to_standard_error_code_from(response)
235
+ end
236
+
237
+ def error_code_from(response)
238
+ error?(response) ? response['code'] : response['failure_code']
239
+ end
240
+
241
+ def message_to_standard_error_code_from(response)
242
+ message = response['message'] if response['code'] == 'invalid_card'
243
+ case message
244
+ when /brand not supported/
245
+ STANDARD_ERROR_CODE[:invalid_number]
246
+ when /number is invalid/
247
+ STANDARD_ERROR_CODE[:incorrect_number]
248
+ when /expiration date cannot be in the past/
249
+ STANDARD_ERROR_CODE[:expired_card]
250
+ when /expiration \w+ is invalid/
251
+ STANDARD_ERROR_CODE[:invalid_expiry_date]
252
+ else
253
+ STANDARD_ERROR_CODE[:processing_error]
254
+ end
255
+ end
256
+
257
+ def message_from(response)
258
+ if successful?(response)
259
+ 'Success'
260
+ else
261
+ (response['message'] ? response['message'] : response['failure_message'])
262
+ end
263
+ end
264
+
265
+ def authorization_from(response)
266
+ response['id'] if successful?(response)
267
+ end
268
+
269
+ def successful?(response)
270
+ !error?(response) && response['failure_code'].nil?
271
+ end
272
+
273
+ def error?(response)
274
+ response.key?('object') && (response['object'] == 'error')
275
+ end
276
+
277
+ def get_token(post, credit_card)
278
+ add_creditcard(post, credit_card) if credit_card
279
+ commit(:post, 'tokens', post, { key: @public_key })
280
+ end
281
+
282
+ def add_token(post, credit_card, options={})
283
+ if options[:token_id].present?
284
+ post[:card] = options[:token_id]
285
+ else
286
+ response = get_token(post, credit_card)
287
+ response.authorization ? (post[:card] = response.authorization) : response
288
+ end
289
+ end
290
+
291
+ def add_creditcard(post, payment_method)
292
+ card = {
293
+ number: payment_method.number,
294
+ name: payment_method.name,
295
+ security_code: payment_method.verification_value,
296
+ expiration_month: payment_method.month,
297
+ expiration_year: payment_method.year
298
+ }
299
+ post[:card] = card
300
+ end
301
+
302
+ def add_customer(post, options={})
303
+ post[:customer] = options[:customer_id] if options[:customer_id]
304
+ end
305
+
306
+ def add_customer_data(post, options={})
307
+ post[:description] = options[:description] if options[:description]
308
+ post[:email] = options[:email] if options[:email]
309
+ end
310
+
311
+ def add_amount(post, money, options)
312
+ post[:amount] = amount(money)
313
+ post[:currency] = (options[:currency] || currency(money))
314
+ post[:description] = options[:description] if options.key?(:description)
315
+ end
316
+
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,194 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class OpenpayGateway < Gateway
4
+ self.live_url = 'https://api.openpay.mx/v1/'
5
+ self.test_url = 'https://sandbox-api.openpay.mx/v1/'
6
+
7
+ self.supported_countries = ['MX']
8
+ self.supported_cardtypes = [:visa, :master, :american_express]
9
+ self.homepage_url = 'http://www.openpay.mx/'
10
+ self.display_name = 'Openpay'
11
+ self.default_currency = 'MXN'
12
+
13
+ # Instantiate a instance of OpenpayGateway by passing through your
14
+ # merchant id and private api key.
15
+ #
16
+ # === To obtain your own credentials
17
+ # 1. Visit http://openpay.mx
18
+ # 2. Sign up
19
+ # 3. Activate your account clicking on the email confirmation
20
+ def initialize(options = {})
21
+ requires!(options, :key, :merchant_id)
22
+ @api_key = options[:key]
23
+ @merchant_id = options[:merchant_id]
24
+ super
25
+ end
26
+
27
+ def purchase(money, creditcard, options = {})
28
+ post = create_post_for_auth_or_purchase(money, creditcard, options)
29
+ commit(:post, 'charges', post, options)
30
+ end
31
+
32
+ def authorize(money, creditcard, options = {})
33
+ post = create_post_for_auth_or_purchase(money, creditcard, options)
34
+ post[:capture] = false
35
+ commit(:post, 'charges', post, options)
36
+ end
37
+
38
+ def capture(money, authorization, options = {})
39
+ post = {}
40
+ post[:amount] = amount(money) if money
41
+ commit(:post, "charges/#{CGI.escape(authorization)}/capture", post, options)
42
+ end
43
+
44
+ def void(identification, options = {})
45
+ commit(:post, "charges/#{CGI.escape(identification)}/refund", nil, options)
46
+ end
47
+
48
+ def refund(money, identification, options = {})
49
+ post = {}
50
+ post[:description] = options[:description]
51
+ post[:amount] = amount(money)
52
+ commit(:post, "charges/#{CGI.escape(identification)}/refund", post, options)
53
+ end
54
+
55
+ def store(creditcard, options = {})
56
+ card_params = {}
57
+ add_creditcard(card_params, creditcard, options)
58
+ card = card_params[:card]
59
+
60
+ if options[:customer].present?
61
+ commit(:post, "customers/#{CGI.escape(options[:customer])}/cards", card, options)
62
+ else
63
+ requires!(options, :email, :name)
64
+ post = {}
65
+ post[:name] = options[:name]
66
+ post[:email] = options[:email]
67
+ MultiResponse.run(:first) do |r|
68
+ r.process { commit(:post, 'customers', post, options) }
69
+
70
+ if(r.success? && !r.params['id'].blank?)
71
+ customer_id = r.params['id']
72
+ r.process { commit(:post, "customers/#{customer_id}/cards", card, options) }
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ def unstore(customer_id, card_id = nil, options = {})
79
+ if card_id.nil?
80
+ commit(:delete, "customers/#{CGI.escape(customer_id)}", nil, options)
81
+ else
82
+ commit(:delete, "customers/#{CGI.escape(customer_id)}/cards/#{CGI.escape(card_id)}", nil, options)
83
+ end
84
+ end
85
+
86
+ private
87
+
88
+ def create_post_for_auth_or_purchase(money, creditcard, options)
89
+ post = {}
90
+ post[:amount] = amount(money)
91
+ post[:method] = 'card'
92
+ post[:description] = options[:description]
93
+ post[:order_id] = options[:order_id]
94
+ post[:device_session_id] = options[:device_session_id]
95
+ add_creditcard(post, creditcard, options)
96
+ post
97
+ end
98
+
99
+ def add_creditcard(post, creditcard, options)
100
+ if creditcard.kind_of?(String)
101
+ post[:source_id] = creditcard
102
+ elsif creditcard.respond_to?(:number)
103
+ card = {
104
+ card_number: creditcard.number,
105
+ expiration_month: "#{sprintf("%02d", creditcard.month)}",
106
+ expiration_year: "#{"#{creditcard.year}"[-2, 2]}",
107
+ cvv2: creditcard.verification_value,
108
+ holder_name: creditcard.name
109
+ }
110
+ add_address(card, options)
111
+ post[:card] = card
112
+ end
113
+ end
114
+
115
+ def add_address(card, options)
116
+ return unless card.kind_of?(Hash)
117
+ if address = (options[:billing_address] || options[:address])
118
+ card[:address] = {
119
+ line1: address[:address1],
120
+ line2: address[:address2],
121
+ line3: address[:company],
122
+ city: address[:city],
123
+ postal_code: address[:zip],
124
+ state: address[:state],
125
+ country_code: address[:country]
126
+ }
127
+ end
128
+ end
129
+
130
+ def headers(options = {})
131
+ {
132
+ "Content-Type" => "application/json",
133
+ "Authorization" => "Basic " + Base64.encode64(@api_key.to_s + ":").strip,
134
+ "User-Agent" => "Openpay/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
135
+ "X-Openpay-Client-User-Agent" => user_agent
136
+ }
137
+ end
138
+
139
+ def parse(body)
140
+ return {} unless body
141
+ JSON.parse(body)
142
+ end
143
+
144
+ def commit(method, resource, parameters, options = {})
145
+ response = http_request(method, resource, parameters, options)
146
+ success = !error?(response)
147
+
148
+ Response.new(success,
149
+ (success ? response['error_code'] : response['description']),
150
+ response,
151
+ :test => test?,
152
+ :authorization => response['id']
153
+ )
154
+ end
155
+
156
+ def http_request(method, resource, parameters={}, options={})
157
+ url = (test? ? self.test_url : self.live_url) + @merchant_id + '/' + resource
158
+ raw_response = nil
159
+ begin
160
+ raw_response = ssl_request(method, url, (parameters ? parameters.to_json : nil), headers(options))
161
+ parse(raw_response)
162
+ rescue ResponseError => e
163
+ raw_response = e.response.body
164
+ response_error(raw_response)
165
+ rescue JSON::ParserError
166
+ json_error(raw_response)
167
+ end
168
+ end
169
+
170
+ def error?(response)
171
+ response.key?('error_code')
172
+ end
173
+
174
+ def response_error(raw_response)
175
+ begin
176
+ parse(raw_response)
177
+ rescue JSON::ParserError
178
+ json_error(raw_response)
179
+ end
180
+ end
181
+
182
+ def json_error(raw_response)
183
+ msg = 'Invalid response received from the Openpay API. Please contact soporte@openpay.mx if you continue to receive this message.'
184
+ msg += " (The raw response returned by the API was #{raw_response.inspect})"
185
+ {
186
+ 'category' => 'request',
187
+ 'error_code' => '9999',
188
+ 'description' => msg
189
+ }
190
+ end
191
+ end
192
+ end
193
+ end
194
+