activemerchant 1.13.0 → 1.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +19 -0
  3. data/CONTRIBUTORS +14 -2
  4. data/README.rdoc +2 -0
  5. data/lib/active_merchant/billing/credit_card.rb +4 -4
  6. data/lib/active_merchant/billing/gateway.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +10 -5
  8. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +133 -11
  9. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +1 -1
  10. data/lib/active_merchant/billing/gateways/beanstream.rb +39 -2
  11. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +64 -26
  12. data/lib/active_merchant/billing/gateways/bogus.rb +21 -3
  13. data/lib/active_merchant/billing/gateways/cyber_source.rb +5 -1
  14. data/lib/active_merchant/billing/gateways/data_cash.rb +1 -1
  15. data/lib/active_merchant/billing/gateways/efsnet.rb +1 -1
  16. data/lib/active_merchant/billing/gateways/epay.rb +5 -1
  17. data/lib/active_merchant/billing/gateways/eway.rb +4 -0
  18. data/lib/active_merchant/billing/gateways/eway_managed.rb +231 -0
  19. data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -7
  20. data/lib/active_merchant/billing/gateways/first_pay.rb +7 -2
  21. data/lib/active_merchant/billing/gateways/iridium.rb +1 -1
  22. data/lib/active_merchant/billing/gateways/jetpay.rb +5 -2
  23. data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -1
  24. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +6 -4
  25. data/lib/active_merchant/billing/gateways/merchant_ware.rb +1 -1
  26. data/lib/active_merchant/billing/gateways/moneris.rb +1 -1
  27. data/lib/active_merchant/billing/gateways/netaxept.rb +6 -1
  28. data/lib/active_merchant/billing/gateways/ogone.rb +1 -1
  29. data/lib/active_merchant/billing/gateways/orbital.rb +317 -0
  30. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  31. data/lib/active_merchant/billing/gateways/paybox_direct.rb +1 -1
  32. data/lib/active_merchant/billing/gateways/payflow.rb +1 -1
  33. data/lib/active_merchant/billing/gateways/payflow_express.rb +6 -1
  34. data/lib/active_merchant/billing/gateways/payment_express.rb +6 -1
  35. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -2
  36. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +11 -7
  37. data/lib/active_merchant/billing/gateways/plugnpay.rb +1 -1
  38. data/lib/active_merchant/billing/gateways/psigate.rb +1 -1
  39. data/lib/active_merchant/billing/gateways/qbms.rb +1 -1
  40. data/lib/active_merchant/billing/gateways/quantum.rb +6 -1
  41. data/lib/active_merchant/billing/gateways/quickpay.rb +6 -1
  42. data/lib/active_merchant/billing/gateways/realex.rb +196 -72
  43. data/lib/active_merchant/billing/gateways/sage_pay.rb +7 -2
  44. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +38 -2
  45. data/lib/active_merchant/billing/gateways/smart_ps.rb +2 -2
  46. data/lib/active_merchant/billing/gateways/trust_commerce.rb +7 -2
  47. data/lib/active_merchant/billing/gateways/verifi.rb +1 -1
  48. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  49. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +0 -1
  50. data/lib/active_merchant/billing/integrations/return.rb +6 -1
  51. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +6 -0
  52. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +5 -1
  53. data/lib/active_merchant/common/connection.rb +15 -0
  54. data/lib/active_merchant/common/posts_data.rb +2 -0
  55. data/lib/active_merchant/common/utils.rb +4 -0
  56. data/lib/active_merchant/version.rb +1 -1
  57. metadata +8 -4
  58. metadata.gz.sig +0 -0
@@ -24,11 +24,16 @@ module ActiveMerchant #:nodoc:
24
24
  commit(request)
25
25
  end
26
26
 
27
- def credit(money, identification, options = {})
27
+ def refund(money, identification, options = {})
28
28
  request = build_reference_request(:credit, money, identification, options)
29
29
  commit(request)
30
30
  end
31
31
 
32
+ def credit(money, identification, options = {})
33
+ deprecated CREDIT_DEPRECATION_MESSAGE
34
+ refund(money, identification, options)
35
+ end
36
+
32
37
  def setup_authorization(money, options = {})
33
38
  requires!(options, :return_url, :cancel_return_url)
34
39
 
@@ -64,12 +64,17 @@ module ActiveMerchant #:nodoc:
64
64
  end
65
65
 
66
66
  # Refund funds to the card holder
67
- def credit(money, identification, options = {})
67
+ def refund(money, identification, options = {})
68
68
  requires!(options, :description)
69
69
 
70
70
  request = build_capture_or_credit_request(money, identification, options)
71
71
  commit(:credit, request)
72
72
  end
73
+
74
+ def credit(money, identification, options = {})
75
+ deprecated CREDIT_DEPRECATION_MESSAGE
76
+ refund(money, identification, options)
77
+ end
73
78
 
74
79
  # token based billing
75
80
 
@@ -105,8 +105,13 @@ module ActiveMerchant #:nodoc:
105
105
  commit 'DoVoid', build_void_request(authorization, options)
106
106
  end
107
107
 
108
+ def refund(money, identification, options = {})
109
+ commit 'RefundTransaction', build_refund_request(money, identification, options)
110
+ end
111
+
108
112
  def credit(money, identification, options = {})
109
- commit 'RefundTransaction', build_credit_request(money, identification, options)
113
+ deprecated CREDIT_DEPRECATION_MESSAGE
114
+ refund(money, identification, options)
110
115
  end
111
116
 
112
117
  private
@@ -141,7 +146,7 @@ module ActiveMerchant #:nodoc:
141
146
  xml.target!
142
147
  end
143
148
 
144
- def build_credit_request(money, identification, options)
149
+ def build_refund_request(money, identification, options)
145
150
  xml = Builder::XmlMarkup.new
146
151
 
147
152
  xml.tag! 'RefundTransactionReq', 'xmlns' => PAYPAL_NAMESPACE do
@@ -2,11 +2,15 @@ module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class PaypalExpressResponse < Response
4
4
  def email
5
- @params['PayerInfo']['Payer']
5
+ info['Payer']
6
+ end
7
+
8
+ def info
9
+ (@params['PayerInfo']||{})
6
10
  end
7
11
 
8
12
  def name
9
- payer = @params['PayerInfo']['PayerName']
13
+ payer = (info['PayerName']||{})
10
14
  [payer['FirstName'], payer['MiddleName'], payer['LastName']].compact.join(' ')
11
15
  end
12
16
 
@@ -15,11 +19,11 @@ module ActiveMerchant #:nodoc:
15
19
  end
16
20
 
17
21
  def payer_id
18
- @params['PayerInfo']['PayerID']
22
+ info['PayerID']
19
23
  end
20
24
 
21
25
  def payer_country
22
- @params['PayerInfo']['PayerCountry']
26
+ info['PayerCountry']
23
27
  end
24
28
 
25
29
  # PayPal returns a contact telephone number only if your Merchant account profile settings require that the buyer enter one.
@@ -28,16 +32,16 @@ module ActiveMerchant #:nodoc:
28
32
  end
29
33
 
30
34
  def address
31
- address = @params['PaymentDetails']['ShipToAddress']
35
+ address = (@params['PaymentDetails']||{})['ShipToAddress']
32
36
  { 'name' => address['Name'],
33
- 'company' => @params['PayerInfo']['PayerBusiness'],
37
+ 'company' => info['PayerBusiness'],
34
38
  'address1' => address['Street1'],
35
39
  'address2' => address['Street2'],
36
40
  'city' => address['CityName'],
37
41
  'state' => address['StateOrProvince'],
38
42
  'country' => address['Country'],
39
43
  'zip' => address['PostalCode'],
40
- 'phone' => contact_phone || address['Phone']
44
+ 'phone' => (contact_phone || address['Phone'])
41
45
  }
42
46
  end
43
47
  end
@@ -156,7 +156,7 @@ module ActiveMerchant
156
156
  add_amount(post, money, options)
157
157
 
158
158
  if identification_or_creditcard.is_a?(String)
159
- warn CREDIT_DEPRECATION_MESSAGE
159
+ deprecated CREDIT_DEPRECATION_MESSAGE
160
160
  refund(money, identification_or_creditcard, options)
161
161
  else
162
162
  add_creditcard(post, identification_or_creditcard)
@@ -79,7 +79,7 @@ module ActiveMerchant #:nodoc:
79
79
 
80
80
  # Psigate Credit
81
81
  def credit(money, authorization, options = {})
82
- warn CREDIT_DEPRECATION_MESSAGE
82
+ deprecated CREDIT_DEPRECATION_MESSAGE
83
83
  refund(money, authorization, options)
84
84
  end
85
85
 
@@ -104,7 +104,7 @@ module ActiveMerchant #:nodoc:
104
104
  #
105
105
  #
106
106
  def credit(money, identification, options = {})
107
- warn CREDIT_DEPRECATION_MESSAGE
107
+ deprecated CREDIT_DEPRECATION_MESSAGE
108
108
  refund(money, identification, options = {})
109
109
  end
110
110
 
@@ -70,10 +70,15 @@ module ActiveMerchant #:nodoc:
70
70
  commit(build_void_request(identification, options), options)
71
71
  end
72
72
 
73
- def credit(money, identification, options = {})
73
+ def refund(money, identification, options = {})
74
74
  commit(build_credit_request(money, identification, options), options)
75
75
  end
76
76
 
77
+ def credit(money, identification, options = {})
78
+ deprecated CREDIT_DEPRECATION_MESSAGE
79
+ refund(money, identification, options)
80
+ end
81
+
77
82
  private
78
83
 
79
84
  def setup_address_hash(options)
@@ -75,7 +75,7 @@ module ActiveMerchant #:nodoc:
75
75
  commit(:cancel, post)
76
76
  end
77
77
 
78
- def credit(money, identification, options = {})
78
+ def refund(money, identification, options = {})
79
79
  post = {}
80
80
 
81
81
  add_amount_without_currency(post, money)
@@ -83,6 +83,11 @@ module ActiveMerchant #:nodoc:
83
83
 
84
84
  commit(:refund, post)
85
85
  end
86
+
87
+ def credit(money, identification, options = {})
88
+ deprecated CREDIT_DEPRECATION_MESSAGE
89
+ refund(money, identification, options)
90
+ end
86
91
 
87
92
  def store(creditcard, options = {})
88
93
  post = {}
@@ -3,11 +3,11 @@ require 'digest/sha1'
3
3
 
4
4
  module ActiveMerchant
5
5
  module Billing
6
- # Realex us the leading CC gateway in Ireland
6
+ # Realex is the leading CC gateway in Ireland
7
7
  # see http://www.realexpayments.com
8
8
  # Contributed by John Ward (john@ward.name)
9
9
  # see http://thinedgeofthewedge.blogspot.com
10
- #
10
+ #
11
11
  # Realex works using the following
12
12
  # login - The unique id of the merchant
13
13
  # password - The secret is used to digitally sign the request
@@ -15,12 +15,12 @@ module ActiveMerchant
15
15
  # and is used if the merchant wishes do distuinguish cc traffic from the different sources
16
16
  # by using a different account. This must be created in advance
17
17
  #
18
- # the Realex team decided to make the orderid unique per request,
19
- # so if validation fails you can not correct and resend using the
18
+ # the Realex team decided to make the orderid unique per request,
19
+ # so if validation fails you can not correct and resend using the
20
20
  # same order id
21
21
  class RealexGateway < Gateway
22
22
  URL = 'https://epage.payandshop.com/epage-remote.cgi'
23
-
23
+
24
24
  CARD_MAPPING = {
25
25
  'master' => 'MC',
26
26
  'visa' => 'VISA',
@@ -30,46 +30,78 @@ module ActiveMerchant
30
30
  'solo' => 'SWITCH',
31
31
  'laser' => 'LASER'
32
32
  }
33
-
33
+
34
34
  self.money_format = :cents
35
35
  self.default_currency = 'EUR'
36
36
  self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :switch, :solo, :laser ]
37
37
  self.supported_countries = [ 'IE', 'GB' ]
38
38
  self.homepage_url = 'http://www.realexpayments.com/'
39
39
  self.display_name = 'Realex'
40
-
40
+
41
41
  SUCCESS, DECLINED = "Successful", "Declined"
42
42
  BANK_ERROR = REALEX_ERROR = "Gateway is in maintenance. Please try again later."
43
43
  ERROR = CLIENT_DEACTIVATED = "Gateway Error"
44
-
44
+
45
45
  def initialize(options = {})
46
46
  requires!(options, :login, :password)
47
+ options[:refund_hash] = Digest::SHA1.hexdigest(options[:rebate_secret]) if options.has_key?(:rebate_secret)
47
48
  @options = options
48
49
  super
49
- end
50
-
50
+ end
51
+
51
52
  def purchase(money, credit_card, options = {})
52
53
  requires!(options, :order_id)
53
-
54
- request = build_purchase_or_authorization_request(:purchase, money, credit_card, options)
54
+
55
+ request = build_purchase_or_authorization_request(:purchase, money, credit_card, options)
55
56
  commit(request)
56
- end
57
-
58
- private
59
- def commit(request)
57
+ end
58
+
59
+ def authorize(money, creditcard, options = {})
60
+ requires!(options, :order_id)
61
+
62
+ request = build_purchase_or_authorization_request(:authorization, money, creditcard, options)
63
+ commit(request)
64
+ end
65
+
66
+ def capture(money, authorization, options = {})
67
+ request = build_capture_request(authorization, options)
68
+ commit(request)
69
+ end
70
+
71
+ def refund(money, authorization, options = {})
72
+ request = build_refund_request(money, authorization, options)
73
+ commit(request)
74
+ end
75
+
76
+ def credit(money, authorization, options = {})
77
+ deprecated CREDIT_DEPRECATION_MESSAGE
78
+ refund(money, authorization, options)
79
+ end
80
+
81
+ def void(authorization, options = {})
82
+ request = build_void_request(authorization, options)
83
+ commit(request)
84
+ end
85
+
86
+ private
87
+ def commit(request)
60
88
  response = parse(ssl_post(URL, request))
61
89
 
62
90
  Response.new(response[:result] == "00", message_from(response), response,
63
91
  :test => response[:message] =~ /\[ test system \]/,
64
- :authorization => response[:authcode],
65
- :cvv_result => response[:cvnresult]
66
- )
92
+ :authorization => authorization_from(response),
93
+ :cvv_result => response[:cvnresult],
94
+ :avs_result => {
95
+ :street_match => response[:avspostcoderesponse],
96
+ :postal_match => response[:avspostcoderesponse]
97
+ }
98
+ )
67
99
  end
68
100
 
69
101
  def parse(xml)
70
102
  response = {}
71
-
72
- xml = REXML::Document.new(xml)
103
+
104
+ xml = REXML::Document.new(xml)
73
105
  xml.elements.each('//response/*') do |node|
74
106
 
75
107
  if (node.elements.size == 0)
@@ -78,88 +110,178 @@ module ActiveMerchant
78
110
  node.elements.each do |childnode|
79
111
  name = "#{node.name.downcase}_#{childnode.name.downcase}"
80
112
  response[name.to_sym] = normalize(childnode.text)
81
- end
113
+ end
82
114
  end
83
115
 
84
116
  end unless xml.root.nil?
85
117
 
86
118
  response
87
119
  end
88
-
89
- def parse_credit_card_number(request)
90
- xml = REXML::Document.new(request)
91
- card_number = REXML::XPath.first(xml, '/request/card/number')
92
- card_number && card_number.text
120
+
121
+ def authorization_from(parsed)
122
+ [parsed[:orderid], parsed[:pasref], parsed[:authcode]].join(';')
93
123
  end
94
124
 
95
125
  def build_purchase_or_authorization_request(action, money, credit_card, options)
96
- timestamp = Time.now.strftime('%Y%m%d%H%M%S')
97
-
126
+ timestamp = new_timestamp
98
127
  xml = Builder::XmlMarkup.new :indent => 2
99
128
  xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'auth' do
100
-
101
- xml.tag! 'merchantid', @options[:login]
102
- xml.tag! 'account', @options[:account]
103
-
129
+ add_merchant_details(xml, options)
104
130
  xml.tag! 'orderid', sanitize_order_id(options[:order_id])
131
+ add_amount(xml, money, options)
132
+ add_card(xml, credit_card)
133
+ xml.tag! 'autosettle', 'flag' => auto_settle_flag(action)
134
+ add_signed_digest(xml, timestamp, @options[:login], options[:order_id], amount(money), (options[:currency] || currency(money)), credit_card.number)
135
+ add_comments(xml, options)
136
+ add_address_and_customer_info(xml, options)
137
+ end
138
+ xml.target!
139
+ end
140
+
141
+ def build_capture_request(authorization, options)
142
+ timestamp = new_timestamp
143
+ xml = Builder::XmlMarkup.new :indent => 2
144
+ xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'settle' do
145
+ add_merchant_details(xml, options)
146
+ add_transaction_identifiers(xml, authorization, options)
147
+ add_comments(xml, options)
148
+ add_signed_digest(xml, timestamp, @options[:login], options[:order_id])
149
+ end
150
+ xml.target!
151
+ end
152
+
153
+ def build_refund_request(money, authorization, options)
154
+ timestamp = new_timestamp
155
+ xml = Builder::XmlMarkup.new :indent => 2
156
+ xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'rebate' do
157
+ add_merchant_details(xml, options)
158
+ add_transaction_identifiers(xml, authorization, options)
105
159
  xml.tag! 'amount', amount(money), 'currency' => options[:currency] || currency(money)
160
+ xml.tag! 'refundhash', @options[:refund_hash] if @options[:refund_hash]
161
+ xml.tag! 'autosettle', 'flag' => 1
162
+ add_comments(xml, options)
163
+ add_signed_digest(xml, timestamp, @options[:login], options[:order_id], amount(money), (options[:currency] || currency(money)))
164
+ end
165
+ xml.target!
166
+ end
106
167
 
107
- xml.tag! 'card' do
108
- xml.tag! 'number', credit_card.number
109
- xml.tag! 'expdate', expiry_date(credit_card)
110
- xml.tag! 'type', CARD_MAPPING[card_brand(credit_card).to_s]
111
- xml.tag! 'chname', credit_card.name
112
- xml.tag! 'issueno', credit_card.issue_number
113
-
114
- xml.tag! 'cvn' do
115
- xml.tag! 'number', credit_card.verification_value
116
- xml.tag! 'presind', credit_card.verification_value? ? 1 : nil
117
- end
118
- end
119
-
120
- xml.tag! 'autosettle', 'flag' => auto_settle_flag(action)
121
- xml.tag! 'sha1hash', sha1from("#{timestamp}.#{@options[:login]}.#{sanitize_order_id(options[:order_id])}.#{amount(money)}.#{options[:currency] || currency(money)}.#{credit_card.number}")
122
- xml.tag! 'comments' do
123
- xml.tag! 'comment', options[:description], 'id' => 1
124
- xml.tag! 'comment', 'id' => 2
125
- end
126
-
127
- billing_address = options[:billing_address] || options[:address] || {}
128
- shipping_address = options[:shipping_address] || {}
129
-
130
- xml.tag! 'tssinfo' do
168
+ def build_void_request(authorization, options)
169
+ timestamp = new_timestamp
170
+ xml = Builder::XmlMarkup.new :indent => 2
171
+ xml.tag! 'request', 'timestamp' => timestamp, 'type' => 'void' do
172
+ add_merchant_details(xml, options)
173
+ add_transaction_identifiers(xml, authorization, options)
174
+ add_comments(xml, options)
175
+ add_signed_digest(xml, timestamp, @options[:login], options[:order_id])
176
+ end
177
+ xml.target!
178
+ end
179
+
180
+ def add_address_and_customer_info(xml, options)
181
+ billing_address = options[:billing_address] || options[:address]
182
+ shipping_address = options[:shipping_address]
183
+
184
+ return unless billing_address || shipping_address || options[:customer] || options[:invoice] || options[:ip]
185
+
186
+ xml.tag! 'tssinfo' do
187
+ xml.tag! 'custnum', options[:customer] if options[:customer]
188
+ xml.tag! 'prodid', options[:invoice] if options[:invoice]
189
+ xml.tag! 'custipaddress', options[:ip] if options[:ip]
190
+
191
+ if billing_address
131
192
  xml.tag! 'address', 'type' => 'billing' do
132
- xml.tag! 'code', billing_address[:zip]
193
+ xml.tag! 'code', avs_input_code( billing_address )
133
194
  xml.tag! 'country', billing_address[:country]
134
195
  end
196
+ end
135
197
 
198
+ if shipping_address
136
199
  xml.tag! 'address', 'type' => 'shipping' do
137
200
  xml.tag! 'code', shipping_address[:zip]
138
201
  xml.tag! 'country', shipping_address[:country]
139
202
  end
140
-
141
- xml.tag! 'custnum', options[:customer]
142
-
143
- xml.tag! 'prodid', options[:invoice]
144
- xml.tag! 'varref'
145
203
  end
146
204
  end
205
+ end
147
206
 
148
- xml.target!
207
+ def add_merchant_details(xml, options)
208
+ xml.tag! 'merchantid', @options[:login]
209
+ if options[:account] || @options[:account]
210
+ xml.tag! 'account', options[:account] || @options[:account]
211
+ end
212
+ end
213
+
214
+ def add_transaction_identifiers(xml, authorization, options)
215
+ options[:order_id], pasref, authcode = authorization.split(';')
216
+ xml.tag! 'orderid', sanitize_order_id(options[:order_id])
217
+ xml.tag! 'pasref', pasref
218
+ xml.tag! 'authcode', authcode
219
+ end
220
+
221
+ def add_comments(xml, options)
222
+ return unless options[:description]
223
+ xml.tag! 'comments' do
224
+ xml.tag! 'comment', options[:description], 'id' => 1
225
+ end
226
+ end
227
+
228
+ def add_amount(xml, money, options)
229
+ xml.tag! 'amount', amount(money), 'currency' => options[:currency] || currency(money)
230
+ end
231
+
232
+ def add_card(xml, credit_card)
233
+ xml.tag! 'card' do
234
+ xml.tag! 'number', credit_card.number
235
+ xml.tag! 'expdate', expiry_date(credit_card)
236
+ xml.tag! 'chname', credit_card.name
237
+ xml.tag! 'type', CARD_MAPPING[card_brand(credit_card).to_s]
238
+ xml.tag! 'issueno', credit_card.issue_number
239
+ xml.tag! 'cvn' do
240
+ xml.tag! 'number', credit_card.verification_value
241
+ xml.tag! 'presind', (options['presind'] || (credit_card.verification_value? ? 1 : nil))
242
+ end
243
+ end
244
+ end
245
+
246
+ def avs_input_code(address)
247
+ address.values_at(:zip, :address1).map{ |v| extract_digits(v) }.join('|')
248
+ end
249
+
250
+ def extract_digits(string)
251
+ return "" if string.nil?
252
+ string.gsub(/[\D]/,'')
253
+ end
254
+
255
+ def stringify_values(values)
256
+ string = ""
257
+ (0..5).each do |i|
258
+ string << "#{values[i]}"
259
+ string << "." unless i == 5
260
+ end
261
+ string
149
262
  end
150
263
 
264
+ def new_timestamp
265
+ Time.now.strftime('%Y%m%d%H%M%S')
266
+ end
267
+
268
+ def add_signed_digest(xml, *values)
269
+ string = stringify_values(values)
270
+ xml.tag! 'sha1hash', sha1from(string)
271
+ end
272
+
151
273
  def auto_settle_flag(action)
152
274
  action == :authorization ? '0' : '1'
153
275
  end
154
-
276
+
155
277
  def expiry_date(credit_card)
156
278
  "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
157
279
  end
158
-
280
+
159
281
  def sha1from(string)
160
282
  Digest::SHA1.hexdigest("#{Digest::SHA1.hexdigest(string)}.#{@options[:password]}")
161
283
  end
162
-
284
+
163
285
  def normalize(field)
164
286
  case field
165
287
  when "true" then true
@@ -167,12 +289,12 @@ module ActiveMerchant
167
289
  when "" then nil
168
290
  when "null" then nil
169
291
  else field
170
- end
292
+ end
171
293
  end
172
-
294
+
173
295
  def message_from(response)
174
296
  message = nil
175
- case response[:result]
297
+ case response[:result]
176
298
  when "00"
177
299
  message = SUCCESS
178
300
  when "101"
@@ -184,14 +306,16 @@ module ActiveMerchant
184
306
  when /^3[0-9][0-9]/
185
307
  message = REALEX_ERROR
186
308
  when /^5[0-9][0-9]/
309
+ message = response[:message]
310
+ when "600", "601", "603"
187
311
  message = ERROR
188
312
  when "666"
189
313
  message = CLIENT_DEACTIVATED
190
314
  else
191
315
  message = DECLINED
192
- end
316
+ end
193
317
  end
194
-
318
+
195
319
  def sanitize_order_id(order_id)
196
320
  order_id.to_s.gsub(/[^a-zA-Z0-9\-_]/, '')
197
321
  end