activemerchant 1.28.0 → 1.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data.tar.gz.sig +3 -3
  2. data/CHANGELOG +36 -0
  3. data/CONTRIBUTORS +8 -0
  4. data/README.md +5 -0
  5. data/lib/active_merchant/billing/gateway.rb +2 -1
  6. data/lib/active_merchant/billing/gateways.rb +6 -7
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +3 -2
  8. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +77 -78
  9. data/lib/active_merchant/billing/gateways/balanced.rb +0 -1
  10. data/lib/active_merchant/billing/gateways/banwire.rb +1 -2
  11. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +19 -20
  12. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +35 -36
  13. data/lib/active_merchant/billing/gateways/blue_pay.rb +135 -140
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +12 -4
  15. data/lib/active_merchant/billing/gateways/card_stream.rb +54 -59
  16. data/lib/active_merchant/billing/gateways/certo_direct.rb +0 -1
  17. data/lib/active_merchant/billing/gateways/cyber_source.rb +19 -14
  18. data/lib/active_merchant/billing/gateways/data_cash.rb +106 -112
  19. data/lib/active_merchant/billing/gateways/efsnet.rb +29 -34
  20. data/lib/active_merchant/billing/gateways/elavon.rb +7 -1
  21. data/lib/active_merchant/billing/gateways/epay.rb +0 -1
  22. data/lib/active_merchant/billing/gateways/eway.rb +88 -93
  23. data/lib/active_merchant/billing/gateways/eway_managed.rb +47 -51
  24. data/lib/active_merchant/billing/gateways/exact.rb +45 -54
  25. data/lib/active_merchant/billing/gateways/federated_canada.rb +3 -4
  26. data/lib/active_merchant/billing/gateways/first_pay.rb +37 -38
  27. data/lib/active_merchant/billing/gateways/garanti.rb +1 -2
  28. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  29. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +5 -8
  30. data/lib/active_merchant/billing/gateways/inspire.rb +52 -52
  31. data/lib/active_merchant/billing/gateways/instapay.rb +10 -11
  32. data/lib/active_merchant/billing/gateways/iridium.rb +38 -39
  33. data/lib/active_merchant/billing/gateways/itransact.rb +7 -9
  34. data/lib/active_merchant/billing/gateways/jetpay.rb +45 -46
  35. data/lib/active_merchant/billing/gateways/linkpoint.rb +104 -108
  36. data/lib/active_merchant/billing/gateways/litle.rb +1 -5
  37. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +153 -155
  38. data/lib/active_merchant/billing/gateways/merchant_ware.rb +49 -50
  39. data/lib/active_merchant/billing/gateways/mercury.rb +272 -0
  40. data/lib/active_merchant/billing/gateways/metrics_global.rb +9 -10
  41. data/lib/active_merchant/billing/gateways/migs.rb +5 -3
  42. data/lib/active_merchant/billing/gateways/modern_payments.rb +6 -7
  43. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +40 -41
  44. data/lib/active_merchant/billing/gateways/moneris.rb +46 -50
  45. data/lib/active_merchant/billing/gateways/moneris_us.rb +52 -55
  46. data/lib/active_merchant/billing/gateways/nab_transact.rb +0 -5
  47. data/lib/active_merchant/billing/gateways/net_registry.rb +20 -21
  48. data/lib/active_merchant/billing/gateways/netaxept.rb +30 -36
  49. data/lib/active_merchant/billing/gateways/netbilling.rb +2 -2
  50. data/lib/active_merchant/billing/gateways/ogone.rb +0 -5
  51. data/lib/active_merchant/billing/gateways/optimal_payment.rb +1 -6
  52. data/lib/active_merchant/billing/gateways/orbital.rb +25 -21
  53. data/lib/active_merchant/billing/gateways/orbital/avs_result.rb +93 -0
  54. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +1 -6
  55. data/lib/active_merchant/billing/gateways/pay_junction.rb +62 -63
  56. data/lib/active_merchant/billing/gateways/pay_secure.rb +29 -30
  57. data/lib/active_merchant/billing/gateways/paybox_direct.rb +0 -5
  58. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +33 -38
  59. data/lib/active_merchant/billing/gateways/payment_express.rb +48 -51
  60. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +7 -11
  61. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +7 -0
  62. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +3 -0
  63. data/lib/active_merchant/billing/gateways/paystation.rb +62 -64
  64. data/lib/active_merchant/billing/gateways/payway.rb +2 -9
  65. data/lib/active_merchant/billing/gateways/plugnpay.rb +0 -1
  66. data/lib/active_merchant/billing/gateways/psigate.rb +102 -94
  67. data/lib/active_merchant/billing/gateways/psl_card.rb +66 -67
  68. data/lib/active_merchant/billing/gateways/qbms.rb +0 -6
  69. data/lib/active_merchant/billing/gateways/quantum.rb +2 -8
  70. data/lib/active_merchant/billing/gateways/quickpay.rb +2 -3
  71. data/lib/active_merchant/billing/gateways/realex.rb +6 -16
  72. data/lib/active_merchant/billing/gateways/redsys.rb +394 -0
  73. data/lib/active_merchant/billing/gateways/sage.rb +15 -16
  74. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +25 -26
  75. data/lib/active_merchant/billing/gateways/sage_pay.rb +51 -56
  76. data/lib/active_merchant/billing/gateways/sallie_mae.rb +1 -2
  77. data/lib/active_merchant/billing/gateways/samurai.rb +1 -4
  78. data/lib/active_merchant/billing/gateways/secure_net.rb +0 -1
  79. data/lib/active_merchant/billing/gateways/secure_pay.rb +5 -8
  80. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +0 -5
  81. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +17 -18
  82. data/lib/active_merchant/billing/gateways/skip_jack.rb +29 -34
  83. data/lib/active_merchant/billing/gateways/smart_ps.rb +55 -56
  84. data/lib/active_merchant/billing/gateways/stripe.rb +8 -3
  85. data/lib/active_merchant/billing/gateways/trans_first.rb +28 -29
  86. data/lib/active_merchant/billing/gateways/trust_commerce.rb +85 -87
  87. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +27 -28
  88. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +0 -5
  89. data/lib/active_merchant/billing/gateways/verifi.rb +86 -87
  90. data/lib/active_merchant/billing/gateways/viaklix.rb +42 -47
  91. data/lib/active_merchant/billing/gateways/vindicia.rb +30 -28
  92. data/lib/active_merchant/billing/gateways/webpay.rb +45 -0
  93. data/lib/active_merchant/billing/gateways/wirecard.rb +0 -6
  94. data/lib/active_merchant/billing/gateways/worldpay.rb +4 -9
  95. data/lib/active_merchant/billing/integrations/a1agregator.rb +26 -0
  96. data/lib/active_merchant/billing/integrations/a1agregator/helper.rb +31 -0
  97. data/lib/active_merchant/billing/integrations/a1agregator/notification.rb +186 -0
  98. data/lib/active_merchant/billing/integrations/a1agregator/status.rb +38 -0
  99. data/lib/active_merchant/billing/integrations/liqpay.rb +30 -0
  100. data/lib/active_merchant/billing/integrations/liqpay/helper.rb +43 -0
  101. data/lib/active_merchant/billing/integrations/liqpay/notification.rb +89 -0
  102. data/lib/active_merchant/billing/integrations/liqpay/return.rb +83 -0
  103. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +17 -1
  104. data/lib/active_merchant/billing/integrations/notification.rb +4 -0
  105. data/lib/active_merchant/billing/integrations/pay_fast.rb +70 -0
  106. data/lib/active_merchant/billing/integrations/pay_fast/common.rb +42 -0
  107. data/lib/active_merchant/billing/integrations/pay_fast/helper.rb +50 -0
  108. data/lib/active_merchant/billing/integrations/pay_fast/notification.rb +134 -0
  109. data/lib/active_merchant/billing/integrations/pay_fast/return.rb +10 -0
  110. data/lib/active_merchant/billing/integrations/paypal/notification.rb +64 -0
  111. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +10 -7
  112. data/lib/active_merchant/billing/integrations/webmoney/notification.rb +12 -0
  113. data/lib/active_merchant/billing/response.rb +19 -4
  114. data/lib/active_merchant/version.rb +1 -1
  115. metadata +45 -27
  116. metadata.gz.sig +0 -0
@@ -22,7 +22,6 @@ module ActiveMerchant #:nodoc:
22
22
 
23
23
  def initialize(options = {})
24
24
  requires!(options, :login, :password)
25
- @options = options
26
25
  super
27
26
  end
28
27
 
@@ -101,7 +100,7 @@ module ActiveMerchant #:nodoc:
101
100
  post[:orderid] = options[:order_id]
102
101
  post[:orderdescription] = options[:description]
103
102
  end
104
-
103
+
105
104
  def add_creditcard(post, creditcard)
106
105
  post[:ccnumber] = creditcard.number
107
106
  post[:ccexp] = expdate(creditcard)
@@ -121,7 +120,7 @@ module ActiveMerchant #:nodoc:
121
120
  memo
122
121
  end
123
122
  end
124
-
123
+
125
124
  def commit(action, money, parameters)
126
125
  parameters[:amount] = amount(money)
127
126
  data = ssl_post(self.live_url, post_data(action, parameters))
@@ -129,7 +128,7 @@ module ActiveMerchant #:nodoc:
129
128
  message = message_from(response)
130
129
  test_mode = test?
131
130
 
132
- Response.new(success?(response), message, response,
131
+ Response.new(success?(response), message, response,
133
132
  :test => test?,
134
133
  :authorization => response['transactionid'],
135
134
  :avs_result => {:code => response['avsresponse']},
@@ -1,52 +1,51 @@
1
1
  module ActiveMerchant #:nodoc:
2
- module Billing #:nodoc:
2
+ module Billing #:nodoc:
3
3
  class FirstPayGateway < Gateway
4
4
  class FirstPayPostData < PostData
5
5
  # Fields that will be sent even if they are blank
6
- self.required_fields = [ :action, :amount, :trackid ]
6
+ self.required_fields = [ :action, :amount, :trackid ]
7
7
  end
8
8
 
9
9
  # both URLs are IP restricted
10
10
  self.test_url = 'https://apgcert.first-pay.com/AcqENGIN/SecureCapture'
11
11
  self.live_url = 'https://acqengin.first-pay.com/AcqENGIN/SecureCapture'
12
-
12
+
13
13
  # The countries the gateway supports merchants from as 2 digit ISO country codes
14
14
  self.supported_countries = ['US']
15
-
15
+
16
16
  # The card types supported by the payment gateway
17
17
  self.supported_cardtypes = [:visa, :master]
18
-
18
+
19
19
  # The homepage URL of the gateway
20
20
  self.homepage_url = 'http://www.first-pay.com'
21
-
21
+
22
22
  # The name of the gateway
23
23
  self.display_name = 'First Pay'
24
-
24
+
25
25
  # all transactions are in cents
26
26
  self.money_format = :cents
27
-
27
+
28
28
  ACTIONS = {
29
29
  'sale' => 1,
30
30
  'credit' => 2,
31
31
  'void' => 3
32
32
  }
33
-
33
+
34
34
  def initialize(options = {})
35
35
  requires!(options, :login, :password)
36
- @options = options
37
36
  super
38
- end
39
-
37
+ end
38
+
40
39
  def purchase(money, creditcard, options = {})
41
40
  post = FirstPayPostData.new
42
41
  add_invoice(post, options)
43
42
  add_creditcard(post, creditcard)
44
43
  add_address(post, options)
45
44
  add_customer_data(post, options)
46
-
45
+
47
46
  commit('sale', money, post)
48
- end
49
-
47
+ end
48
+
50
49
  def refund(money, reference, options = {})
51
50
  requires!(options, :credit_card)
52
51
 
@@ -56,7 +55,7 @@ module ActiveMerchant #:nodoc:
56
55
  add_address(post, options)
57
56
  add_customer_data(post, options)
58
57
  add_credit_data(post, reference)
59
-
58
+
60
59
  commit('credit', money, post)
61
60
  end
62
61
 
@@ -64,73 +63,73 @@ module ActiveMerchant #:nodoc:
64
63
  deprecated CREDIT_DEPRECATION_MESSAGE
65
64
  refund(money, reference, options)
66
65
  end
67
-
66
+
68
67
  def void(money, creditcard, options = {})
69
68
  post = FirstPayPostData.new
70
69
  add_creditcard(post, creditcard)
71
70
  add_void_data(post, options)
72
71
  add_invoice(post, options)
73
72
  add_customer_data(post, options)
74
-
73
+
75
74
  commit('void', money, post)
76
75
  end
77
-
78
-
76
+
77
+
79
78
  private
80
-
79
+
81
80
  def add_customer_data(post, options)
82
81
  post[:cardip] = options[:ip]
83
82
  post[:email] = options[:email]
84
83
  end
85
-
84
+
86
85
  def add_address(post, options)
87
86
  if billing_address = options[:billing_address] || options[:address]
88
87
  post[:addr] = billing_address[:address1].to_s + ' ' + billing_address[:address2].to_s
89
88
  post[:city] = billing_address[:city]
90
89
  post[:state] = billing_address[:state]
91
- post[:zip] = billing_address[:zip]
90
+ post[:zip] = billing_address[:zip]
92
91
  post[:country] = billing_address[:country]
93
92
  end
94
93
  end
95
-
94
+
96
95
  def add_invoice(post, options)
97
96
  post[:trackid] = rand(Time.now.to_i)
98
97
  end
99
-
98
+
100
99
  def add_creditcard(post, creditcard)
101
100
  post[:member] = creditcard.first_name.to_s + " " + creditcard.last_name.to_s
102
101
  post[:card] = creditcard.number
103
102
  post[:exp] = expdate(creditcard)
104
103
  end
105
-
104
+
106
105
  def expdate(credit_card)
107
106
  year = sprintf("%.4i", credit_card.year)
108
107
  month = sprintf("%.2i", credit_card.month)
109
108
 
110
109
  "#{month}#{year[-2..-1]}"
111
110
  end
112
-
111
+
113
112
  def add_credit_data(post, transaction_id)
114
113
  post[:transid] = transaction_id
115
114
  end
116
-
115
+
117
116
  def add_void_data(post, options)
118
117
  post[:transid] = options[:transactionid]
119
118
  end
120
-
119
+
121
120
  def commit(action, money, post)
122
121
  response = parse( ssl_post(test? ? self.test_url : self.live_url, post_data(action, post, money)) )
123
-
122
+
124
123
  Response.new(response[:response] == 'CAPTURED', response[:message], response,
125
124
  :test => test?,
126
125
  :authorization => response[:authorization],
127
126
  :avs_result => { :code => response[:avsresponse] },
128
127
  :cvv_result => response[:cvvresponse])
129
128
  end
130
-
129
+
131
130
  def parse(body)
132
131
  response = {}
133
-
132
+
134
133
  # check for an error first
135
134
  if body.include?('!ERROR!')
136
135
  response[:response] = 'ERROR'
@@ -139,7 +138,7 @@ module ActiveMerchant #:nodoc:
139
138
  # a capture / not captured response will be : delimited
140
139
  split = body.split(':')
141
140
  response[:response] = split[0]
142
-
141
+
143
142
  # FirstPay docs are worthless. turns out the transactionid is required for credits
144
143
  # so we need to store that in authorization, not the actual auth.
145
144
  if response[:response] == 'CAPTURED'
@@ -154,21 +153,21 @@ module ActiveMerchant #:nodoc:
154
153
  response[:transactionid] = split[9]
155
154
  end
156
155
  end
157
-
156
+
158
157
  return response
159
158
  end
160
-
159
+
161
160
  def error_message_from(response)
162
161
  # error messages use this format - '!ERROR! 704-MISSING BASIC DATA TYPE:card, exp, zip, addr, member, amount\n'
163
162
  response.split("! ")[1].chomp
164
163
  end
165
-
164
+
166
165
  def post_data(action, post, money)
167
- post[:vid] = @options[:login]
166
+ post[:vid] = @options[:login]
168
167
  post[:password] = @options[:password]
169
168
  post[:action] = ACTIONS[action]
170
169
  post[:amount] = amount(money)
171
-
170
+
172
171
  return post.to_post_data
173
172
  end
174
173
  end
@@ -36,7 +36,6 @@ module ActiveMerchant #:nodoc:
36
36
 
37
37
  def initialize(options = {})
38
38
  requires!(options, :login, :password, :terminal_id, :merchant_id)
39
- @options = options
40
39
  super
41
40
  end
42
41
 
@@ -198,7 +197,7 @@ module ActiveMerchant #:nodoc:
198
197
 
199
198
  def normalize(text)
200
199
  return unless text
201
-
200
+
202
201
  if ActiveSupport::Inflector.method(:transliterate).arity == -2
203
202
  ActiveSupport::Inflector.transliterate(text,'')
204
203
  elsif RUBY_VERSION >= '1.9'
@@ -0,0 +1,207 @@
1
+ require "nokogiri"
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class HdfcGateway < Gateway
6
+ self.display_name = "HDFC"
7
+ self.homepage_url = "http://www.hdfcbank.com/sme/sme-details/merchant-services/guzh6m0i"
8
+
9
+ self.test_url = "https://securepgtest.fssnet.co.in/pgway/servlet/"
10
+ self.live_url = "https://securepg.fssnet.co.in/pgway/servlet/"
11
+
12
+ self.supported_countries = ["IN"]
13
+ self.default_currency = "INR"
14
+ self.money_format = :dollars
15
+ self.supported_cardtypes = [:visa, :master, :discover, :diners_club]
16
+
17
+ def initialize(options={})
18
+ requires!(options, :login, :password)
19
+ super
20
+ end
21
+
22
+ def purchase(amount, payment_method, options={})
23
+ post = {}
24
+ add_invoice(post, amount, options)
25
+ add_payment_method(post, payment_method)
26
+ add_customer_data(post, options)
27
+
28
+ commit("purchase", post)
29
+ end
30
+
31
+ def authorize(amount, payment_method, options={})
32
+ post = {}
33
+ add_invoice(post, amount, options)
34
+ add_payment_method(post, payment_method)
35
+ add_customer_data(post, options)
36
+
37
+ commit("authorize", post)
38
+ end
39
+
40
+ def capture(amount, authorization, options={})
41
+ post = {}
42
+ add_invoice(post, amount, options)
43
+ add_reference(post, authorization)
44
+ add_customer_data(post, options)
45
+
46
+ commit("capture", post)
47
+ end
48
+
49
+ def refund(amount, authorization, options={})
50
+ post = {}
51
+ add_invoice(post, amount, options)
52
+ add_reference(post, authorization)
53
+ add_customer_data(post, options)
54
+
55
+ commit("refund", post)
56
+ end
57
+
58
+ private
59
+
60
+ CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")}
61
+ CURRENCY_CODES["AED"] = "784"
62
+ CURRENCY_CODES["AUD"] = "036"
63
+ CURRENCY_CODES["CAD"] = "124"
64
+ CURRENCY_CODES["EUR"] = "978"
65
+ CURRENCY_CODES["GBP"] = "826"
66
+ CURRENCY_CODES["INR"] = "356"
67
+ CURRENCY_CODES["OMR"] = "512"
68
+ CURRENCY_CODES["QAR"] = "634"
69
+ CURRENCY_CODES["SGD"] = "702"
70
+ CURRENCY_CODES["USD"] = "840"
71
+
72
+ def add_invoice(post, amount, options)
73
+ post[:amt] = amount(amount)
74
+ post[:currencycode] = CURRENCY_CODES[options[:currency] || currency(amount)]
75
+ post[:trackid] = escape(options[:order_id], 40) if options[:order_id]
76
+ post[:udf1] = escape(options[:description]) if options[:description]
77
+ post[:eci] = options[:eci] if options[:eci]
78
+ end
79
+
80
+ def add_customer_data(post, options)
81
+ post[:udf2] = escape(options[:email]) if options[:email]
82
+ if address = (options[:billing_address] || options[:address])
83
+ post[:udf3] = escape(address[:phone]) if address[:phone]
84
+ post[:udf4] = escape(<<EOA)
85
+ #{address[:name]}
86
+ #{address[:company]}
87
+ #{address[:address1]}
88
+ #{address[:address2]}
89
+ #{address[:city]} #{address[:state]} #{address[:zip]}
90
+ #{address[:country]}
91
+ EOA
92
+ end
93
+ end
94
+
95
+ def add_payment_method(post, payment_method)
96
+ post[:member] = escape(payment_method.name, 30)
97
+ post[:card] = escape(payment_method.number)
98
+ post[:cvv2] = escape(payment_method.verification_value)
99
+ post[:expyear] = format(payment_method.year, :four_digits)
100
+ post[:expmonth] = format(payment_method.month, :two_digits)
101
+ end
102
+
103
+ def add_reference(post, authorization)
104
+ tranid, member = split_authorization(authorization)
105
+ post[:transid] = tranid
106
+ post[:member] = member
107
+ end
108
+
109
+ def parse(xml)
110
+ response = {}
111
+
112
+ doc = Nokogiri::XML.fragment(fix_xml(xml))
113
+ doc.children.each do |node|
114
+ if node.text?
115
+ next
116
+ elsif (node.elements.size == 0)
117
+ response[node.name.downcase.to_sym] = node.text
118
+ else
119
+ node.elements.each do |childnode|
120
+ name = "#{node.name.downcase}_#{childnode.name.downcase}"
121
+ response[name.to_sym] = childnode.text
122
+ end
123
+ end
124
+ end
125
+
126
+ response
127
+ end
128
+
129
+ def fix_xml(xml)
130
+ xml.gsub(/&(?!(?:amp|quot|apos|lt|gt);)/, "&amp;")
131
+ end
132
+
133
+ ACTIONS = {
134
+ "purchase" => "1",
135
+ "refund" => "2",
136
+ "authorize" => "4",
137
+ "capture" => "5",
138
+ }
139
+
140
+ def commit(action, post)
141
+ post[:id] = @options[:login]
142
+ post[:password] = @options[:password]
143
+ post[:action] = ACTIONS[action] if ACTIONS[action]
144
+
145
+ raw = parse(ssl_post(url(action), build_request(post)))
146
+
147
+ succeeded = success_from(raw[:result])
148
+ Response.new(
149
+ succeeded,
150
+ message_from(succeeded, raw),
151
+ raw,
152
+ :authorization => authorization_from(post, raw),
153
+ :test => test?
154
+ )
155
+ end
156
+
157
+ def build_request(post)
158
+ xml = Builder::XmlMarkup.new :indent => 2
159
+ xml.instruct!
160
+ post.each do |field, value|
161
+ xml.tag!(field, value)
162
+ end
163
+ xml.target!
164
+ end
165
+
166
+ def url(action)
167
+ endpoint = "TranPortalXMLServlet"
168
+ (test? ? test_url : live_url) + endpoint
169
+ end
170
+
171
+ def success_from(result)
172
+ case result
173
+ when "CAPTURED", "APPROVED", "NOT ENROLLED", "ENROLLED"
174
+ true
175
+ else
176
+ false
177
+ end
178
+ end
179
+
180
+ def message_from(succeeded, response)
181
+ if succeeded
182
+ "Succeeded"
183
+ else
184
+ (response[:error_text] || response[:result] || "Unable to read error message").split("-").last
185
+ end
186
+ end
187
+
188
+ def authorization_from(request, response)
189
+ [response[:tranid], request[:member]].join("|")
190
+ end
191
+
192
+ def split_authorization(authorization)
193
+ tranid, member = authorization.split("|")
194
+ [tranid, member]
195
+ end
196
+
197
+ def escape(string, max_length=250)
198
+ return "" unless string
199
+ if max_length
200
+ string = string[0...max_length]
201
+ end
202
+ string.gsub(/[^A-Za-z0-9 \-_@\.\n]/, '')
203
+ end
204
+ end
205
+ end
206
+ end
207
+