activemerchant 1.32.1 → 1.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +41 -0
  3. data/CONTRIBUTORS +8 -0
  4. data/README.md +6 -4
  5. data/lib/active_merchant/billing/check.rb +4 -3
  6. data/lib/active_merchant/billing/credit_card.rb +7 -3
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +27 -7
  8. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +8 -1
  9. data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -185
  10. data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
  11. data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
  12. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +94 -12
  13. data/lib/active_merchant/billing/gateways/litle.rb +41 -11
  14. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +27 -6
  15. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -2
  16. data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
  17. data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
  18. data/lib/active_merchant/billing/gateways/orbital.rb +181 -48
  19. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
  20. data/lib/active_merchant/billing/gateways/paymill.rb +5 -5
  21. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +11 -6
  22. data/lib/active_merchant/billing/gateways/paypal_express.rb +25 -7
  23. data/lib/active_merchant/billing/gateways/pin.rb +5 -5
  24. data/lib/active_merchant/billing/gateways/sage.rb +10 -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_pay.rb +1 -0
  29. data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
  30. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +8 -3
  31. data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
  32. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
  33. data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
  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/notification.rb +13 -8
  39. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +13 -1
  40. data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
  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/quickpay/notification.rb +68 -5
  45. data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
  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/version.rb +1 -1
  49. metadata +14 -4
  50. metadata.gz.sig +0 -0
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
34
34
  money = amount(money)
35
35
  case normalize(credit_card_or_reference)
36
36
  when /1$/, AUTHORIZATION
37
- Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
37
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true, :authorization => AUTHORIZATION)
38
38
  when /2$/
39
39
  Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE },:test => true)
40
40
  else
@@ -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,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] || "")
@@ -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
-