activemerchant 1.58.0 → 1.59.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +54 -0
  3. data/README.md +3 -3
  4. data/lib/active_merchant/billing/check.rb +3 -0
  5. data/lib/active_merchant/billing/credit_card.rb +7 -2
  6. data/lib/active_merchant/billing/credit_card_methods.rb +5 -1
  7. data/lib/active_merchant/billing/gateway.rb +5 -3
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -3
  9. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +34 -5
  10. data/lib/active_merchant/billing/gateways/blue_pay.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/blue_snap.rb +348 -0
  12. data/lib/active_merchant/billing/gateways/braintree_blue.rb +6 -3
  13. data/lib/active_merchant/billing/gateways/card_stream.rb +33 -15
  14. data/lib/active_merchant/billing/gateways/cashnet.rb +1 -0
  15. data/lib/active_merchant/billing/gateways/cyber_source.rb +7 -3
  16. data/lib/active_merchant/billing/gateways/global_collect.rb +293 -0
  17. data/lib/active_merchant/billing/gateways/jetpay.rb +11 -8
  18. data/lib/active_merchant/billing/gateways/latitude19.rb +416 -0
  19. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +13 -0
  20. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +10 -7
  21. data/lib/active_merchant/billing/gateways/mercury.rb +1 -1
  22. data/lib/active_merchant/billing/gateways/metrics_global.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/moneris.rb +8 -1
  24. data/lib/active_merchant/billing/gateways/nmi.rb +25 -9
  25. data/lib/active_merchant/billing/gateways/openpay.rb +1 -1
  26. data/lib/active_merchant/billing/gateways/orbital.rb +5 -3
  27. data/lib/active_merchant/billing/gateways/paymill.rb +1 -1
  28. data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -6
  29. data/lib/active_merchant/billing/gateways/payu_in.rb +3 -2
  30. data/lib/active_merchant/billing/gateways/s5.rb +8 -5
  31. data/lib/active_merchant/billing/gateways/sage.rb +1 -7
  32. data/lib/active_merchant/billing/gateways/sage_pay.rb +0 -4
  33. data/lib/active_merchant/billing/gateways/secure_net.rb +0 -5
  34. data/lib/active_merchant/billing/gateways/secure_pay.rb +1 -1
  35. data/lib/active_merchant/billing/gateways/securion_pay.rb +46 -17
  36. data/lib/active_merchant/billing/gateways/stripe.rb +5 -8
  37. data/lib/active_merchant/billing/gateways/tns.rb +1 -1
  38. data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
  39. data/lib/active_merchant/billing/gateways/vanco.rb +1 -1
  40. data/lib/active_merchant/billing/gateways/visanet_peru.rb +218 -0
  41. data/lib/active_merchant/billing/gateways/world_net.rb +344 -0
  42. data/lib/active_merchant/billing/gateways/worldpay.rb +8 -11
  43. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +4 -0
  44. data/lib/active_merchant/country.rb +0 -2
  45. data/lib/active_merchant/version.rb +1 -1
  46. metadata +7 -2
@@ -12,9 +12,9 @@ module ActiveMerchant #:nodoc:
12
12
 
13
13
  self.supported_countries = ['AU']
14
14
  self.supported_cardtypes = [:visa, :master, :american_express,
15
- :diners_club, :discover]
16
- self.homepage_url = 'http://www.merchantwarrior.com/'
17
- self.display_name = 'MerchantWarrior'
15
+ :diners_club, :discover, :jcb]
16
+ self.homepage_url = 'https://www.merchantwarrior.com/'
17
+ self.display_name = 'Merchant Warrior'
18
18
 
19
19
  self.money_format = :dollars
20
20
  self.default_currency = 'AUD'
@@ -27,7 +27,7 @@ module ActiveMerchant #:nodoc:
27
27
  def authorize(money, payment_method, options = {})
28
28
  post = {}
29
29
  add_amount(post, money, options)
30
- add_product(post, options)
30
+ add_order_id(post, options)
31
31
  add_address(post, options)
32
32
  add_payment_method(post, payment_method)
33
33
  commit('processAuth', post)
@@ -36,7 +36,7 @@ module ActiveMerchant #:nodoc:
36
36
  def purchase(money, payment_method, options = {})
37
37
  post = {}
38
38
  add_amount(post, money, options)
39
- add_product(post, options)
39
+ add_order_id(post, options)
40
40
  add_address(post, options)
41
41
  add_payment_method(post, payment_method)
42
42
  commit('processCard', post)
@@ -83,10 +83,13 @@ module ActiveMerchant #:nodoc:
83
83
  post['customerCity'] = address[:city]
84
84
  post['customerAddress'] = address[:address1]
85
85
  post['customerPostCode'] = address[:zip]
86
+ post['customerIP'] = address[:ip]
87
+ post['customerPhone'] = address[:phone]
88
+ post['customerEmail'] = address[:email]
86
89
  end
87
90
 
88
- def add_product(post, options)
89
- post['transactionProduct'] = truncate(options[:description], 34)
91
+ def add_order_id(post, options)
92
+ post['transactionProduct'] = truncate(options[:order_id], 34) || SecureRandom.hex(15)
90
93
  end
91
94
 
92
95
  def add_payment_method(post, payment_method)
@@ -12,7 +12,7 @@ module ActiveMerchant #:nodoc:
12
12
  # and +refund+ will become mandatory.
13
13
  class MercuryGateway < Gateway
14
14
  URLS = {
15
- :test => 'https://w1.mercurydev.net/ws/ws.asmx',
15
+ :test => 'https://w1.mercurycert.net/ws/ws.asmx',
16
16
  :live => 'https://w1.mercurypay.com/ws/ws.asmx'
17
17
  }
18
18
 
@@ -218,7 +218,7 @@ module ActiveMerchant #:nodoc:
218
218
  post[:delim_data] = "TRUE"
219
219
  post[:delim_char] = ","
220
220
  post[:encap_char] = "$"
221
- post[:solution_ID] = application_id if application_id.present? && application_id != "ActiveMerchant"
221
+ post[:solution_ID] = application_id if application_id
222
222
 
223
223
  request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
224
224
  request
@@ -53,7 +53,7 @@ module ActiveMerchant #:nodoc:
53
53
  post[:crypt_type] = options[:crypt_type] || @options[:crypt_type]
54
54
  action = if post[:cavv]
55
55
  'cavv_preauth'
56
- elsif post[:data_key].blank?
56
+ elsif post[:data_key].blank?
57
57
  'preauth'
58
58
  else
59
59
  'res_preauth_cc'
@@ -132,6 +132,13 @@ module ActiveMerchant #:nodoc:
132
132
  commit 'refund', crediting_params(authorization, :amount => amount(money))
133
133
  end
134
134
 
135
+ def verify(credit_card, options={})
136
+ MultiResponse.run(:use_first_response) do |r|
137
+ r.process { authorize(100, credit_card, options) }
138
+ r.process(:ignore_result) { void(r.authorization, options) }
139
+ end
140
+ end
141
+
135
142
  def store(credit_card, options = {})
136
143
  post = {}
137
144
  post[:pan] = credit_card.number
@@ -30,7 +30,7 @@ module ActiveMerchant #:nodoc:
30
30
  def purchase(amount, payment_method, options={})
31
31
  post = {}
32
32
  add_invoice(post, amount, options)
33
- add_payment_method(post, payment_method)
33
+ add_payment_method(post, payment_method, options)
34
34
  add_customer_data(post, options)
35
35
  add_merchant_defined_fields(post, options)
36
36
 
@@ -40,7 +40,7 @@ module ActiveMerchant #:nodoc:
40
40
  def authorize(amount, payment_method, options={})
41
41
  post = {}
42
42
  add_invoice(post, amount, options)
43
- add_payment_method(post, payment_method)
43
+ add_payment_method(post, payment_method, options)
44
44
  add_customer_data(post, options)
45
45
  add_merchant_defined_fields(post, options)
46
46
 
@@ -59,6 +59,7 @@ module ActiveMerchant #:nodoc:
59
59
  def void(authorization, options={})
60
60
  post = {}
61
61
  add_reference(post, authorization)
62
+ add_payment_type(post, authorization)
62
63
 
63
64
  commit("void", post)
64
65
  end
@@ -67,6 +68,7 @@ module ActiveMerchant #:nodoc:
67
68
  post = {}
68
69
  add_invoice(post, amount, options)
69
70
  add_reference(post, authorization)
71
+ add_payment_type(post, authorization)
70
72
 
71
73
  commit("refund", post)
72
74
  end
@@ -74,7 +76,7 @@ module ActiveMerchant #:nodoc:
74
76
  def credit(amount, payment_method, options={})
75
77
  post = {}
76
78
  add_invoice(post, amount, options)
77
- add_payment_method(post, payment_method)
79
+ add_payment_method(post, payment_method, options)
78
80
  add_customer_data(post, options)
79
81
 
80
82
  commit("credit", post)
@@ -82,7 +84,7 @@ module ActiveMerchant #:nodoc:
82
84
 
83
85
  def verify(payment_method, options={})
84
86
  post = {}
85
- add_payment_method(post, payment_method)
87
+ add_payment_method(post, payment_method, options)
86
88
  add_customer_data(post, options)
87
89
  add_merchant_defined_fields(post, options)
88
90
 
@@ -92,7 +94,7 @@ module ActiveMerchant #:nodoc:
92
94
  def store(payment_method, options = {})
93
95
  post = {}
94
96
  add_invoice(post, nil, options)
95
- add_payment_method(post, payment_method)
97
+ add_payment_method(post, payment_method, options)
96
98
  add_customer_data(post, options)
97
99
  add_merchant_defined_fields(post, options)
98
100
 
@@ -125,7 +127,7 @@ module ActiveMerchant #:nodoc:
125
127
  end
126
128
  end
127
129
 
128
- def add_payment_method(post, payment_method)
130
+ def add_payment_method(post, payment_method, options)
129
131
  if(payment_method.is_a?(String))
130
132
  post[:customer_vault_id] = payment_method
131
133
  elsif(card_brand(payment_method) == 'check')
@@ -135,7 +137,7 @@ module ActiveMerchant #:nodoc:
135
137
  post[:checkaccount] = payment_method.account_number
136
138
  post[:account_holder_type] = payment_method.account_holder_type
137
139
  post[:account_type] = payment_method.account_type
138
- post[:sec_code] = 'WEB'
140
+ post[:sec_code] = options[:sec_code] || 'WEB'
139
141
  else
140
142
  post[:payment] = 'creditcard'
141
143
  post[:firstname] = payment_method.first_name
@@ -182,7 +184,13 @@ module ActiveMerchant #:nodoc:
182
184
  end
183
185
 
184
186
  def add_reference(post, authorization)
185
- post[:transactionid] = authorization
187
+ transaction_id, _ = split_authorization(authorization)
188
+ post[:transactionid] = transaction_id
189
+ end
190
+
191
+ def add_payment_type(post, authorization)
192
+ _, payment_type = split_authorization(authorization)
193
+ post[:payment] = payment_type if payment_type
186
194
  end
187
195
 
188
196
  def exp_date(payment_method)
@@ -203,13 +211,21 @@ module ActiveMerchant #:nodoc:
203
211
  succeeded,
204
212
  message_from(succeeded, response),
205
213
  response,
206
- authorization: response[:transactionid],
214
+ authorization: authorization_from(response, params[:payment]),
207
215
  avs_result: AVSResult.new(code: response[:avsresponse]),
208
216
  cvv_result: CVVResult.new(response[:cvvresponse]),
209
217
  test: test?
210
218
  )
211
219
  end
212
220
 
221
+ def authorization_from(response, payment_type)
222
+ [ response[:transactionid], payment_type ].join("#")
223
+ end
224
+
225
+ def split_authorization(authorization)
226
+ authorization.split("#")
227
+ end
228
+
213
229
  def headers
214
230
  { "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8" }
215
231
  end
@@ -143,7 +143,7 @@ module ActiveMerchant #:nodoc:
143
143
  def headers(options = {})
144
144
  {
145
145
  "Content-Type" => "application/json",
146
- "Authorization" => "Basic " + Base64.encode64(@api_key.to_s + ":").strip,
146
+ "Authorization" => "Basic " + Base64.strict_encode64(@api_key.to_s + ":").strip,
147
147
  "User-Agent" => "Openpay/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
148
148
  "X-Openpay-Client-User-Agent" => user_agent
149
149
  }
@@ -28,6 +28,8 @@ module ActiveMerchant #:nodoc:
28
28
  # Company will automatically be affiliated.
29
29
 
30
30
  class OrbitalGateway < Gateway
31
+ include Empty
32
+
31
33
  API_VERSION = "5.6"
32
34
 
33
35
  POST_HEADERS = {
@@ -328,7 +330,7 @@ module ActiveMerchant #:nodoc:
328
330
 
329
331
  def add_address(xml, creditcard, options)
330
332
  if(address = (options[:billing_address] || options[:address]))
331
- avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
333
+ avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s) || empty?(address[:country])
332
334
 
333
335
  if avs_supported
334
336
  xml.tag! :AVSzip, byte_limit(format_address_field(address[:zip]), 10)
@@ -338,9 +340,9 @@ module ActiveMerchant #:nodoc:
338
340
  xml.tag! :AVSstate, byte_limit(format_address_field(address[:state]), 2)
339
341
  xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
340
342
  end
341
- # can't look in billing address?
343
+
342
344
  xml.tag! :AVSname, ((creditcard && creditcard.name) ? creditcard.name[0..29] : nil)
343
- xml.tag! :AVScountryCode, (avs_supported ? address[:country] : '')
345
+ xml.tag! :AVScountryCode, (avs_supported ? (byte_limit(format_address_field(address[:country]), 2)) : '')
344
346
 
345
347
  # Needs to come after AVScountryCode
346
348
  add_destination_address(xml, address) if avs_supported
@@ -154,7 +154,7 @@ module ActiveMerchant #:nodoc:
154
154
  begin
155
155
  raw_response = ssl_request(:get, "#{save_card_url}?#{post_data(post)}", nil, {})
156
156
  rescue ResponseError => e
157
- return Response.new(false, e.response.body, e.response.body, {})
157
+ return Response.new(false, e.response.body)
158
158
  end
159
159
 
160
160
  response_for_save_from(raw_response)
@@ -26,12 +26,11 @@ module ActiveMerchant #:nodoc:
26
26
  'TW' => 'zh_TW'
27
27
  }
28
28
 
29
- CURRENCIES_WITHOUT_FRACTIONS = %w(HUF JPY TWD)
30
-
31
29
  self.test_redirect_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'
32
30
  self.supported_countries = ['US']
33
31
  self.homepage_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=xpt/merchant/ExpressCheckoutIntro-outside'
34
32
  self.display_name = 'PayPal Express Checkout'
33
+ self.currencies_without_fractions = %w(HUF JPY TWD)
35
34
 
36
35
  def setup_authorization(money, options = {})
37
36
  requires!(options, :return_url, :cancel_return_url)
@@ -86,10 +85,6 @@ module ActiveMerchant #:nodoc:
86
85
  end
87
86
 
88
87
  private
89
- def non_fractional_currency?(currency)
90
- CURRENCIES_WITHOUT_FRACTIONS.include?(currency.to_s)
91
- end
92
-
93
88
  def build_get_details_request(token)
94
89
  xml = Builder::XmlMarkup.new :indent => 2
95
90
  xml.tag! 'GetExpressCheckoutDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
@@ -11,7 +11,7 @@ module ActiveMerchant #:nodoc:
11
11
 
12
12
  self.supported_countries = ['IN']
13
13
  self.default_currency = 'INR'
14
- self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
14
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :maestro]
15
15
 
16
16
  self.homepage_url = 'https://www.payu.in/'
17
17
  self.display_name = 'PayU India'
@@ -135,7 +135,8 @@ module ActiveMerchant #:nodoc:
135
135
  visa: "VISA",
136
136
  master: "MAST",
137
137
  american_express: "AMEX",
138
- diners_club: "DINR"
138
+ diners_club: "DINR",
139
+ maestro: "MAES"
139
140
  }
140
141
 
141
142
  def add_payment(post, payment)
@@ -29,6 +29,7 @@ module ActiveMerchant #:nodoc:
29
29
 
30
30
  def purchase(money, payment, options={})
31
31
  request = build_xml_request do |xml|
32
+ add_identification(xml, options)
32
33
  add_payment(xml, money, 'sale', options)
33
34
  add_account(xml, payment)
34
35
  add_customer(xml, payment, options)
@@ -40,7 +41,7 @@ module ActiveMerchant #:nodoc:
40
41
 
41
42
  def refund(money, authorization, options={})
42
43
  request = build_xml_request do |xml|
43
- add_identification(xml, authorization)
44
+ add_identification(xml, options, authorization)
44
45
  add_payment(xml, money, 'refund', options)
45
46
  end
46
47
 
@@ -49,6 +50,7 @@ module ActiveMerchant #:nodoc:
49
50
 
50
51
  def authorize(money, payment, options={})
51
52
  request = build_xml_request do |xml|
53
+ add_identification(xml, options)
52
54
  add_payment(xml, money, 'authonly', options)
53
55
  add_account(xml, payment)
54
56
  add_customer(xml, payment, options)
@@ -60,7 +62,7 @@ module ActiveMerchant #:nodoc:
60
62
 
61
63
  def capture(money, authorization, options={})
62
64
  request = build_xml_request do |xml|
63
- add_identification(xml, authorization)
65
+ add_identification(xml, options, authorization)
64
66
  add_payment(xml, money, 'capture', options)
65
67
  end
66
68
 
@@ -69,7 +71,7 @@ module ActiveMerchant #:nodoc:
69
71
 
70
72
  def void(authorization, options={})
71
73
  request = build_xml_request do |xml|
72
- add_identification(xml, authorization)
74
+ add_identification(xml, options, authorization)
73
75
  add_payment(xml, nil, 'void', options)
74
76
  end
75
77
 
@@ -108,9 +110,10 @@ module ActiveMerchant #:nodoc:
108
110
 
109
111
  private
110
112
 
111
- def add_identification(xml, authorization)
113
+ def add_identification(xml, options, authorization = nil)
112
114
  xml.Identification do
113
- xml.ReferenceID authorization
115
+ xml.TransactionID options[:order_id] if options[:order_id]
116
+ xml.ReferenceID authorization if authorization
114
117
  end
115
118
  end
116
119
 
@@ -204,13 +204,7 @@ module ActiveMerchant #:nodoc:
204
204
 
205
205
  post[:C_address] = billing_address[:address1]
206
206
  post[:C_city] = billing_address[:city]
207
-
208
- if ['US', 'CA'].include?(billing_address[:country])
209
- post[:C_state] = billing_address[:state]
210
- else
211
- post[:C_state] = "Outside of United States"
212
- end
213
-
207
+ post[:C_state] = billing_address[:state]
214
208
  post[:C_zip] = billing_address[:zip]
215
209
  post[:C_country] = billing_address[:country]
216
210
  post[:C_telephone] = billing_address[:phone]
@@ -390,10 +390,6 @@ module ActiveMerchant #:nodoc:
390
390
  post[key] = value if !value.blank? || options[:required]
391
391
  end
392
392
 
393
- def localized_amount(money, currency)
394
- amount = amount(money)
395
- CURRENCIES_WITHOUT_FRACTIONS.include?(currency.to_s) ? amount.split('.').first : amount
396
- end
397
393
  end
398
394
 
399
395
  end
@@ -219,11 +219,6 @@ module ActiveMerchant #:nodoc:
219
219
  end
220
220
 
221
221
  def message_from(response)
222
- if response[:response_code].to_i == DECLINED
223
- return CVVResult.messages[ response[:card_code_response_code] ] if CARD_CODE_ERRORS.include?(response[:card_code_response_code])
224
- return AVSResult.messages[ response[:avs_result_code] ] if AVS_ERRORS.include?(response[:avs_result_code])
225
- end
226
-
227
222
  return response[:response_reason_text].nil? ? '' : response[:response_reason_text][0..-1]
228
223
  end
229
224
 
@@ -100,7 +100,7 @@ module ActiveMerchant #:nodoc:
100
100
  post[:delim_data] = "TRUE"
101
101
  post[:delim_char] = ","
102
102
  post[:encap_char] = "$"
103
- post[:solution_ID] = application_id if application_id.present? && application_id != "ActiveMerchant"
103
+ post[:solution_ID] = application_id if application_id
104
104
 
105
105
  request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
106
106
  request
@@ -4,18 +4,10 @@ module ActiveMerchant #:nodoc:
4
4
  self.test_url = 'https://api.securionpay.com/'
5
5
  self.live_url = 'https://api.securionpay.com/'
6
6
 
7
- self.supported_countries = ["AF", "AL", "DZ", "AS", "AD", "AO", "AI", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD",
8
- "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA", "CV",
9
- "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ",
10
- "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE",
11
- "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID",
12
- "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KV", "KW", "KG", "LA", "LV", "LB",
13
- "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM",
14
- "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "AN", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP",
15
- "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW", "BL", "SH",
16
- "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC", "SL", "SG", "SK", "SI", "SB", "SO", "ZA", "GS", "ES",
17
- "LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC",
18
- "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW", "AX"]
7
+
8
+ self.supported_countries = %w(AL AD AT BY BE BG HR CY RE DK EE IS FI FR DE GI GR HU IS IE IT LV LI LT LU
9
+ MK MT MD MC NL NO PL PT RO RU MA RS SK SI ES SE CH UA KI CI RS RS ME)
10
+
19
11
  self.default_currency = 'USD'
20
12
  self.money_format = :cents
21
13
  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
@@ -79,6 +71,29 @@ module ActiveMerchant #:nodoc:
79
71
  end
80
72
  end
81
73
 
74
+ def store(credit_card, options = {})
75
+ if options[:customer_id].blank?
76
+ MultiResponse.run() do |r|
77
+ #create charge object
78
+ r.process { authorize(100, credit_card, options) }
79
+ #create customer and save card
80
+ r.process { create_customer_add_card(r.authorization, options) }
81
+ #void the charge
82
+ r.process(:ignore_result) { void(r.params["metadata"]["chargeId"], options) }
83
+ end
84
+ else
85
+ verify(credit_card, options)
86
+ end
87
+ end
88
+
89
+ def customer(options = {})
90
+ if options[:customer_id].blank?
91
+ return nil
92
+ else
93
+ commit("customers/#{CGI.escape(options[:customer_id])}", nil, options, :get)
94
+ end
95
+ end
96
+
82
97
  def supports_scrubbing?
83
98
  true
84
99
  end
@@ -92,8 +107,18 @@ module ActiveMerchant #:nodoc:
92
107
 
93
108
  private
94
109
 
110
+ def create_customer_add_card(authorization, options)
111
+ post = {}
112
+ post[:email] = options[:email]
113
+ post[:description] = options[:description]
114
+ post[:card] = authorization
115
+ post[:metadata] = {}
116
+ post[:metadata][:chargeId] = authorization
117
+ commit('customers', post, options)
118
+ end
119
+
95
120
  def add_customer(post, payment, options)
96
- post[:customer] = options[:customer] if options[:customer]
121
+ post[:customerId] = options[:customer_id] if options[:customer_id]
97
122
  end
98
123
 
99
124
  def add_customer_data(post, options)
@@ -156,8 +181,8 @@ module ActiveMerchant #:nodoc:
156
181
  JSON.parse(body)
157
182
  end
158
183
 
159
- def commit(url, parameters = nil, options = {})
160
- response = api_request(url, parameters, options)
184
+ def commit(url, parameters = nil, options = {}, method = nil)
185
+ response = api_request(url, parameters, options, method)
161
186
  success = !response.key?("error")
162
187
 
163
188
  Response.new(success,
@@ -206,10 +231,14 @@ module ActiveMerchant #:nodoc:
206
231
  end.compact.join("&")
207
232
  end
208
233
 
209
- def api_request(endpoint, parameters = nil, options = {})
234
+ def api_request(endpoint, parameters = nil, options = {}, method = nil)
210
235
  raw_response = response = nil
211
236
  begin
212
- raw_response = ssl_post(self.live_url + endpoint, post_data(parameters), headers(options))
237
+ if method.blank?
238
+ raw_response = ssl_post(self.live_url + endpoint, post_data(parameters), headers(options))
239
+ else
240
+ raw_response = ssl_request(method, self.live_url + endpoint, post_data(parameters), headers(options))
241
+ end
213
242
  response = parse(raw_response)
214
243
  rescue ResponseError => e
215
244
  raw_response = e.response.body