activemerchant 1.32.0 → 1.33.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 (52) hide show
  1. data/CHANGELOG +50 -0
  2. data/CONTRIBUTORS +8 -0
  3. data/README.md +6 -4
  4. data/lib/active_merchant/billing/check.rb +4 -3
  5. data/lib/active_merchant/billing/credit_card.rb +7 -3
  6. data/lib/active_merchant/billing/gateways/authorize_net.rb +27 -7
  7. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +8 -1
  8. data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -185
  9. data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
  10. data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
  11. data/lib/active_merchant/billing/gateways/cc5.rb +0 -4
  12. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +94 -12
  13. data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
  14. data/lib/active_merchant/billing/gateways/litle.rb +41 -11
  15. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +27 -6
  16. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -2
  17. data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
  18. data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
  19. data/lib/active_merchant/billing/gateways/orbital.rb +181 -48
  20. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
  21. data/lib/active_merchant/billing/gateways/paymill.rb +27 -13
  22. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +11 -6
  23. data/lib/active_merchant/billing/gateways/paypal_express.rb +25 -7
  24. data/lib/active_merchant/billing/gateways/pin.rb +5 -5
  25. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +16 -11
  26. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
  27. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
  28. data/lib/active_merchant/billing/gateways/sage.rb +10 -5
  29. data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -0
  30. data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
  31. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
  32. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
  33. data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
  34. data/lib/active_merchant/billing/integrations/dwolla/common.rb +21 -0
  35. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +15 -6
  36. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +11 -6
  37. data/lib/active_merchant/billing/integrations/dwolla/return.rb +12 -4
  38. data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
  39. data/lib/active_merchant/billing/integrations/notification.rb +13 -8
  40. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +13 -1
  41. data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
  42. data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
  43. data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
  44. data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
  45. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +68 -5
  46. data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
  47. data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
  48. data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
  49. data/lib/active_merchant/version.rb +1 -1
  50. data.tar.gz.sig +0 -0
  51. metadata +72 -62
  52. metadata.gz.sig +0 -0
@@ -0,0 +1,155 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class CardStreamModernGateway < Gateway
4
+ self.test_url = self.live_url = 'https://gateway.cardstream.com/direct/'
5
+ self.money_format = :cents
6
+ self.default_currency = 'GBP'
7
+ self.supported_countries = ['GB']
8
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro, :solo, :switch]
9
+ self.homepage_url = 'http://www.cardstream.com/'
10
+ self.display_name = 'CardStream'
11
+
12
+ def initialize(options = {})
13
+ requires!(options, :login)
14
+ if(options[:threeDSRequired])
15
+ @threeDSRequired = options[:threeDSRequired]
16
+ else
17
+ @threeDSRequired = 'N'
18
+ end
19
+ super
20
+ end
21
+
22
+ def authorize(money, creditcard, options = {})
23
+ post = {}
24
+ add_amount(post, money, options)
25
+ add_invoice(post, creditcard, money, options)
26
+ add_creditcard(post, creditcard)
27
+ add_address(post, creditcard, options)
28
+ add_customer_data(post, options)
29
+ commit('PREAUTH', post)
30
+ end
31
+
32
+ def purchase(money, creditcard, options = {})
33
+ post = {}
34
+ add_amount(post, money, options)
35
+ add_invoice(post, creditcard, money, options)
36
+ add_creditcard(post, creditcard)
37
+ add_address(post, creditcard, options)
38
+ add_customer_data(post, options)
39
+ commit('SALE', post)
40
+ end
41
+
42
+ def capture(money, authorization, options = {})
43
+ post = {}
44
+ add_pair(post, :xref, authorization)
45
+ add_amount(post, money, options)
46
+ commit('SALE', post)
47
+ end
48
+
49
+ def refund(money, authorization, options = {})
50
+ post = {}
51
+ add_pair(post, :xref, authorization)
52
+ add_amount(post, money, options)
53
+ commit('REFUND', post)
54
+ end
55
+
56
+ def void(authorization, options = {})
57
+ post = {}
58
+ add_pair(post, :xref, authorization)
59
+ commit('REFUND', post)
60
+ end
61
+
62
+ private
63
+
64
+ def add_amount(post, money, options)
65
+ add_pair(post, :amount, amount(money), :required => true)
66
+ add_pair(post, :currencyCode, options[:currency] || self.default_currency)
67
+ end
68
+
69
+ def add_customer_data(post, options)
70
+ address = options[:billing_address] || options[:address]
71
+ add_pair(post, :customerPostCode, address[:zip])
72
+ add_pair(post, :customerEmail, options[:email])
73
+ add_pair(post, :customerPhone, options[:phone])
74
+ end
75
+
76
+ def add_address(post, creditcard, options)
77
+ address = options[:billing_address] || options[:address]
78
+
79
+ return if address.nil?
80
+
81
+ add_pair(post, :customerAddress, address[:address1] + " " + (address[:address2].nil? ? "" : address[:address2]) )
82
+ add_pair(post, :customerPostCode, address[:zip])
83
+ end
84
+
85
+ def add_invoice(post, credit_card, money, options)
86
+ add_pair(post, :transactionUnique, options[:order_id], :required => true)
87
+ add_pair(post, :orderRef, options[:description] || options[:order_id], :required => true)
88
+ if [ 'american_express', 'diners_club' ].include?(card_brand(credit_card).to_s)
89
+ add_pair(post, :item1Quantity, 1)
90
+ add_pair(post, :item1Description, (options[:description] || options[:order_id]).slice(0, 15))
91
+ add_pair(post, :item1GrossValue, amount(money))
92
+ end
93
+ end
94
+
95
+ def add_creditcard(post, credit_card)
96
+ add_pair(post, :customerName, credit_card.name, :required => true)
97
+ add_pair(post, :cardNumber, credit_card.number, :required => true)
98
+
99
+ add_pair(post, :cardExpiryMonth, format(credit_card.month, :two_digits), :required => true)
100
+ add_pair(post, :cardExpiryYear, format(credit_card.year, :two_digits), :required => true)
101
+
102
+ if requires_start_date_or_issue_number?(credit_card)
103
+ add_pair(post, :cardStartMonth, format(credit_card.start_month, :two_digits))
104
+ add_pair(post, :cardStartYear, format(credit_card.start_year, :two_digits))
105
+
106
+ add_pair(post, :cardIssueNumber, credit_card.issue_number)
107
+ end
108
+
109
+ add_pair(post, :cardCVV, credit_card.verification_value)
110
+ end
111
+
112
+ def parse(body)
113
+ result = {}
114
+ pairs = body.split("&")
115
+ pairs.each do |pair|
116
+ a = pair.split("=")
117
+ result[a[0].to_sym] = CGI.unescape(a[1])
118
+ end
119
+ result
120
+ end
121
+
122
+ def commit(action, parameters)
123
+ response = parse( ssl_post(self.live_url, post_data(action, parameters)) )
124
+
125
+ Response.new(response[:responseCode] == "0",
126
+ response[:responseCode] == "0" ? "APPROVED" : response[:responseMessage],
127
+ response,
128
+ :test => test?,
129
+ :authorization => response[:xref],
130
+ :avs_result => {
131
+ :street_match => response[:addressCheck],
132
+ :postal_match => response[:postcodeCheck],
133
+ },
134
+ :cvv_result => response[:cv2Check]
135
+ )
136
+ end
137
+
138
+ def post_data(action, parameters = {})
139
+ parameters.update(
140
+ :merchantID => @options[:login],
141
+ :action => action,
142
+ :type => '1', #Ecommerce
143
+ :countryCode => self.supported_countries[0],
144
+ :threeDSRequired => @threeDSRequired #Disable 3d secure by default
145
+ )
146
+ parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
147
+ end
148
+
149
+ def add_pair(post, key, value, options = {})
150
+ post[key] = value if !value.blank? || options[:required]
151
+ end
152
+ end
153
+ end
154
+ end
155
+
@@ -1,7 +1,3 @@
1
- if RUBY_VERSION < '1.9' && $KCODE == "NONE"
2
- $KCODE = 'u'
3
- end
4
-
5
1
  module ActiveMerchant #:nodoc:
6
2
  module Billing #:nodoc:
7
3
  # CC5 API is used by many banks in Turkey. Extend this base class to provide
@@ -1,15 +1,17 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class FirstdataE4Gateway < Gateway
4
- self.test_url = "https://api.demo.globalgatewaye4.firstdata.com/transaction"
5
- self.live_url = "https://api.globalgatewaye4.firstdata.com/transaction"
4
+ # TransArmor support requires v11 or lower
5
+ self.test_url = "https://api.demo.globalgatewaye4.firstdata.com/transaction/v11"
6
+ self.live_url = "https://api.globalgatewaye4.firstdata.com/transaction/v11"
6
7
 
7
8
  TRANSACTIONS = {
8
9
  :sale => "00",
9
10
  :authorization => "01",
10
11
  :capture => "32",
11
12
  :void => "33",
12
- :credit => "34"
13
+ :credit => "34",
14
+ :store => "05"
13
15
  }
14
16
 
15
17
  POST_HEADERS = {
@@ -44,12 +46,12 @@ module ActiveMerchant #:nodoc:
44
46
  super
45
47
  end
46
48
 
47
- def authorize(money, credit_card, options = {})
48
- commit(:authorization, build_sale_or_authorization_request(money, credit_card, options))
49
+ def authorize(money, credit_card_or_store_authorization, options = {})
50
+ commit(:authorization, build_sale_or_authorization_request(money, credit_card_or_store_authorization, options))
49
51
  end
50
52
 
51
- def purchase(money, credit_card, options = {})
52
- commit(:sale, build_sale_or_authorization_request(money, credit_card, options))
53
+ def purchase(money, credit_card_or_store_authorization, options = {})
54
+ commit(:sale, build_sale_or_authorization_request(money, credit_card_or_store_authorization, options))
53
55
  end
54
56
 
55
57
  def capture(money, authorization, options = {})
@@ -64,6 +66,33 @@ module ActiveMerchant #:nodoc:
64
66
  commit(:credit, build_capture_or_credit_request(money, authorization, options))
65
67
  end
66
68
 
69
+ # Tokenize a credit card with TransArmor
70
+ #
71
+ # The TransArmor token and other card data necessary for subsequent
72
+ # transactions is stored in the response's +authorization+ attribute.
73
+ # The authorization string may be passed to +authorize+ and +purchase+
74
+ # instead of a +ActiveMerchant::Billing::CreditCard+ instance.
75
+ #
76
+ # TransArmor support must be explicitly activated on your gateway
77
+ # account by FirstData. If your authorization string is empty, contact
78
+ # FirstData support for account setup assistance.
79
+ #
80
+ # === Example
81
+ #
82
+ # # Generate token
83
+ # result = gateway.store(credit_card)
84
+ # if result.success?
85
+ # my_record.update_attributes(:authorization => result.authorization)
86
+ # end
87
+ #
88
+ # # Use token
89
+ # result = gateway.purchase(1000, my_record.authorization)
90
+ #
91
+ # https://firstdata.zendesk.com/entries/21303361-transarmor-tokenization
92
+ def store(credit_card, options = {})
93
+ commit(:store, build_store_request(credit_card, options), credit_card)
94
+ end
95
+
67
96
  private
68
97
 
69
98
  def build_request(action, body)
@@ -79,11 +108,17 @@ module ActiveMerchant #:nodoc:
79
108
  xml.target!
80
109
  end
81
110
 
82
- def build_sale_or_authorization_request(money, credit_card, options)
111
+ def build_sale_or_authorization_request(money, credit_card_or_store_authorization, options)
83
112
  xml = Builder::XmlMarkup.new
84
113
 
85
114
  add_amount(xml, money)
86
- add_credit_card(xml, credit_card)
115
+
116
+ if credit_card_or_store_authorization.is_a? String
117
+ add_credit_card_token(xml, credit_card_or_store_authorization)
118
+ else
119
+ add_credit_card(xml, credit_card_or_store_authorization)
120
+ end
121
+
87
122
  add_customer_data(xml, options)
88
123
  add_invoice(xml, options)
89
124
 
@@ -100,6 +135,15 @@ module ActiveMerchant #:nodoc:
100
135
  xml.target!
101
136
  end
102
137
 
138
+ def build_store_request(credit_card, options)
139
+ xml = Builder::XmlMarkup.new
140
+
141
+ add_credit_card(xml, credit_card)
142
+ add_customer_data(xml, options)
143
+
144
+ xml.target!
145
+ end
146
+
103
147
  def add_credentials(xml)
104
148
  xml.tag! "ExactID", @options[:login]
105
149
  xml.tag! "Password", @options[:password]
@@ -132,6 +176,21 @@ module ActiveMerchant #:nodoc:
132
176
  end
133
177
  end
134
178
 
179
+ def add_credit_card_token(xml, store_authorization)
180
+ params = store_authorization.split(";")
181
+ credit_card = CreditCard.new(
182
+ :brand => params[1],
183
+ :first_name => params[2],
184
+ :last_name => params[3],
185
+ :month => params[4],
186
+ :year => params[5])
187
+
188
+ xml.tag! "TransarmorToken", params[0]
189
+ xml.tag! "Expiry_Date", expdate(credit_card)
190
+ xml.tag! "CardHoldersName", credit_card.name
191
+ xml.tag! "CardType", credit_card.brand
192
+ end
193
+
135
194
  def add_customer_data(xml, options)
136
195
  xml.tag! "Customer_Ref", options[:customer] if options[:customer]
137
196
  xml.tag! "Client_IP", options[:ip] if options[:ip]
@@ -153,7 +212,7 @@ module ActiveMerchant #:nodoc:
153
212
  "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
154
213
  end
155
214
 
156
- def commit(action, request)
215
+ def commit(action, request, credit_card = nil)
157
216
  url = (test? ? self.test_url : self.live_url)
158
217
  begin
159
218
  response = parse(ssl_post(url, build_request(action, request), POST_HEADERS))
@@ -163,7 +222,7 @@ module ActiveMerchant #:nodoc:
163
222
 
164
223
  Response.new(successful?(response), message_from(response), response,
165
224
  :test => test?,
166
- :authorization => authorization_from(response),
225
+ :authorization => response_authorization(action, response, credit_card),
167
226
  :avs_result => {:code => response[:avs]},
168
227
  :cvv_result => response[:cvv2]
169
228
  )
@@ -173,6 +232,14 @@ module ActiveMerchant #:nodoc:
173
232
  response[:transaction_approved] == SUCCESS
174
233
  end
175
234
 
235
+ def response_authorization(action, response, credit_card)
236
+ if action == :store
237
+ store_authorization_from(response, credit_card)
238
+ else
239
+ authorization_from(response)
240
+ end
241
+ end
242
+
176
243
  def authorization_from(response)
177
244
  if response[:authorization_num] && response[:transaction_tag]
178
245
  [
@@ -185,6 +252,21 @@ module ActiveMerchant #:nodoc:
185
252
  end
186
253
  end
187
254
 
255
+ def store_authorization_from(response, credit_card)
256
+ if response[:transarmor_token].present?
257
+ [
258
+ response[:transarmor_token],
259
+ credit_card.brand,
260
+ credit_card.first_name,
261
+ credit_card.last_name,
262
+ credit_card.month,
263
+ credit_card.year
264
+ ].map { |value| value.to_s.gsub(/;/, "") }.join(";")
265
+ else
266
+ raise StandardError, "TransArmor support is not enabled on your #{display_name} account"
267
+ end
268
+ end
269
+
188
270
  def money_from_authorization(auth)
189
271
  _, _, amount = auth.split(/;/, 3)
190
272
  amount.to_i # return the # of cents, no need to divide
@@ -193,7 +275,7 @@ module ActiveMerchant #:nodoc:
193
275
  def message_from(response)
194
276
  if(response[:faultcode] && response[:faultstring])
195
277
  response[:faultstring]
196
- elsif(response[:error_number] != "0")
278
+ elsif(response[:error_number] && response[:error_number] != "0")
197
279
  response[:error_description]
198
280
  else
199
281
  result = (response[:exact_message] || "")
@@ -1,7 +1,3 @@
1
- if RUBY_VERSION < '1.9' && $KCODE == "NONE"
2
- $KCODE = 'u'
3
- end
4
-
5
1
  module ActiveMerchant #:nodoc:
6
2
  module Billing #:nodoc:
7
3
  class GarantiGateway < Gateway
@@ -82,13 +82,26 @@ module ActiveMerchant #:nodoc:
82
82
  end
83
83
 
84
84
  def capture(money, authorization, options = {})
85
- to_pass = create_capture_hash(money, authorization, options)
85
+ transaction_id, kind = split_authorization(authorization)
86
+ to_pass = create_capture_hash(money, transaction_id, options)
86
87
  build_response(:capture, @litle.capture(to_pass))
87
88
  end
88
89
 
90
+ # Note: Litle requires that authorization requests be voided via auth_reversal
91
+ # and other requests via void. To maintain the same interface as the other
92
+ # gateways the transaction_id and the kind of transaction are concatenated
93
+ # together with a ; separator (e.g. 1234;authorization)
94
+ #
95
+ # A partial auth_reversal can be accomplished by passing :amount as an option
89
96
  def void(identification, options = {})
90
- to_pass = create_void_hash(identification, options)
91
- build_response(:void, @litle.void(to_pass))
97
+ transaction_id, kind = split_authorization(identification)
98
+ if(kind == 'authorization')
99
+ to_pass = create_auth_reversal_hash(transaction_id, options[:amount], options)
100
+ build_response(:authReversal, @litle.auth_reversal(to_pass))
101
+ else
102
+ to_pass = create_void_hash(transaction_id, options)
103
+ build_response(:void, @litle.void(to_pass))
104
+ end
92
105
  end
93
106
 
94
107
  def credit(money, identification_or_token, options = {})
@@ -142,17 +155,11 @@ module ActiveMerchant #:nodoc:
142
155
  if response['response'] == "0"
143
156
  detail = response["#{kind}Response"]
144
157
  fraud = fraud_result(detail)
145
- authorization = case kind
146
- when :registerToken
147
- response['registerTokenResponse']['litleToken']
148
- else
149
- detail['litleTxnId']
150
- end
151
158
  Response.new(
152
159
  valid_responses.include?(detail['response']),
153
160
  detail['message'],
154
161
  { :litleOnlineResponse => response },
155
- :authorization => authorization,
162
+ :authorization => authorization_from(detail, kind),
156
163
  :avs_result => { :code => fraud['avs'] },
157
164
  :cvv_result => fraud['cvv'],
158
165
  :test => test?
@@ -162,6 +169,22 @@ module ActiveMerchant #:nodoc:
162
169
  end
163
170
  end
164
171
 
172
+ # Generates an authorization string of the appropriate id and the kind of transaction
173
+ # See #void for how the kind is used
174
+ def authorization_from(litle_response, kind)
175
+ case kind
176
+ when :registerToken
177
+ authorization = litle_response['litleToken']
178
+ else
179
+ authorization = [litle_response['litleTxnId'], kind.to_s].join(";")
180
+ end
181
+ end
182
+
183
+ def split_authorization(authorization)
184
+ transaction_id, kind = authorization.to_s.split(';')
185
+ [transaction_id, kind]
186
+ end
187
+
165
188
  def build_authorize_request(money, creditcard_or_token, options)
166
189
  payment_method = build_payment_method(creditcard_or_token, options)
167
190
 
@@ -224,7 +247,8 @@ module ActiveMerchant #:nodoc:
224
247
  if identification_or_cardtoken.is_a?(LitleCardToken)
225
248
  add_cardtoken_hash(hash, identification_or_cardtoken)
226
249
  else
227
- hash['litleTxnId'] = identification_or_cardtoken
250
+ transaction_id, kind = split_authorization(identification_or_cardtoken)
251
+ hash['litleTxnId'] = transaction_id
228
252
  end
229
253
  end
230
254
 
@@ -274,6 +298,12 @@ module ActiveMerchant #:nodoc:
274
298
  hash
275
299
  end
276
300
 
301
+ def create_auth_reversal_hash(identification, money, options)
302
+ hash = create_hash(money, options)
303
+ hash['litleTxnId'] = identification
304
+ hash
305
+ end
306
+
277
307
  def create_hash(money, options)
278
308
  fraud_check_type = {}
279
309
  if options[:ip]
@@ -23,6 +23,8 @@ module ActiveMerchant #:nodoc:
23
23
 
24
24
  def authorize(money, creditcard_or_card_id, options = {})
25
25
  post = {}
26
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
27
+ post[:moto_ecommerce_ind] = options[:moto_ecommerce_ind] if options.has_key?(:moto_ecommerce_ind)
26
28
  add_invoice(post, options)
27
29
  add_payment_source(post, creditcard_or_card_id, options)
28
30
  add_address(post, options)
@@ -31,6 +33,8 @@ module ActiveMerchant #:nodoc:
31
33
 
32
34
  def purchase(money, creditcard_or_card_id, options = {})
33
35
  post = {}
36
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
37
+ post[:moto_ecommerce_ind] = options[:moto_ecommerce_ind] if options.has_key?(:moto_ecommerce_ind)
34
38
  add_invoice(post, options)
35
39
  add_payment_source(post, creditcard_or_card_id, options)
36
40
  add_address(post, options)
@@ -40,33 +44,48 @@ module ActiveMerchant #:nodoc:
40
44
  def capture(money, transaction_id, options = {})
41
45
  post ={}
42
46
  post[:transaction_id] = transaction_id
47
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
43
48
  commit('S', money, post)
44
49
  end
45
50
 
46
51
  def store(creditcard, options = {})
47
52
  post = {}
53
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
48
54
  add_creditcard(post, creditcard, options)
49
55
  commit('T', nil, post)
50
56
  end
51
57
 
52
58
  def unstore(card_id)
53
59
  post = {}
60
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
54
61
  post[:card_id] = card_id
55
62
  commit('X', nil, post)
56
63
  end
57
64
 
58
65
  def refund(money, identification, options = {})
59
- commit('U', money, options.merge(:transaction_id => identification))
66
+ post = {}
67
+ post[:transaction_id] = identification
68
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
69
+ options.delete(:customer)
70
+ options.delete(:billing_address)
71
+ commit('U', money, options.merge(post))
60
72
  end
61
73
 
62
74
  def credit(money, creditcard_or_card_id, options = {})
63
75
  post = {}
76
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
77
+ add_invoice(post, options)
64
78
  add_payment_source(post, creditcard_or_card_id, options)
65
79
  commit('C', money, post)
66
80
  end
67
81
 
68
82
  def void(transaction_id, options = {})
69
- commit('V', nil, options.merge(:transaction_id => transaction_id))
83
+ post = {}
84
+ post[:transaction_id] = transaction_id
85
+ post[:client_reference_number] = options[:customer] if options.has_key?(:customer)
86
+ options.delete(:customer)
87
+ options.delete(:billing_address)
88
+ commit('V', nil, options.merge(post))
70
89
  end
71
90
 
72
91
  private
@@ -111,11 +130,15 @@ module ActiveMerchant #:nodoc:
111
130
  end
112
131
 
113
132
  def commit(action, money, parameters)
114
-
115
133
  url = test? ? self.test_url : self.live_url
116
134
  parameters[:transaction_amount] = amount(money) if money unless action == 'V'
117
135
 
118
- response = parse( ssl_post(url, post_data(action,parameters)) )
136
+
137
+ response = begin
138
+ parse( ssl_post(url, post_data(action,parameters)) )
139
+ rescue ActiveMerchant::ResponseError => e
140
+ { "error_code" => "404", "auth_response_text" => e.to_s }
141
+ end
119
142
 
120
143
  Response.new(response["error_code"] == "000", message_from(response), response,
121
144
  :authorization => response["transaction_id"],
@@ -123,7 +146,6 @@ module ActiveMerchant #:nodoc:
123
146
  :cvv_result => response["cvv2_result"],
124
147
  :avs_result => { :code => response["avs_result"] }
125
148
  )
126
-
127
149
  end
128
150
 
129
151
  def expdate(creditcard)
@@ -152,4 +174,3 @@ module ActiveMerchant #:nodoc:
152
174
  end
153
175
  end
154
176
  end
155
-
@@ -62,8 +62,8 @@ module ActiveMerchant #:nodoc:
62
62
  post = {
63
63
  'cardName' => creditcard.name,
64
64
  'cardNumber' => creditcard.number,
65
- 'cardExpiryMonth' => sprintf('%02d', creditcard.month),
66
- 'cardExpiryYear' => sprintf('%02d', creditcard.year)
65
+ 'cardExpiryMonth' => format(creditcard.month, :two_digits),
66
+ 'cardExpiryYear' => format(creditcard.year, :two_digits)
67
67
  }
68
68
  commit('addCard', post)
69
69
  end
@@ -41,7 +41,7 @@ module ActiveMerchant
41
41
  :purchase => 'purchase',
42
42
  :capture => 'completion',
43
43
  :status => 'status',
44
- :credit => 'refund'
44
+ :refund => 'refund'
45
45
  }
46
46
 
47
47
  # Create a new NetRegistry gateway.
@@ -94,13 +94,18 @@ module ActiveMerchant
94
94
  commit(:purchase, params)
95
95
  end
96
96
 
97
- def credit(money, identification, options = {})
97
+ def refund(money, identification, options = {})
98
98
  params = {
99
99
  'AMOUNT' => amount(money),
100
100
  'TXNREF' => identification
101
101
  }
102
102
  add_request_details(params, options)
103
- commit(:credit, params)
103
+ commit(:refund, params)
104
+ end
105
+
106
+ def credit(money, identification, options = {})
107
+ deprecated CREDIT_DEPRECATION_MESSAGE
108
+ refund(money, identification, options)
104
109
  end
105
110
 
106
111
  # Specific to NetRegistry.