activemerchant 1.32.0 → 1.33.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/CHANGELOG +50 -0
- data/CONTRIBUTORS +8 -0
- data/README.md +6 -4
- data/lib/active_merchant/billing/check.rb +4 -3
- data/lib/active_merchant/billing/credit_card.rb +7 -3
- data/lib/active_merchant/billing/gateways/authorize_net.rb +27 -7
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +8 -1
- data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -185
- data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
- data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +0 -4
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +94 -12
- data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
- data/lib/active_merchant/billing/gateways/litle.rb +41 -11
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +27 -6
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -2
- data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
- data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
- data/lib/active_merchant/billing/gateways/orbital.rb +181 -48
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
- data/lib/active_merchant/billing/gateways/paymill.rb +27 -13
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +11 -6
- data/lib/active_merchant/billing/gateways/paypal_express.rb +25 -7
- data/lib/active_merchant/billing/gateways/pin.rb +5 -5
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +16 -11
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
- data/lib/active_merchant/billing/gateways/sage.rb +10 -5
- data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
- data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
- data/lib/active_merchant/billing/integrations/dwolla/common.rb +21 -0
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +15 -6
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +11 -6
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +12 -4
- data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
- data/lib/active_merchant/billing/integrations/notification.rb +13 -8
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +13 -1
- data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
- data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
- data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
- data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +68 -5
- data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
- data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
- data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +72 -62
- metadata.gz.sig +0 -0
|
@@ -30,56 +30,73 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
def purchase(money, creditcard, options = {})
|
|
31
31
|
requires!(options, :order_id)
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
add_creditcard(post, creditcard)
|
|
38
|
-
commit('Sale', post)
|
|
33
|
+
MultiResponse.run do |r|
|
|
34
|
+
r.process{authorize(money, creditcard, options)}
|
|
35
|
+
r.process{capture(money, r.authorization, options)}
|
|
36
|
+
end
|
|
39
37
|
end
|
|
40
38
|
|
|
41
39
|
def authorize(money, creditcard, options = {})
|
|
42
40
|
requires!(options, :order_id)
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
commit('Auth', post)
|
|
42
|
+
MultiResponse.run do |r|
|
|
43
|
+
r.process{setup_transaction(money, options)}
|
|
44
|
+
r.process{add_and_auth_credit_card(r.authorization, creditcard, options)}
|
|
45
|
+
r.process{query_transaction(r.authorization, options)}
|
|
46
|
+
end
|
|
50
47
|
end
|
|
51
48
|
|
|
52
49
|
def capture(money, authorization, options = {})
|
|
53
50
|
post = {}
|
|
54
51
|
add_credentials(post, options)
|
|
55
52
|
add_authorization(post, authorization, money)
|
|
56
|
-
|
|
53
|
+
post[:operation] = "Capture"
|
|
54
|
+
commit("Netaxept/process.aspx", post)
|
|
57
55
|
end
|
|
58
56
|
|
|
59
57
|
def refund(money, authorization, options = {})
|
|
60
58
|
post = {}
|
|
61
59
|
add_credentials(post, options)
|
|
62
60
|
add_authorization(post, authorization, money)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def credit(money, authorization, options = {})
|
|
67
|
-
deprecated CREDIT_DEPRECATION_MESSAGE
|
|
68
|
-
refund(money, authorization, options)
|
|
61
|
+
post[:operation] = "Credit"
|
|
62
|
+
commit("Netaxept/process.aspx", post)
|
|
69
63
|
end
|
|
70
64
|
|
|
71
65
|
def void(authorization, options = {})
|
|
72
66
|
post = {}
|
|
73
67
|
add_credentials(post, options)
|
|
74
68
|
add_authorization(post, authorization)
|
|
75
|
-
|
|
69
|
+
post[:operation] = "Annul"
|
|
70
|
+
commit("Netaxept/process.aspx", post)
|
|
76
71
|
end
|
|
77
72
|
|
|
78
73
|
private
|
|
79
74
|
|
|
80
|
-
def
|
|
75
|
+
def setup_transaction(money, options)
|
|
76
|
+
post = {}
|
|
77
|
+
add_credentials(post, options)
|
|
78
|
+
add_order(post, money, options)
|
|
79
|
+
commit("Netaxept/Register.aspx", post)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def add_and_auth_credit_card(authorization, creditcard, options)
|
|
83
|
+
post = {}
|
|
84
|
+
add_credentials(post, options, false)
|
|
85
|
+
add_authorization(post, authorization)
|
|
86
|
+
add_creditcard(post, creditcard)
|
|
87
|
+
commit("terminal/default.aspx", post, false)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def query_transaction(authorization, options)
|
|
91
|
+
post = {}
|
|
92
|
+
add_credentials(post, options)
|
|
93
|
+
add_authorization(post, authorization)
|
|
94
|
+
commit("Netaxept/query.aspx", post)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def add_credentials(post, options, secure=true)
|
|
81
98
|
post[:merchantId] = @options[:login]
|
|
82
|
-
post[:token] = @options[:password]
|
|
99
|
+
post[:token] = @options[:password] if secure
|
|
83
100
|
end
|
|
84
101
|
|
|
85
102
|
def add_authorization(post, authorization, money=nil)
|
|
@@ -87,92 +104,45 @@ module ActiveMerchant #:nodoc:
|
|
|
87
104
|
post[:transactionAmount] = amount(money) if money
|
|
88
105
|
end
|
|
89
106
|
|
|
90
|
-
def add_transaction(post, options)
|
|
91
|
-
post[:transactionId] = generate_transaction_id(options)
|
|
92
|
-
post[:serviceType] = 'M'
|
|
93
|
-
post[:redirectUrl] = 'http://example.com'
|
|
94
|
-
end
|
|
95
|
-
|
|
96
107
|
def add_order(post, money, options)
|
|
108
|
+
post[:serviceType] = 'M'
|
|
97
109
|
post[:orderNumber] = options[:order_id]
|
|
98
110
|
post[:amount] = amount(money)
|
|
99
111
|
post[:currencyCode] = (options[:currency] || currency(money))
|
|
112
|
+
post[:autoAuth] = "true"
|
|
100
113
|
end
|
|
101
114
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
def add_creditcard(post, creditcard)
|
|
108
|
-
brand = Gateway.card_brand(creditcard)
|
|
109
|
-
prefix = CARD_TYPE_PREFIXES[brand]
|
|
110
|
-
unless prefix
|
|
111
|
-
raise ArgumentError.new("Card type #{brand} not supported.")
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
post[:creditcard] = {}
|
|
115
|
-
post[:creditcard][:"#{prefix}a"] = creditcard.number
|
|
116
|
-
post[:creditcard][:"#{prefix}m"] = format(creditcard.month, :two_digits)
|
|
117
|
-
post[:creditcard][:"#{prefix}y"] = format(creditcard.year, :two_digits)
|
|
118
|
-
post[:creditcard][:"#{prefix}c"] = creditcard.verification_value
|
|
115
|
+
def add_creditcard(post, options)
|
|
116
|
+
post[:pan] = options.number
|
|
117
|
+
post[:expiryDate] = format(options.month, :two_digits) + format(options.year, :two_digits)
|
|
118
|
+
post[:securityCode] = options.verification_value
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
def commit(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
response = {:success => false}
|
|
125
|
-
|
|
126
|
-
catch(:exception) do
|
|
127
|
-
if setup
|
|
128
|
-
commit_transaction_setup(response, parameters)
|
|
129
|
-
commit_payment_details(response, parameters)
|
|
130
|
-
commit_process_setup(response, parameters)
|
|
131
|
-
end
|
|
132
|
-
commit_transaction(response, parameters)
|
|
133
|
-
response[:success] = true
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
Response.new(response[:success], response[:message], response, :test => test?, :authorization => response[:authorization])
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def commit_transaction_setup(response, parameters)
|
|
140
|
-
response[:setup] = parse(ssl_get(build_url("REST/Setup.aspx", pick(parameters, :merchantId, :token, :serviceType, :amount, :currencyCode, :redirectUrl, :orderNumber, :transactionId))))
|
|
141
|
-
process(response, :setup)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def commit_payment_details(response, parameters)
|
|
145
|
-
data = encode(parameters[:creditcard].merge(:BBSePay_transaction => response[:setup]['SetupString']))
|
|
146
|
-
response[:paymentDetails] = parse(ssl_post(build_url("terminal/default.aspx"), data), false)
|
|
147
|
-
process(response, :paymentDetails)
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def commit_process_setup(response, parameters)
|
|
151
|
-
result = ssl_get(build_url("REST/ProcessSetup.aspx", pick(parameters, :merchantId, :token, :transactionId).merge(:transactionString => response[:paymentDetails][:result])))
|
|
152
|
-
response[:processSetup] = parse(result)
|
|
153
|
-
process(response, :processSetup)
|
|
154
|
-
end
|
|
121
|
+
def commit(path, parameters, xml=true)
|
|
122
|
+
raw = parse(ssl_get(build_url(path, parameters)), xml)
|
|
155
123
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
def process(response, step)
|
|
163
|
-
if response[step][:container] =~ /Exception|Error/
|
|
164
|
-
response[:message] = response[step]['Message']
|
|
165
|
-
throw :exception
|
|
124
|
+
success = false
|
|
125
|
+
authorization = (raw["TransactionId"] || parameters[:transactionId])
|
|
126
|
+
if raw[:container] =~ /Exception|Error/
|
|
127
|
+
message = (raw["Message"] || raw["Error"]["Message"])
|
|
128
|
+
elsif raw["Error"] && !raw["Error"].empty?
|
|
129
|
+
message = (raw["Error"]["ResponseText"] || raw["Error"]["ResponseCode"])
|
|
166
130
|
else
|
|
167
|
-
message = (
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
response[:authorization] = response[step]['TransactionId']
|
|
131
|
+
message = (raw["ResponseText"] || raw["ResponseCode"] || "OK")
|
|
132
|
+
success = true
|
|
171
133
|
end
|
|
134
|
+
|
|
135
|
+
Response.new(
|
|
136
|
+
success,
|
|
137
|
+
message,
|
|
138
|
+
raw,
|
|
139
|
+
:test => test?,
|
|
140
|
+
:authorization => authorization
|
|
141
|
+
)
|
|
172
142
|
end
|
|
173
143
|
|
|
174
144
|
def parse(result, expects_xml=true)
|
|
175
|
-
if expects_xml
|
|
145
|
+
if expects_xml
|
|
176
146
|
doc = REXML::Document.new(result)
|
|
177
147
|
extract_xml(doc.root).merge(:container => doc.root.name)
|
|
178
148
|
else
|
|
@@ -192,20 +162,8 @@ module ActiveMerchant #:nodoc:
|
|
|
192
162
|
end
|
|
193
163
|
end
|
|
194
164
|
|
|
195
|
-
def url
|
|
196
|
-
(test? ? self.test_url : self.live_url)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def generate_transaction_id(options)
|
|
200
|
-
Digest::MD5.hexdigest("#{options.inspect}+#{Time.now}+#{rand}")
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def pick(hash, *keys)
|
|
204
|
-
keys.inject({}){|h,key| h[key] = hash[key] if hash[key]; h}
|
|
205
|
-
end
|
|
206
|
-
|
|
207
165
|
def build_url(base, parameters=nil)
|
|
208
|
-
url =
|
|
166
|
+
url = (test? ? self.test_url : self.live_url).dup
|
|
209
167
|
url << base
|
|
210
168
|
if parameters
|
|
211
169
|
url << '?'
|
|
@@ -217,16 +175,6 @@ module ActiveMerchant #:nodoc:
|
|
|
217
175
|
def encode(hash)
|
|
218
176
|
hash.collect{|(k,v)| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"}.join('&')
|
|
219
177
|
end
|
|
220
|
-
|
|
221
|
-
class Response < Billing::Response
|
|
222
|
-
attr_reader :error_detail
|
|
223
|
-
def initialize(success, message, raw, options)
|
|
224
|
-
super
|
|
225
|
-
unless success
|
|
226
|
-
@error_detail = raw[:processSetup]['Result']['ResponseText'] if raw[:processSetup] && raw[:processSetup]['Result']
|
|
227
|
-
end
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
178
|
end
|
|
231
179
|
end
|
|
232
180
|
end
|
|
@@ -32,8 +32,8 @@ module ActiveMerchant #:nodoc:
|
|
|
32
32
|
API_VERSION = "5.6"
|
|
33
33
|
|
|
34
34
|
POST_HEADERS = {
|
|
35
|
-
"MIME-Version" => "1.
|
|
36
|
-
"Content-Type" => "
|
|
35
|
+
"MIME-Version" => "1.1",
|
|
36
|
+
"Content-Type" => "application/PTI56",
|
|
37
37
|
"Content-transfer-encoding" => "text",
|
|
38
38
|
"Request-number" => '1',
|
|
39
39
|
"Document-type" => "Request",
|
|
@@ -80,6 +80,63 @@ module ActiveMerchant #:nodoc:
|
|
|
80
80
|
"EUR" => '978'
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
# INDUSTRY TYPES
|
|
84
|
+
ECOMMERCE_TRANSACTION = 'EC'
|
|
85
|
+
RECURRING_PAYMENT_TRANSACTION = 'RC'
|
|
86
|
+
MAIL_ORDER_TELEPHONE_ORDER_TRANSACTION = 'MO'
|
|
87
|
+
INTERACTIVE_VOICE_RESPONSE = 'IV'
|
|
88
|
+
# INTERACTIVE_VOICE_RESPONSE = 'IN'
|
|
89
|
+
|
|
90
|
+
# Auth Only No Capture
|
|
91
|
+
AUTH_ONLY = 'A'
|
|
92
|
+
# AC - Auth and Capture = 'AC'
|
|
93
|
+
AUTH_AND_CAPTURE = 'AC'
|
|
94
|
+
# F - Force Auth No Capture and no online authorization = 'F'
|
|
95
|
+
FORCE_AUTH_ONLY = 'F'
|
|
96
|
+
# FR - Force Auth No Capture and no online authorization = 'FR'
|
|
97
|
+
# FC - Force Auth and Capture no online authorization = 'FC'
|
|
98
|
+
FORCE_AUTH_AND_CAPTURE = 'FC'
|
|
99
|
+
# Refund and Capture no online authorization
|
|
100
|
+
REFUND = 'R'
|
|
101
|
+
|
|
102
|
+
# Tax Inds
|
|
103
|
+
TAX_NOT_PROVIDED = 0
|
|
104
|
+
TAX_INCLUDED = 1
|
|
105
|
+
NON_TAXABLE_TRANSACTION = 2
|
|
106
|
+
|
|
107
|
+
# Customer Profile Actions
|
|
108
|
+
CREATE = 'C'
|
|
109
|
+
RETRIEVE = 'R'
|
|
110
|
+
UPDATE = 'U'
|
|
111
|
+
DELETE = 'D'
|
|
112
|
+
|
|
113
|
+
RECURRING = 'R'
|
|
114
|
+
DEFERRED = 'D'
|
|
115
|
+
|
|
116
|
+
# Status
|
|
117
|
+
# Profile Status Flag
|
|
118
|
+
# This field is used to set the status of a Customer Profile.
|
|
119
|
+
ACTIVE = 'A'
|
|
120
|
+
INACTIVE = 'I'
|
|
121
|
+
MANUAL_SUSPEND = 'MS'
|
|
122
|
+
|
|
123
|
+
# CustomerProfileOrderOverrideInd
|
|
124
|
+
# Defines if any Order Data can be pre-populated from
|
|
125
|
+
# the Customer Reference Number (CustomerRefNum)
|
|
126
|
+
NO_MAPPING_TO_ORDER_DATA = 'NO'
|
|
127
|
+
USE_CRN_FOR_ORDER_ID = 'OI'
|
|
128
|
+
USE_CRN_FOR_COMMENTS = 'OD'
|
|
129
|
+
USE_CRN_FOR_ORDER_ID_AND_COMMENTS = 'OA'
|
|
130
|
+
|
|
131
|
+
# CustomerProfileFromOrderInd
|
|
132
|
+
# Method to use to Generate the Customer Profile Number
|
|
133
|
+
# When Customer Profile Action Type = Create, defines
|
|
134
|
+
# what the Customer Profile Number will be:
|
|
135
|
+
AUTO_GENERATE = 'A' # Auto-Generate the CustomerRefNum
|
|
136
|
+
USE_CUSTOMER_REF_NUM = 'S' # Use CustomerRefNum field
|
|
137
|
+
USE_ORDER_ID = 'O' # Use OrderID field
|
|
138
|
+
USE_COMMENTS = 'D' # Use Comments field
|
|
139
|
+
|
|
83
140
|
def initialize(options = {})
|
|
84
141
|
requires!(options, :merchant_id)
|
|
85
142
|
requires!(options, :login, :password) unless options[:ip_authentication]
|
|
@@ -88,22 +145,28 @@ module ActiveMerchant #:nodoc:
|
|
|
88
145
|
|
|
89
146
|
# A – Authorization request
|
|
90
147
|
def authorize(money, creditcard, options = {})
|
|
91
|
-
order = build_new_order_xml(
|
|
148
|
+
order = build_new_order_xml(AUTH_ONLY, money, options) do |xml|
|
|
92
149
|
add_creditcard(xml, creditcard, options[:currency]) unless creditcard.nil? && options[:profile_txn]
|
|
93
150
|
add_address(xml, creditcard, options)
|
|
94
|
-
|
|
151
|
+
if @options[:customer_profiles]
|
|
152
|
+
add_customer_data(xml, options)
|
|
153
|
+
add_managed_billing(xml, options)
|
|
154
|
+
end
|
|
95
155
|
end
|
|
96
|
-
commit(order, :authorize)
|
|
156
|
+
commit(order, :authorize, options[:trace_number])
|
|
97
157
|
end
|
|
98
158
|
|
|
99
159
|
# AC – Authorization and Capture
|
|
100
160
|
def purchase(money, creditcard, options = {})
|
|
101
|
-
order = build_new_order_xml(
|
|
161
|
+
order = build_new_order_xml(AUTH_AND_CAPTURE, money, options) do |xml|
|
|
102
162
|
add_creditcard(xml, creditcard, options[:currency]) unless creditcard.nil? && options[:profile_txn]
|
|
103
163
|
add_address(xml, creditcard, options)
|
|
104
|
-
|
|
164
|
+
if @options[:customer_profiles]
|
|
165
|
+
add_customer_data(xml, options)
|
|
166
|
+
add_managed_billing(xml, options)
|
|
167
|
+
end
|
|
105
168
|
end
|
|
106
|
-
commit(order, :purchase)
|
|
169
|
+
commit(order, :purchase, options[:trace_number])
|
|
107
170
|
end
|
|
108
171
|
|
|
109
172
|
# MFC - Mark For Capture
|
|
@@ -113,11 +176,11 @@ module ActiveMerchant #:nodoc:
|
|
|
113
176
|
|
|
114
177
|
# R – Refund request
|
|
115
178
|
def refund(money, authorization, options = {})
|
|
116
|
-
order = build_new_order_xml(
|
|
179
|
+
order = build_new_order_xml(REFUND, money, options.merge(:authorization => authorization)) do |xml|
|
|
117
180
|
add_refund(xml, options[:currency])
|
|
118
181
|
xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
|
|
119
182
|
end
|
|
120
|
-
commit(order, :refund)
|
|
183
|
+
commit(order, :refund, options[:trace_number])
|
|
121
184
|
end
|
|
122
185
|
|
|
123
186
|
def credit(money, authorization, options= {})
|
|
@@ -132,7 +195,7 @@ module ActiveMerchant #:nodoc:
|
|
|
132
195
|
end
|
|
133
196
|
|
|
134
197
|
order = build_void_request_xml(authorization, options)
|
|
135
|
-
commit(order, :void)
|
|
198
|
+
commit(order, :void, options[:trace_number])
|
|
136
199
|
end
|
|
137
200
|
|
|
138
201
|
|
|
@@ -158,25 +221,25 @@ module ActiveMerchant #:nodoc:
|
|
|
158
221
|
# 'MS' - Manual Suspend
|
|
159
222
|
|
|
160
223
|
def add_customer_profile(creditcard, options = {})
|
|
161
|
-
options.merge!(:customer_profile_action =>
|
|
224
|
+
options.merge!(:customer_profile_action => CREATE)
|
|
162
225
|
order = build_customer_request_xml(creditcard, options)
|
|
163
226
|
commit(order, :add_customer_profile)
|
|
164
227
|
end
|
|
165
228
|
|
|
166
229
|
def update_customer_profile(creditcard, options = {})
|
|
167
|
-
options.merge!(:customer_profile_action =>
|
|
230
|
+
options.merge!(:customer_profile_action => UPDATE)
|
|
168
231
|
order = build_customer_request_xml(creditcard, options)
|
|
169
232
|
commit(order, :update_customer_profile)
|
|
170
233
|
end
|
|
171
234
|
|
|
172
235
|
def retrieve_customer_profile(customer_ref_num)
|
|
173
|
-
options = {:customer_profile_action =>
|
|
236
|
+
options = {:customer_profile_action => RETRIEVE, :customer_ref_num => customer_ref_num}
|
|
174
237
|
order = build_customer_request_xml(nil, options)
|
|
175
238
|
commit(order, :retrieve_customer_profile)
|
|
176
239
|
end
|
|
177
240
|
|
|
178
241
|
def delete_customer_profile(customer_ref_num)
|
|
179
|
-
options = {:customer_profile_action =>
|
|
242
|
+
options = {:customer_profile_action => DELETE, :customer_ref_num => customer_ref_num}
|
|
180
243
|
order = build_customer_request_xml(nil, options)
|
|
181
244
|
commit(order, :delete_customer_profile)
|
|
182
245
|
end
|
|
@@ -196,12 +259,12 @@ module ActiveMerchant #:nodoc:
|
|
|
196
259
|
xml.tag! :CustomerRefNum, options[:customer_ref_num]
|
|
197
260
|
else
|
|
198
261
|
if options[:customer_ref_num]
|
|
199
|
-
xml.tag! :CustomerProfileFromOrderInd,
|
|
262
|
+
xml.tag! :CustomerProfileFromOrderInd, USE_CUSTOMER_REF_NUM
|
|
200
263
|
xml.tag! :CustomerRefNum, options[:customer_ref_num]
|
|
201
264
|
else
|
|
202
|
-
xml.tag! :CustomerProfileFromOrderInd,
|
|
265
|
+
xml.tag! :CustomerProfileFromOrderInd, AUTO_GENERATE
|
|
203
266
|
end
|
|
204
|
-
xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] ||
|
|
267
|
+
xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
|
|
205
268
|
end
|
|
206
269
|
end
|
|
207
270
|
|
|
@@ -215,32 +278,51 @@ module ActiveMerchant #:nodoc:
|
|
|
215
278
|
end
|
|
216
279
|
|
|
217
280
|
def add_address(xml, creditcard, options)
|
|
218
|
-
if
|
|
281
|
+
if(address = (options[:billing_address] || options[:address]))
|
|
219
282
|
avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
|
|
220
283
|
|
|
221
284
|
if avs_supported
|
|
222
|
-
xml.tag! :AVSzip, address[:zip].to_s[0..9]
|
|
223
|
-
xml.tag! :AVSaddress1, address[:address1][0..29]
|
|
224
|
-
xml.tag! :AVSaddress2, address[:address2][0..29]
|
|
225
|
-
xml.tag! :AVScity, address[:city][0..19]
|
|
226
|
-
xml.tag! :AVSstate,
|
|
227
|
-
xml.tag! :AVSphoneNum,
|
|
285
|
+
xml.tag! :AVSzip, (address[:zip] ? address[:zip].to_s[0..9] : nil)
|
|
286
|
+
xml.tag! :AVSaddress1, (address[:address1] ? address[:address1][0..29] : nil)
|
|
287
|
+
xml.tag! :AVSaddress2, (address[:address2] ? address[:address2][0..29] : nil)
|
|
288
|
+
xml.tag! :AVScity, (address[:city] ? address[:city][0..19] : nil)
|
|
289
|
+
xml.tag! :AVSstate, address[:state]
|
|
290
|
+
xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
|
|
228
291
|
end
|
|
229
|
-
|
|
230
|
-
xml.tag! :
|
|
292
|
+
# can't look in billing address?
|
|
293
|
+
xml.tag! :AVSname, ((creditcard && creditcard.name) ? creditcard.name[0..29] : nil)
|
|
294
|
+
xml.tag! :AVScountryCode, (avs_supported ? address[:country] : '')
|
|
295
|
+
|
|
296
|
+
# Needs to come after AVScountryCode
|
|
297
|
+
add_destination_address(xml, address) if avs_supported
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
def add_destination_address(xml, address)
|
|
302
|
+
if address[:dest_zip]
|
|
303
|
+
xml.tag! :AVSDestzip, (address[:dest_zip] ? address[:dest_zip].to_s[0..9] : nil)
|
|
304
|
+
xml.tag! :AVSDestaddress1, (address[:dest_address1] ? address[:dest_address1][0..29] : nil)
|
|
305
|
+
xml.tag! :AVSDestaddress2, (address[:dest_address2] ? address[:dest_address2][0..29] : nil)
|
|
306
|
+
xml.tag! :AVSDestcity, (address[:dest_city] ? address[:dest_city][0..19] : nil)
|
|
307
|
+
xml.tag! :AVSDeststate, address[:dest_state]
|
|
308
|
+
xml.tag! :AVSDestphoneNum, (address[:dest_phone] ? address[:dest_phone].scan(/\d/).join.to_s[0..13] : nil)
|
|
309
|
+
|
|
310
|
+
xml.tag! :AVSDestname, (address[:dest_name] ? address[:dest_name][0..29] : nil)
|
|
311
|
+
xml.tag! :AVSDestcountryCode, address[:dest_country]
|
|
231
312
|
end
|
|
232
313
|
end
|
|
233
314
|
|
|
234
315
|
# For Profile requests
|
|
235
316
|
def add_customer_address(xml, options)
|
|
236
|
-
if
|
|
237
|
-
xml.tag! :CustomerAddress1, address[:address1]
|
|
238
|
-
xml.tag! :CustomerAddress2, address[:address2]
|
|
239
|
-
xml.tag! :CustomerCity, address[:city]
|
|
317
|
+
if(address = (options[:billing_address] || options[:address]))
|
|
318
|
+
xml.tag! :CustomerAddress1, (address[:address1] ? address[:address1][0..29] : nil)
|
|
319
|
+
xml.tag! :CustomerAddress2, (address[:address2] ? address[:address2][0..29] : nil)
|
|
320
|
+
xml.tag! :CustomerCity, (address[:city] ? address[:city][0..19] : nil)
|
|
240
321
|
xml.tag! :CustomerState, address[:state]
|
|
241
|
-
xml.tag! :CustomerZIP, address[:zip]
|
|
242
|
-
xml.tag! :
|
|
243
|
-
xml.tag! :
|
|
322
|
+
xml.tag! :CustomerZIP, (address[:zip] ? address[:zip].to_s[0..9] : nil)
|
|
323
|
+
xml.tag! :CustomerEmail, address[:email].to_s[0..49] if address[:email]
|
|
324
|
+
xml.tag! :CustomerPhone, (address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil)
|
|
325
|
+
xml.tag! :CustomerCountryCode, (address[:country] ? address[:country][0..1] : nil)
|
|
244
326
|
end
|
|
245
327
|
end
|
|
246
328
|
|
|
@@ -261,7 +343,7 @@ module ActiveMerchant #:nodoc:
|
|
|
261
343
|
# Do not submit the attribute at all.
|
|
262
344
|
# - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
|
263
345
|
if %w( visa discover ).include?(creditcard.brand)
|
|
264
|
-
xml.tag! :CardSecValInd, creditcard.verification_value? ? '1' : '9'
|
|
346
|
+
xml.tag! :CardSecValInd, (creditcard.verification_value? ? '1' : '9')
|
|
265
347
|
end
|
|
266
348
|
xml.tag! :CardSecVal, creditcard.verification_value if creditcard.verification_value?
|
|
267
349
|
end
|
|
@@ -273,6 +355,27 @@ module ActiveMerchant #:nodoc:
|
|
|
273
355
|
xml.tag! :CurrencyExponent, '2' # Will need updating to support currencies such as the Yen.
|
|
274
356
|
end
|
|
275
357
|
|
|
358
|
+
def add_managed_billing(xml, options)
|
|
359
|
+
if mb = options[:managed_billing]
|
|
360
|
+
# default to recurring (R). Other option is deferred (D).
|
|
361
|
+
xml.tag! :MBType, mb[:type] || RECURRING
|
|
362
|
+
# default to Customer Reference Number
|
|
363
|
+
xml.tag! :MBOrderIdGenerationMethod, mb[:order_id_generation_method] || 'IO'
|
|
364
|
+
# By default use MBRecurringEndDate, set to N.
|
|
365
|
+
# MMDDYYYY
|
|
366
|
+
xml.tag! :MBRecurringStartDate, mb[:start_date].scan(/\d/).join.to_s if mb[:start_date]
|
|
367
|
+
# MMDDYYYY
|
|
368
|
+
xml.tag! :MBRecurringEndDate, mb[:end_date].scan(/\d/).join.to_s if mb[:end_date]
|
|
369
|
+
# By default listen to any value set in MBRecurringEndDate.
|
|
370
|
+
xml.tag! :MBRecurringNoEndDateFlag, mb[:no_end_date_flag] || 'N' # 'Y' || 'N' (Yes or No).
|
|
371
|
+
xml.tag! :MBRecurringMaxBillings, mb[:max_billings] if mb[:max_billings]
|
|
372
|
+
xml.tag! :MBRecurringFrequency, mb[:frequency] if mb[:frequency]
|
|
373
|
+
xml.tag! :MBDeferredBillDate, mb[:deferred_bill_date] if mb[:deferred_bill_date]
|
|
374
|
+
xml.tag! :MBMicroPaymentMaxDollarValue, mb[:max_dollar_value] if mb[:max_dollar_value]
|
|
375
|
+
xml.tag! :MBMicroPaymentMaxBillingDays, mb[:max_billing_days] if mb[:max_billing_days]
|
|
376
|
+
xml.tag! :MBMicroPaymentMaxTransactions, mb[:max_transactions] if mb[:max_transactions]
|
|
377
|
+
end
|
|
378
|
+
end
|
|
276
379
|
|
|
277
380
|
def parse(body)
|
|
278
381
|
response = {}
|
|
@@ -295,8 +398,10 @@ module ActiveMerchant #:nodoc:
|
|
|
295
398
|
end
|
|
296
399
|
end
|
|
297
400
|
|
|
298
|
-
def commit(order, message_type)
|
|
401
|
+
def commit(order, message_type, trace_number=nil)
|
|
299
402
|
headers = POST_HEADERS.merge("Content-length" => order.size.to_s)
|
|
403
|
+
headers.merge!( "Trace-number" => trace_number.to_s,
|
|
404
|
+
"Merchant-Id" => @options[:merchant_id] ) if @options[:retry_logic] && trace_number
|
|
300
405
|
request = lambda{|url| parse(ssl_post(url, order, headers))}
|
|
301
406
|
|
|
302
407
|
# Failover URL will be attempted in the event of a connection error
|
|
@@ -318,9 +423,9 @@ module ActiveMerchant #:nodoc:
|
|
|
318
423
|
|
|
319
424
|
def remote_url(url=:primary)
|
|
320
425
|
if url == :primary
|
|
321
|
-
self.test? ? self.test_url : self.live_url
|
|
426
|
+
(self.test? ? self.test_url : self.live_url)
|
|
322
427
|
else
|
|
323
|
-
self.test? ? self.secondary_test_url : self.secondary_live_url
|
|
428
|
+
(self.test? ? self.secondary_test_url : self.secondary_live_url)
|
|
324
429
|
end
|
|
325
430
|
end
|
|
326
431
|
|
|
@@ -349,7 +454,18 @@ module ActiveMerchant #:nodoc:
|
|
|
349
454
|
xml.tag! :Request do
|
|
350
455
|
xml.tag! :NewOrder do
|
|
351
456
|
add_xml_credentials(xml)
|
|
352
|
-
|
|
457
|
+
# EC - Ecommerce transaction
|
|
458
|
+
# RC - Recurring Payment transaction
|
|
459
|
+
# MO - Mail Order Telephone Order transaction
|
|
460
|
+
# IV - Interactive Voice Response
|
|
461
|
+
# IN - Interactive Voice Response
|
|
462
|
+
xml.tag! :IndustryType, parameters[:industry_type] || ECOMMERCE_TRANSACTION
|
|
463
|
+
# A - Auth Only No Capture
|
|
464
|
+
# AC - Auth and Capture
|
|
465
|
+
# F - Force Auth No Capture and no online authorization
|
|
466
|
+
# FR - Force Auth No Capture and no online authorization
|
|
467
|
+
# FC - Force Auth and Capture no online authorization
|
|
468
|
+
# R - Refund and Capture no online authorization
|
|
353
469
|
xml.tag! :MessageType, action
|
|
354
470
|
add_bin_merchant_and_terminal(xml, parameters)
|
|
355
471
|
|
|
@@ -359,6 +475,8 @@ module ActiveMerchant #:nodoc:
|
|
|
359
475
|
xml.tag! :Amount, amount(money)
|
|
360
476
|
xml.tag! :Comments, parameters[:comments] if parameters[:comments]
|
|
361
477
|
|
|
478
|
+
# CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
|
|
479
|
+
|
|
362
480
|
if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
|
|
363
481
|
add_soft_descriptors(xml, parameters[:soft_descriptors])
|
|
364
482
|
end
|
|
@@ -366,7 +484,7 @@ module ActiveMerchant #:nodoc:
|
|
|
366
484
|
set_recurring_ind(xml, parameters)
|
|
367
485
|
|
|
368
486
|
# Append Transaction Reference Number at the end for Refund transactions
|
|
369
|
-
if action ==
|
|
487
|
+
if action == REFUND
|
|
370
488
|
tx_ref_num, _ = split_authorization(parameters[:authorization])
|
|
371
489
|
xml.tag! :TxRefNum, tx_ref_num
|
|
372
490
|
end
|
|
@@ -411,6 +529,8 @@ module ActiveMerchant #:nodoc:
|
|
|
411
529
|
xml.tag! :AdjustedAmt, parameters[:amount] # setting adjusted amount to nil will void entire amount
|
|
412
530
|
xml.tag! :OrderID, format_order_id(order_id || parameters[:order_id])
|
|
413
531
|
add_bin_merchant_and_terminal(xml, parameters)
|
|
532
|
+
xml.tag! :ReversalRetryNumber, parameters[:reversal_retry_number] if parameters[:reversal_retry_number]
|
|
533
|
+
xml.tag! :OnlineReversalInd, parameters[:online_reversal_ind] if parameters[:online_reversal_ind]
|
|
414
534
|
end
|
|
415
535
|
end
|
|
416
536
|
xml.target!
|
|
@@ -435,8 +555,10 @@ module ActiveMerchant #:nodoc:
|
|
|
435
555
|
end
|
|
436
556
|
|
|
437
557
|
def add_xml_credentials(xml)
|
|
438
|
-
|
|
439
|
-
|
|
558
|
+
unless ip_authentication?
|
|
559
|
+
xml.tag! :OrbitalConnectionUsername, @options[:login]
|
|
560
|
+
xml.tag! :OrbitalConnectionPassword, @options[:password]
|
|
561
|
+
end
|
|
440
562
|
end
|
|
441
563
|
|
|
442
564
|
def add_bin_merchant_and_terminal(xml, parameters)
|
|
@@ -475,22 +597,33 @@ module ActiveMerchant #:nodoc:
|
|
|
475
597
|
add_customer_address(xml, options)
|
|
476
598
|
|
|
477
599
|
xml.tag! :CustomerProfileAction, options[:customer_profile_action] # C, R, U, D
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
600
|
+
# NO No mapping to order data
|
|
601
|
+
# OI Use <CustomerRefNum> for <OrderID>
|
|
602
|
+
# OD Use <CustomerReferNum> for <Comments>
|
|
603
|
+
# OA Use <CustomerRefNum> for <OrderID> and <Comments>
|
|
604
|
+
xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
|
|
605
|
+
|
|
606
|
+
if options[:customer_profile_action] == CREATE
|
|
607
|
+
# A Auto-Generate the CustomerRefNum
|
|
608
|
+
# S Use CustomerRefNum field
|
|
609
|
+
# O Use OrderID field
|
|
610
|
+
# D Use Comments field
|
|
611
|
+
xml.tag! :CustomerProfileFromOrderInd, (options[:customer_ref_num] ? USE_CUSTOMER_REF_NUM : AUTO_GENERATE)
|
|
482
612
|
end
|
|
483
613
|
|
|
484
614
|
xml.tag! :OrderDefaultDescription, options[:order_default_description][0..63] if options[:order_default_description]
|
|
485
615
|
xml.tag! :OrderDefaultAmount, options[:order_default_amount] if options[:order_default_amount]
|
|
486
616
|
|
|
487
|
-
if [
|
|
617
|
+
if [CREATE, UPDATE].include? options[:customer_profile_action]
|
|
488
618
|
xml.tag! :CustomerAccountType, 'CC' # Only credit card supported
|
|
489
|
-
xml.tag! :Status, options[:status] ||
|
|
619
|
+
xml.tag! :Status, options[:status] || ACTIVE # Active
|
|
490
620
|
end
|
|
491
621
|
|
|
492
622
|
xml.tag! :CCAccountNum, creditcard.number if creditcard
|
|
493
623
|
xml.tag! :CCExpireDate, creditcard.expiry_date.expiration.strftime("%m%y") if creditcard
|
|
624
|
+
|
|
625
|
+
# This has to come after CCExpireDate.
|
|
626
|
+
add_managed_billing(xml, options)
|
|
494
627
|
end
|
|
495
628
|
end
|
|
496
629
|
xml.target!
|