activemerchant 1.25.0 → 1.26.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.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +11 -0
- data/CONTRIBUTORS +8 -0
- data/README.md +9 -7
- data/lib/active_merchant/billing/gateways/cyber_source.rb +102 -84
- data/lib/active_merchant/billing/gateways/netbilling.rb +76 -48
- data/lib/active_merchant/billing/gateways/orbital.rb +12 -17
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +266 -0
- data/lib/active_merchant/billing/gateways/payway.rb +213 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +17 -45
- data/lib/active_merchant/billing/response.rb +38 -6
- data/lib/active_merchant/version.rb +1 -1
- metadata +28 -26
- metadata.gz.sig +0 -0
@@ -2,15 +2,16 @@ module ActiveMerchant #:nodoc:
|
|
2
2
|
module Billing #:nodoc:
|
3
3
|
class NetbillingGateway < Gateway
|
4
4
|
URL = 'https://secure.netbilling.com:1402/gw/sas/direct3.1'
|
5
|
-
|
5
|
+
|
6
6
|
TRANSACTIONS = {
|
7
|
-
:authorization
|
8
|
-
:purchase
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:capture
|
7
|
+
:authorization => 'A',
|
8
|
+
:purchase => 'S',
|
9
|
+
:refund => 'R',
|
10
|
+
:credit => 'C',
|
11
|
+
:capture => 'D',
|
12
|
+
:void => 'U'
|
12
13
|
}
|
13
|
-
|
14
|
+
|
14
15
|
SUCCESS_CODES = [ '1', 'T' ]
|
15
16
|
SUCCESS_MESSAGE = 'The transaction was approved'
|
16
17
|
FAILURE_MESSAGE = 'The transaction failed'
|
@@ -20,54 +21,78 @@ module ActiveMerchant #:nodoc:
|
|
20
21
|
self.homepage_url = 'http://www.netbilling.com'
|
21
22
|
self.supported_countries = ['US']
|
22
23
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
|
23
|
-
|
24
|
+
|
24
25
|
def initialize(options = {})
|
25
26
|
requires!(options, :login)
|
26
27
|
@options = options
|
27
28
|
super
|
28
|
-
end
|
29
|
-
|
29
|
+
end
|
30
|
+
|
30
31
|
def authorize(money, credit_card, options = {})
|
31
32
|
post = {}
|
32
33
|
add_amount(post, money)
|
33
34
|
add_invoice(post, options)
|
34
|
-
add_credit_card(post, credit_card)
|
35
|
-
add_address(post, credit_card, options)
|
35
|
+
add_credit_card(post, credit_card)
|
36
|
+
add_address(post, credit_card, options)
|
36
37
|
add_customer_data(post, options)
|
37
|
-
|
38
|
-
commit(:authorization,
|
38
|
+
|
39
|
+
commit(:authorization, post)
|
39
40
|
end
|
40
|
-
|
41
|
+
|
41
42
|
def purchase(money, credit_card, options = {})
|
42
43
|
post = {}
|
43
44
|
add_amount(post, money)
|
44
45
|
add_invoice(post, options)
|
45
|
-
add_credit_card(post, credit_card)
|
46
|
-
add_address(post, credit_card, options)
|
46
|
+
add_credit_card(post, credit_card)
|
47
|
+
add_address(post, credit_card, options)
|
47
48
|
add_customer_data(post, options)
|
48
|
-
|
49
|
-
commit(:purchase,
|
50
|
-
end
|
51
|
-
|
49
|
+
|
50
|
+
commit(:purchase, post)
|
51
|
+
end
|
52
|
+
|
52
53
|
def capture(money, authorization, options = {})
|
53
54
|
post = {}
|
54
55
|
add_reference(post, authorization)
|
55
|
-
commit(:capture,
|
56
|
+
commit(:capture, post)
|
57
|
+
end
|
58
|
+
|
59
|
+
def refund(money, source, options = {})
|
60
|
+
post = {}
|
61
|
+
add_amount(post, money)
|
62
|
+
add_reference(post, source)
|
63
|
+
commit(:refund, post)
|
56
64
|
end
|
57
|
-
|
65
|
+
|
66
|
+
def credit(money, credit_card, options = {})
|
67
|
+
post = {}
|
68
|
+
add_amount(post, money)
|
69
|
+
add_invoice(post, options)
|
70
|
+
add_credit_card(post, credit_card)
|
71
|
+
add_address(post, credit_card, options)
|
72
|
+
add_customer_data(post, options)
|
73
|
+
|
74
|
+
commit(:credit, post)
|
75
|
+
end
|
76
|
+
|
77
|
+
def void(source, options = {})
|
78
|
+
post = {}
|
79
|
+
add_reference(post, source)
|
80
|
+
commit(:void, post)
|
81
|
+
end
|
82
|
+
|
58
83
|
def test?
|
59
84
|
@options[:login] == TEST_LOGIN || super
|
60
85
|
end
|
61
|
-
|
62
|
-
private
|
86
|
+
|
87
|
+
private
|
63
88
|
def add_amount(post, money)
|
64
89
|
post[:amount] = amount(money)
|
65
90
|
end
|
66
|
-
|
91
|
+
|
67
92
|
def add_reference(post, reference)
|
68
93
|
post[:orig_id] = reference
|
69
94
|
end
|
70
|
-
|
95
|
+
|
71
96
|
def add_customer_data(post, options)
|
72
97
|
post[:cust_email] = options[:email]
|
73
98
|
post[:cust_ip] = options[:ip]
|
@@ -82,10 +107,10 @@ module ActiveMerchant #:nodoc:
|
|
82
107
|
post[:bill_country] = billing_address[:country]
|
83
108
|
post[:bill_state] = billing_address[:state]
|
84
109
|
end
|
85
|
-
|
110
|
+
|
86
111
|
if shipping_address = options[:shipping_address]
|
87
112
|
first_name, last_name = parse_first_and_last_name(shipping_address[:name])
|
88
|
-
|
113
|
+
|
89
114
|
post[:ship_name1] = first_name
|
90
115
|
post[:ship_name2] = last_name
|
91
116
|
post[:ship_street] = shipping_address[:address1]
|
@@ -95,11 +120,11 @@ module ActiveMerchant #:nodoc:
|
|
95
120
|
post[:ship_state] = shipping_address[:state]
|
96
121
|
end
|
97
122
|
end
|
98
|
-
|
123
|
+
|
99
124
|
def add_invoice(post, options)
|
100
125
|
post[:description] = options[:description]
|
101
126
|
end
|
102
|
-
|
127
|
+
|
103
128
|
def add_credit_card(post, credit_card)
|
104
129
|
post[:bill_name1] = credit_card.first_name
|
105
130
|
post[:bill_name2] = credit_card.last_name
|
@@ -107,31 +132,34 @@ module ActiveMerchant #:nodoc:
|
|
107
132
|
post[:card_expire] = expdate(credit_card)
|
108
133
|
post[:card_cvv2] = credit_card.verification_value
|
109
134
|
end
|
110
|
-
|
135
|
+
|
111
136
|
def parse(body)
|
112
137
|
results = {}
|
113
138
|
body.split(/&/).each do |pair|
|
114
|
-
key,val = pair.split(
|
139
|
+
key,val = pair.split(/\=/)
|
115
140
|
results[key.to_sym] = CGI.unescape(val)
|
116
141
|
end
|
117
142
|
results
|
118
|
-
end
|
119
|
-
|
120
|
-
def commit(action,
|
143
|
+
end
|
144
|
+
|
145
|
+
def commit(action, parameters)
|
121
146
|
response = parse(ssl_post(URL, post_data(action, parameters)))
|
122
|
-
|
123
|
-
Response.new(success?(response), message_from(response), response,
|
124
|
-
:test => test_response?(response),
|
147
|
+
|
148
|
+
Response.new(success?(response), message_from(response), response,
|
149
|
+
:test => test_response?(response),
|
125
150
|
:authorization => response[:trans_id],
|
126
151
|
:avs_result => { :code => response[:avs_code]},
|
127
152
|
:cvv_result => response[:cvv2_code]
|
128
153
|
)
|
154
|
+
rescue ActiveMerchant::ResponseError => e
|
155
|
+
raise unless(e.response.code =~ /^[67]\d\d$/)
|
156
|
+
return Response.new(false, e.response.message, {:status_code => e.response.code}, :test => test?)
|
129
157
|
end
|
130
|
-
|
158
|
+
|
131
159
|
def test_response?(response)
|
132
160
|
!!(test? || response[:auth_msg] =~ /TEST/)
|
133
161
|
end
|
134
|
-
|
162
|
+
|
135
163
|
def success?(response)
|
136
164
|
SUCCESS_CODES.include?(response[:status_code])
|
137
165
|
end
|
@@ -139,28 +167,28 @@ module ActiveMerchant #:nodoc:
|
|
139
167
|
def message_from(response)
|
140
168
|
success?(response) ? SUCCESS_MESSAGE : (response[:auth_msg] || FAILURE_MESSAGE)
|
141
169
|
end
|
142
|
-
|
170
|
+
|
143
171
|
def expdate(credit_card)
|
144
172
|
year = sprintf("%.4i", credit_card.year)
|
145
173
|
month = sprintf("%.2i", credit_card.month)
|
146
174
|
|
147
175
|
"#{month}#{year[-2..-1]}"
|
148
176
|
end
|
149
|
-
|
177
|
+
|
150
178
|
def post_data(action, parameters = {})
|
151
179
|
parameters[:account_id] = @options[:login]
|
152
180
|
parameters[:pay_type] = 'C'
|
153
|
-
parameters[:tran_type] = TRANSACTIONS[action]
|
154
|
-
|
181
|
+
parameters[:tran_type] = TRANSACTIONS[action]
|
182
|
+
|
155
183
|
parameters.reject{|k,v| v.blank?}.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
156
184
|
end
|
157
|
-
|
185
|
+
|
158
186
|
def parse_first_and_last_name(value)
|
159
187
|
name = value.to_s.split(' ')
|
160
|
-
|
188
|
+
|
161
189
|
last_name = name.pop || ''
|
162
190
|
first_name = name.join(' ')
|
163
|
-
[ first_name, last_name ]
|
191
|
+
[ first_name, last_name ]
|
164
192
|
end
|
165
193
|
end
|
166
194
|
end
|
@@ -148,10 +148,20 @@ module ActiveMerchant #:nodoc:
|
|
148
148
|
xml.tag! :SDMerchantEmail, soft_desc.merchant_email
|
149
149
|
end
|
150
150
|
|
151
|
-
def add_address(xml, creditcard, options)
|
151
|
+
def add_address(xml, creditcard, options)
|
152
152
|
if address = options[:billing_address] || options[:address]
|
153
|
-
|
153
|
+
avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
|
154
|
+
|
155
|
+
if avs_supported
|
156
|
+
xml.tag! :AVSzip, address[:zip]
|
157
|
+
xml.tag! :AVSaddress1, address[:address1]
|
158
|
+
xml.tag! :AVSaddress2, address[:address2]
|
159
|
+
xml.tag! :AVScity, address[:city]
|
160
|
+
xml.tag! :AVSstate, address[:state]
|
161
|
+
xml.tag! :AVSphoneNum, address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil
|
162
|
+
end
|
154
163
|
xml.tag! :AVSname, creditcard.name
|
164
|
+
xml.tag! :AVScountryCode, avs_supported ? address[:country] : ''
|
155
165
|
end
|
156
166
|
end
|
157
167
|
|
@@ -173,21 +183,6 @@ module ActiveMerchant #:nodoc:
|
|
173
183
|
xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
|
174
184
|
end
|
175
185
|
|
176
|
-
def add_avs_details(xml, address)
|
177
|
-
if AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
|
178
|
-
xml.tag! :AVSzip, address[:zip]
|
179
|
-
xml.tag! :AVSaddress1, address[:address1]
|
180
|
-
xml.tag! :AVSaddress2, address[:address2]
|
181
|
-
xml.tag! :AVScity, address[:city]
|
182
|
-
xml.tag! :AVSstate, address[:state]
|
183
|
-
xml.tag! :AVSphoneNum, address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil
|
184
|
-
country_code = address[:country]
|
185
|
-
else
|
186
|
-
country_code = ''
|
187
|
-
end
|
188
|
-
xml.tag! :AVScountryCode, country_code
|
189
|
-
end
|
190
|
-
|
191
186
|
|
192
187
|
def parse(body)
|
193
188
|
response = {}
|
@@ -0,0 +1,266 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# This gateway accepts the following arguments:
|
6
|
+
# :login => your PayJunction username
|
7
|
+
# :password => your PayJunction pass
|
8
|
+
# Example use:
|
9
|
+
#
|
10
|
+
# gateway = ActiveMerchant::Billing::Base.gateway(:pay_gate_xml).new(
|
11
|
+
# :login => "my_account",
|
12
|
+
# :password => "my_pass"
|
13
|
+
# )
|
14
|
+
#
|
15
|
+
# # set up credit card obj as in main ActiveMerchant example
|
16
|
+
# creditcard = ActiveMerchant::Billing::CreditCard.new(
|
17
|
+
# :type => 'visa',
|
18
|
+
# :number => '4242424242424242',
|
19
|
+
# :month => 8,
|
20
|
+
# :year => 2009,
|
21
|
+
# :first_name => 'Bob',
|
22
|
+
# :last_name => 'Bobsen'
|
23
|
+
# )
|
24
|
+
#
|
25
|
+
# # run request
|
26
|
+
# response = gateway.purchase(1000, creditcard) # charge 10 dollars
|
27
|
+
#
|
28
|
+
# 1) Check whether the transaction was successful
|
29
|
+
#
|
30
|
+
# response.success?
|
31
|
+
#
|
32
|
+
# 2) Retrieve the message returned by PayJunction
|
33
|
+
#
|
34
|
+
# response.message
|
35
|
+
#
|
36
|
+
# 3) Retrieve the unique transaction ID returned by PayGateXML
|
37
|
+
#
|
38
|
+
# response.authorization
|
39
|
+
#
|
40
|
+
# This gateway has many other features which are not implemented here yet
|
41
|
+
# The basic setup here only supports auth/capture transactions.
|
42
|
+
#
|
43
|
+
# Test Transactions
|
44
|
+
#
|
45
|
+
# PayGateXML has a global test user/pass, but you can also sign up for your own.
|
46
|
+
# The class and the test come equipped with the global test creds
|
47
|
+
#
|
48
|
+
# Usage Details
|
49
|
+
#
|
50
|
+
# Below is a map of only SOME of the values accepted by PayGateXML and how you should submit
|
51
|
+
# each to ActiveMerchant
|
52
|
+
#
|
53
|
+
# PayGateXML Field ActiveMerchant Use
|
54
|
+
#
|
55
|
+
# pgid use :login value to gateway instantation
|
56
|
+
# pwd use :password value to gateway instantiation
|
57
|
+
#
|
58
|
+
# cname credit_card.name
|
59
|
+
# cc credit_card.number
|
60
|
+
# exp credit_card values formatted to YYYYMMDD
|
61
|
+
# budp South Africa only - set to 0 if purchase is not on budget
|
62
|
+
# amt include as argument to method for your transaction type
|
63
|
+
# ver do nothing, always set to current API version
|
64
|
+
#
|
65
|
+
# cref provide as :invoice in options, varchar(80)
|
66
|
+
# cur 3 char field, currently only ZAR
|
67
|
+
# cvv credit_card.verification
|
68
|
+
# bno batch processing number, i.e. you supply this
|
69
|
+
#
|
70
|
+
# others -- not used in this implementation
|
71
|
+
# nurl, rurl - must remain blank or absent or they will use an alternative authentication mechanism
|
72
|
+
# email, ip - must remain blank or absent or they will use a PayGate extra service call PayProtector
|
73
|
+
# threed - must remain blank unless you are using your own 3D Secure server
|
74
|
+
#
|
75
|
+
class PayGateXmlGateway < Gateway
|
76
|
+
LIVE_URL = 'https://www.paygate.co.za/payxml/process.trans'
|
77
|
+
|
78
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
79
|
+
self.supported_countries = ['US', 'ZA']
|
80
|
+
|
81
|
+
# The card types supported by the payment gateway
|
82
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
83
|
+
|
84
|
+
# The homepage URL of the gateway
|
85
|
+
self.homepage_url = 'http://paygate.co.za/'
|
86
|
+
|
87
|
+
# The name of the gateway
|
88
|
+
self.display_name = 'PayGate PayXML'
|
89
|
+
|
90
|
+
# PayGate only supports Rands
|
91
|
+
self.default_currency = 'ZAR'
|
92
|
+
|
93
|
+
# PayGate accepts only lowest denomination
|
94
|
+
self.money_format = :cents
|
95
|
+
|
96
|
+
# PayGateXML public test account - you can get a private one too
|
97
|
+
TEST_ID_3DSECURE = '10011013800'
|
98
|
+
TEST_ID = '10011021600'
|
99
|
+
TEST_PWD = 'test'
|
100
|
+
|
101
|
+
API_VERSION = '4.0'
|
102
|
+
|
103
|
+
DECLINE_CODES = {
|
104
|
+
# Credit Card Errors - These RESULT_CODEs are returned if the transaction cannot be authorized due to a problem with the card. The TRANSACTION_STATUS will be 2
|
105
|
+
900001 => "Call for Approval",
|
106
|
+
900002 => "Card Expired",
|
107
|
+
900003 => "Insufficient Funds",
|
108
|
+
900004 => "Invalid Card Number",
|
109
|
+
900005 => "Bank Interface Timeout", # indicates a communications failure between the banks systems
|
110
|
+
900006 => "Invalid Card",
|
111
|
+
900007 => "Declined",
|
112
|
+
900009 => "Lost Card",
|
113
|
+
900010 => "Invalid Card Length",
|
114
|
+
900011 => "Suspected Fraud",
|
115
|
+
900012 => "Card Reported As Stolen",
|
116
|
+
900013 => "Restricted Card",
|
117
|
+
900014 => "Excessive Card Usage",
|
118
|
+
900015 => "Card Blacklisted",
|
119
|
+
|
120
|
+
900207 => "Declined; authentication failed", # indicates the cardholder did not enter their MasterCard SecureCode / Verified by Visa password correctly
|
121
|
+
|
122
|
+
990020 => "Auth Declined",
|
123
|
+
|
124
|
+
991001 => "Invalid expiry date",
|
125
|
+
991002 => "Invalid amount",
|
126
|
+
|
127
|
+
# Communication Errors - These RESULT_CODEs are returned if the transaction cannot be completed due to an unexpected error. TRANSACTION_STATUS will be 0.
|
128
|
+
900205 => "Unexpected authentication result (phase 1)",
|
129
|
+
900206 => "Unexpected authentication result (phase 1)",
|
130
|
+
|
131
|
+
990001 => "Could not insert into Database",
|
132
|
+
|
133
|
+
990022 => "Bank not available",
|
134
|
+
|
135
|
+
990053 => "Error processing transaction",
|
136
|
+
|
137
|
+
# Miscellaneous - Unless otherwise noted, the TRANSACTION_STATUS will be 0.
|
138
|
+
900209 => "Transaction verification failed (phase 2)", # Indicates the verification data returned from MasterCard SecureCode / Verified by Visa has been altered
|
139
|
+
900210 => "Authentication complete; transaction must be restarted", # Indicates that the MasterCard SecuerCode / Verified by Visa transaction has already been completed. Most likely caused by the customer clicking the refresh button
|
140
|
+
|
141
|
+
990024 => "Duplicate Transaction Detected. Please check before submitting",
|
142
|
+
|
143
|
+
990028 => "Transaction cancelled" # Customer clicks the 'Cancel' button on the payment page
|
144
|
+
}
|
145
|
+
|
146
|
+
SUCCESS_CODES = %w( 990004 990005 990017 990012 990018 990031 )
|
147
|
+
|
148
|
+
TRANSACTION_CODES = {
|
149
|
+
0 => 'Not Done',
|
150
|
+
1 => 'Approved',
|
151
|
+
2 => 'Declined',
|
152
|
+
3 => 'Paid',
|
153
|
+
4 => 'Refunded',
|
154
|
+
5 => 'Received by PayGate',
|
155
|
+
6 => 'Replied to Client'
|
156
|
+
}
|
157
|
+
|
158
|
+
def initialize(options = {})
|
159
|
+
requires!(options, :login, :password)
|
160
|
+
@options = options
|
161
|
+
super
|
162
|
+
end
|
163
|
+
|
164
|
+
def purchase(money, creditcard, options = {})
|
165
|
+
MultiResponse.new.tap do |r|
|
166
|
+
r.process{authorize(money, creditcard, options)}
|
167
|
+
r.process{capture(money, r.authorization, options)}
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def authorize(money, creditcard, options = {})
|
172
|
+
action = 'authtx'
|
173
|
+
|
174
|
+
options.merge!(:money => money, :creditcard => creditcard)
|
175
|
+
commit(action, build_request(action, options))
|
176
|
+
end
|
177
|
+
|
178
|
+
def capture(money, authorization, options = {})
|
179
|
+
action = 'settletx'
|
180
|
+
|
181
|
+
options.merge!(:money => money, :authorization => authorization)
|
182
|
+
commit(action, build_request(action, options))
|
183
|
+
end
|
184
|
+
|
185
|
+
def test?
|
186
|
+
@options[:test] || (Base.gateway_mode == :test)
|
187
|
+
end
|
188
|
+
|
189
|
+
private
|
190
|
+
|
191
|
+
def successful?(response)
|
192
|
+
SUCCESS_CODES.include?(response[:res])
|
193
|
+
end
|
194
|
+
|
195
|
+
def build_request(action, options={})
|
196
|
+
xml = Builder::XmlMarkup.new
|
197
|
+
xml.instruct!
|
198
|
+
|
199
|
+
xml.tag! 'protocol', :ver => API_VERSION, :pgid => (test? ? TEST_ID : @options[:login]), :pwd => @options[:password] do |protocol|
|
200
|
+
case action
|
201
|
+
when 'authtx'
|
202
|
+
money = options.delete(:money)
|
203
|
+
creditcard = options.delete(:creditcard)
|
204
|
+
build_authorization(protocol, money, creditcard, options)
|
205
|
+
when 'settletx'
|
206
|
+
money = options.delete(:money)
|
207
|
+
authorization = options.delete(:authorization)
|
208
|
+
build_capture(protocol, money, authorization, options)
|
209
|
+
else
|
210
|
+
raise "no action specified for build_request"
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
xml.target!
|
215
|
+
end
|
216
|
+
|
217
|
+
def build_authorization(xml, money, creditcard, options={})
|
218
|
+
xml.tag! 'authtx', {
|
219
|
+
:cref => options[:order_id],
|
220
|
+
:cname => creditcard.name,
|
221
|
+
:cc => creditcard.number,
|
222
|
+
:exp => "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :four_digits)}",
|
223
|
+
:budp => 0,
|
224
|
+
:amt => amount(money),
|
225
|
+
:cur => (options[:currency] || currency(money)),
|
226
|
+
:cvv => creditcard.verification_value
|
227
|
+
}
|
228
|
+
end
|
229
|
+
|
230
|
+
def build_capture(xml, money, authorization, options={})
|
231
|
+
xml.tag! 'settletx', {
|
232
|
+
:tid => authorization
|
233
|
+
}
|
234
|
+
end
|
235
|
+
|
236
|
+
def parse(action, body)
|
237
|
+
hash = {}
|
238
|
+
xml = REXML::Document.new(body)
|
239
|
+
|
240
|
+
response_action = action.gsub(/tx/, 'rx')
|
241
|
+
root = REXML::XPath.first(xml.root, response_action)
|
242
|
+
# we might have gotten an error
|
243
|
+
if root.nil?
|
244
|
+
root = REXML::XPath.first(xml.root, 'errorrx')
|
245
|
+
end
|
246
|
+
root.attributes.each do |name, value|
|
247
|
+
hash[name.to_sym] = value
|
248
|
+
end
|
249
|
+
hash
|
250
|
+
end
|
251
|
+
|
252
|
+
def commit(action, request)
|
253
|
+
response = parse(action, ssl_post(LIVE_URL, request))
|
254
|
+
Response.new(successful?(response), message_from(response), response,
|
255
|
+
:test => test?,
|
256
|
+
:authorization => response[:tid]
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
def message_from(response)
|
261
|
+
(response[:rdesc] || response[:edesc])
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|