activemerchant 1.13.0 → 1.14.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 (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