activemerchant 1.29.3 → 1.30.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +39 -0
- data/CONTRIBUTORS +19 -0
- data/README.md +43 -41
- data/lib/active_merchant/billing/check.rb +15 -11
- data/lib/active_merchant/billing/credit_card.rb +5 -1
- data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
- data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
- data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
- data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +6 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
- data/lib/active_merchant/billing/gateways/eway.rb +114 -171
- data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +222 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
- data/lib/active_merchant/billing/gateways/litle.rb +50 -19
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +2 -4
- data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
- data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +18 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +9 -5
- data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_express.rb +2 -0
- data/lib/active_merchant/billing/gateways/pin.rb +157 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
- data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
- data/lib/active_merchant/billing/gateways/sage_pay.rb +6 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +235 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +1 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +4 -1
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
- data/lib/active_merchant/version.rb +1 -1
- metadata +109 -49
- metadata.gz.sig +0 -0
@@ -89,7 +89,18 @@ module ActiveMerchant #:nodoc:
|
|
89
89
|
commit("ProcessPayment", post)
|
90
90
|
end
|
91
91
|
|
92
|
-
#
|
92
|
+
# Get customer's stored credit card details given by billing_id
|
93
|
+
#
|
94
|
+
# ==== Parameters
|
95
|
+
#
|
96
|
+
# * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
|
97
|
+
def retrieve(billing_id)
|
98
|
+
post = {}
|
99
|
+
post[:managedCustomerID] = billing_id.to_s
|
100
|
+
|
101
|
+
commit("QueryCustomer", post)
|
102
|
+
end
|
103
|
+
|
93
104
|
# TODO: eWay API also provides QueryPayment
|
94
105
|
|
95
106
|
private
|
@@ -146,25 +157,29 @@ module ActiveMerchant #:nodoc:
|
|
146
157
|
# Successful payment
|
147
158
|
reply=parse_purchase(root)
|
148
159
|
else
|
149
|
-
if root = REXML::XPath.first(xml, '//
|
150
|
-
reply
|
151
|
-
reply[:CreateCustomerResult]=root.text
|
152
|
-
reply[:success]=true
|
160
|
+
if root = REXML::XPath.first(xml, '//QueryCustomerResult') then
|
161
|
+
reply=parse_query_customer(root)
|
153
162
|
else
|
154
|
-
if root = REXML::XPath.first(xml, '//
|
155
|
-
|
156
|
-
|
157
|
-
|
163
|
+
if root = REXML::XPath.first(xml, '//CreateCustomerResult') then
|
164
|
+
reply[:message]='OK'
|
165
|
+
reply[:CreateCustomerResult]=root.text
|
166
|
+
reply[:success]=true
|
167
|
+
else
|
168
|
+
if root = REXML::XPath.first(xml, '//UpdateCustomerResult') then
|
169
|
+
if root.text.downcase == 'true' then
|
170
|
+
reply[:message]='OK'
|
171
|
+
reply[:success]=true
|
172
|
+
else
|
173
|
+
# ERROR: This state should never occur. If there is a problem,
|
174
|
+
# a soap:Fault will be returned. The presence of this
|
175
|
+
# element always means a success.
|
176
|
+
raise StandardError, "Unexpected \"false\" in UpdateCustomerResult"
|
177
|
+
end
|
158
178
|
else
|
159
|
-
# ERROR: This state should never occur.
|
160
|
-
#
|
161
|
-
|
162
|
-
raise StandardError, "Unexpected \"false\" in UpdateCustomerResult"
|
179
|
+
# ERROR: This state should never occur currently. We have handled
|
180
|
+
# responses for all the methods which we support.
|
181
|
+
raise StandardError, "Unexpected response"
|
163
182
|
end
|
164
|
-
else
|
165
|
-
# ERROR: This state should never occur currently. We have handled
|
166
|
-
# responses for all the methods which we support.
|
167
|
-
raise StandardError, "Unexpected response"
|
168
183
|
end
|
169
184
|
end
|
170
185
|
end
|
@@ -188,6 +203,17 @@ module ActiveMerchant #:nodoc:
|
|
188
203
|
reply
|
189
204
|
end
|
190
205
|
|
206
|
+
def parse_query_customer(node)
|
207
|
+
reply={}
|
208
|
+
reply[:message]='OK'
|
209
|
+
reply[:success]=true
|
210
|
+
reply[:CCNumber]=REXML::XPath.first(node, '//CCNumber').text
|
211
|
+
reply[:CCName]=REXML::XPath.first(node, '//CCName').text
|
212
|
+
reply[:CCExpiryMonth]=REXML::XPath.first(node, '//CCExpiryMonth').text
|
213
|
+
reply[:CCExpiryYear]=REXML::XPath.first(node, '//CCExpiryYear').text
|
214
|
+
reply
|
215
|
+
end
|
216
|
+
|
191
217
|
def commit(action, post)
|
192
218
|
raw = begin
|
193
219
|
ssl_post(test? ? self.test_url : self.live_url, soap_request(post, action), 'Content-Type' => 'application/soap+xml; charset=utf-8')
|
@@ -206,11 +232,15 @@ module ActiveMerchant #:nodoc:
|
|
206
232
|
def soap_request(arguments, action)
|
207
233
|
# eWay demands all fields be sent, but contain an empty string if blank
|
208
234
|
post = case action
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
235
|
+
when 'QueryCustomer'
|
236
|
+
arguments
|
237
|
+
when 'ProcessPayment'
|
238
|
+
default_payment_fields.merge(arguments)
|
239
|
+
when 'CreateCustomer'
|
240
|
+
default_customer_fields.merge(arguments)
|
241
|
+
when 'UpdateCustomer'
|
242
|
+
default_customer_fields.merge(arguments)
|
243
|
+
end
|
214
244
|
|
215
245
|
xml = Builder::XmlMarkup.new :indent => 2
|
216
246
|
xml.instruct!
|
@@ -0,0 +1,222 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class FirstdataE4Gateway < Gateway
|
4
|
+
self.test_url = "https://api.demo.globalgatewaye4.firstdata.com/transaction"
|
5
|
+
self.live_url = "https://api.globalgatewaye4.firstdata.com/transaction"
|
6
|
+
|
7
|
+
TRANSACTIONS = {
|
8
|
+
:sale => "00",
|
9
|
+
:authorization => "01",
|
10
|
+
:capture => "32",
|
11
|
+
:void => "33",
|
12
|
+
:credit => "34"
|
13
|
+
}
|
14
|
+
|
15
|
+
POST_HEADERS = {
|
16
|
+
"Accepts" => "application/xml",
|
17
|
+
"Content-Type" => "application/xml"
|
18
|
+
}
|
19
|
+
|
20
|
+
SUCCESS = "true"
|
21
|
+
|
22
|
+
SENSITIVE_FIELDS = [:verification_str2, :expiry_date, :card_number]
|
23
|
+
|
24
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
|
25
|
+
self.supported_countries = ["CA", "US"]
|
26
|
+
self.default_currency = "USD"
|
27
|
+
self.homepage_url = "http://www.firstdata.com"
|
28
|
+
self.display_name = "FirstData Global Gateway e4"
|
29
|
+
|
30
|
+
def initialize(options = {})
|
31
|
+
requires!(options, :login, :password)
|
32
|
+
@options = options
|
33
|
+
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def authorize(money, credit_card, options = {})
|
38
|
+
commit(:authorization, build_sale_or_authorization_request(money, credit_card, options))
|
39
|
+
end
|
40
|
+
|
41
|
+
def purchase(money, credit_card, options = {})
|
42
|
+
commit(:sale, build_sale_or_authorization_request(money, credit_card, options))
|
43
|
+
end
|
44
|
+
|
45
|
+
def capture(money, authorization, options = {})
|
46
|
+
commit(:capture, build_capture_or_credit_request(money, authorization, options))
|
47
|
+
end
|
48
|
+
|
49
|
+
def void(authorization, options = {})
|
50
|
+
commit(:void, build_capture_or_credit_request(money_from_authorization(authorization), authorization, options))
|
51
|
+
end
|
52
|
+
|
53
|
+
def refund(money, authorization, options = {})
|
54
|
+
commit(:credit, build_capture_or_credit_request(money, authorization, options))
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def build_request(action, body)
|
60
|
+
xml = Builder::XmlMarkup.new
|
61
|
+
|
62
|
+
xml.instruct!
|
63
|
+
xml.tag! "Transaction" do
|
64
|
+
add_credentials(xml)
|
65
|
+
add_transaction_type(xml, action)
|
66
|
+
xml << body
|
67
|
+
end
|
68
|
+
|
69
|
+
xml.target!
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_sale_or_authorization_request(money, credit_card, options)
|
73
|
+
xml = Builder::XmlMarkup.new
|
74
|
+
|
75
|
+
add_amount(xml, money)
|
76
|
+
add_credit_card(xml, credit_card)
|
77
|
+
add_customer_data(xml, options)
|
78
|
+
add_invoice(xml, options)
|
79
|
+
|
80
|
+
xml.target!
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_capture_or_credit_request(money, identification, options)
|
84
|
+
xml = Builder::XmlMarkup.new
|
85
|
+
|
86
|
+
add_identification(xml, identification)
|
87
|
+
add_amount(xml, money)
|
88
|
+
add_customer_data(xml, options)
|
89
|
+
|
90
|
+
xml.target!
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_credentials(xml)
|
94
|
+
xml.tag! "ExactID", @options[:login]
|
95
|
+
xml.tag! "Password", @options[:password]
|
96
|
+
end
|
97
|
+
|
98
|
+
def add_transaction_type(xml, action)
|
99
|
+
xml.tag! "Transaction_Type", TRANSACTIONS[action]
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_identification(xml, identification)
|
103
|
+
authorization_num, transaction_tag, _ = identification.split(";")
|
104
|
+
|
105
|
+
xml.tag! "Authorization_Num", authorization_num
|
106
|
+
xml.tag! "Transaction_Tag", transaction_tag
|
107
|
+
end
|
108
|
+
|
109
|
+
def add_amount(xml, money)
|
110
|
+
xml.tag! "DollarAmount", amount(money)
|
111
|
+
end
|
112
|
+
|
113
|
+
def add_credit_card(xml, credit_card)
|
114
|
+
xml.tag! "Card_Number", credit_card.number
|
115
|
+
xml.tag! "Expiry_Date", expdate(credit_card)
|
116
|
+
xml.tag! "CardHoldersName", credit_card.name
|
117
|
+
xml.tag! "CardType", credit_card.brand
|
118
|
+
|
119
|
+
if credit_card.verification_value?
|
120
|
+
xml.tag! "CVD_Presence_Ind", "1"
|
121
|
+
xml.tag! "VerificationStr2", credit_card.verification_value
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def add_customer_data(xml, options)
|
126
|
+
xml.tag! "Customer_Ref", options[:customer] if options[:customer]
|
127
|
+
xml.tag! "Client_IP", options[:ip] if options[:ip]
|
128
|
+
xml.tag! "Client_Email", options[:email] if options[:email]
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_address(xml, options)
|
132
|
+
if address = (options[:billing_address] || options[:address])
|
133
|
+
xml.tag! "ZipCode", address[:zip]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def add_invoice(xml, options)
|
138
|
+
xml.tag! "Reference_No", options[:order_id]
|
139
|
+
xml.tag! "Reference_3", options[:description] if options[:description]
|
140
|
+
end
|
141
|
+
|
142
|
+
def expdate(credit_card)
|
143
|
+
"#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
|
144
|
+
end
|
145
|
+
|
146
|
+
def commit(action, request)
|
147
|
+
url = (test? ? self.test_url : self.live_url)
|
148
|
+
begin
|
149
|
+
response = parse(ssl_post(url, build_request(action, request), POST_HEADERS))
|
150
|
+
rescue ResponseError => e
|
151
|
+
response = parse_error(e.response)
|
152
|
+
end
|
153
|
+
|
154
|
+
Response.new(successful?(response), message_from(response), response,
|
155
|
+
:test => test?,
|
156
|
+
:authorization => authorization_from(response),
|
157
|
+
:avs_result => {:code => response[:avs]},
|
158
|
+
:cvv_result => response[:cvv2]
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
def successful?(response)
|
163
|
+
response[:transaction_approved] == SUCCESS
|
164
|
+
end
|
165
|
+
|
166
|
+
def authorization_from(response)
|
167
|
+
if response[:authorization_num] && response[:transaction_tag]
|
168
|
+
[
|
169
|
+
response[:authorization_num],
|
170
|
+
response[:transaction_tag],
|
171
|
+
(response[:dollar_amount].to_f * 100).to_i
|
172
|
+
].join(";")
|
173
|
+
else
|
174
|
+
""
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def money_from_authorization(auth)
|
179
|
+
_, _, amount = auth.split(/;/, 3)
|
180
|
+
amount.to_i # return the # of cents, no need to divide
|
181
|
+
end
|
182
|
+
|
183
|
+
def message_from(response)
|
184
|
+
if(response[:faultcode] && response[:faultstring])
|
185
|
+
response[:faultstring]
|
186
|
+
elsif(response[:error_number] != "0")
|
187
|
+
response[:error_description]
|
188
|
+
else
|
189
|
+
result = (response[:exact_message] || "")
|
190
|
+
result << " - #{response[:bank_message]}" if response[:bank_message].present?
|
191
|
+
result
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def parse_error(error)
|
196
|
+
{
|
197
|
+
:transaction_approved => "false",
|
198
|
+
:error_number => error.code,
|
199
|
+
:error_description => error.body
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
def parse(xml)
|
204
|
+
response = {}
|
205
|
+
xml = REXML::Document.new(xml)
|
206
|
+
|
207
|
+
if root = REXML::XPath.first(xml, "//TransactionResult")
|
208
|
+
parse_elements(response, root)
|
209
|
+
end
|
210
|
+
|
211
|
+
response.delete_if{ |k,v| SENSITIVE_FIELDS.include?(k) }
|
212
|
+
end
|
213
|
+
|
214
|
+
def parse_elements(response, root)
|
215
|
+
root.elements.to_a.each do |node|
|
216
|
+
response[node.name.gsub(/EXact/, "Exact").underscore.to_sym] = (node.text || "").strip
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
@@ -9,12 +9,23 @@ module ActiveMerchant #:nodoc:
|
|
9
9
|
#
|
10
10
|
# ActiveMerchant expects the amounts to be given as an Integer in cents. In this case, 10 EUR becomes 1000.
|
11
11
|
#
|
12
|
+
# Create certificates for authentication:
|
13
|
+
#
|
14
|
+
# The PEM file expected should contain both the certificate and the generated PEM file.
|
15
|
+
# Some sample shell commands to generate the certificates:
|
16
|
+
#
|
17
|
+
# openssl genrsa -aes128 -out priv.pem -passout pass:[YOUR PASSWORD] 1024
|
18
|
+
# openssl req -x509 -new -key priv.pem -passin pass:[YOUR PASSWORD] -days 3000 -out cert.cer
|
19
|
+
# cat cert.cer priv.pem > ideal.pem
|
20
|
+
#
|
21
|
+
# Following the steps above, upload cert.cer to the ideal web interface and pass the path of ideal.pem to the :pem option.
|
22
|
+
#
|
12
23
|
# Configure the gateway using your iDEAL bank account info and security settings:
|
13
24
|
#
|
14
25
|
# Create gateway:
|
15
26
|
# gateway = ActiveMerchant::Billing::IdealRabobankGateway.new(
|
16
|
-
# :login => '123456789', # merchant number
|
17
|
-
# :pem => File.read(
|
27
|
+
# :login => '123456789', # 9 digit merchant number
|
28
|
+
# :pem => File.read(Rails.root + 'config/ideal.pem'),
|
18
29
|
# :password => 'password' # password for the PEM key
|
19
30
|
# )
|
20
31
|
#
|
@@ -71,13 +71,13 @@ module ActiveMerchant #:nodoc:
|
|
71
71
|
super
|
72
72
|
end
|
73
73
|
|
74
|
-
def authorize(money,
|
75
|
-
to_pass =
|
74
|
+
def authorize(money, creditcard_or_token, options = {})
|
75
|
+
to_pass = build_authorize_request(money, creditcard_or_token, options)
|
76
76
|
build_response(:authorization, @litle.authorization(to_pass))
|
77
77
|
end
|
78
78
|
|
79
|
-
def purchase(money,
|
80
|
-
to_pass =
|
79
|
+
def purchase(money, creditcard_or_token, options = {})
|
80
|
+
to_pass = build_purchase_request(money, creditcard_or_token, options)
|
81
81
|
build_response(:sale, @litle.sale(to_pass))
|
82
82
|
end
|
83
83
|
|
@@ -98,7 +98,7 @@ module ActiveMerchant #:nodoc:
|
|
98
98
|
|
99
99
|
def store(creditcard, options = {})
|
100
100
|
to_pass = create_token_hash(creditcard, options)
|
101
|
-
build_response(:registerToken, @litle.register_token_request(to_pass), %w(801 802))
|
101
|
+
build_response(:registerToken, @litle.register_token_request(to_pass), %w(000 801 802))
|
102
102
|
end
|
103
103
|
|
104
104
|
private
|
@@ -142,11 +142,17 @@ module ActiveMerchant #:nodoc:
|
|
142
142
|
if response['response'] == "0"
|
143
143
|
detail = response["#{kind}Response"]
|
144
144
|
fraud = fraud_result(detail)
|
145
|
+
authorization = case kind
|
146
|
+
when :registerToken
|
147
|
+
response['registerTokenResponse']['litleToken']
|
148
|
+
else
|
149
|
+
detail['litleTxnId']
|
150
|
+
end
|
145
151
|
Response.new(
|
146
152
|
valid_responses.include?(detail['response']),
|
147
153
|
detail['message'],
|
148
154
|
{:litleOnlineResponse => response},
|
149
|
-
:authorization =>
|
155
|
+
:authorization => authorization,
|
150
156
|
:avs_result => {:code => fraud['avs']},
|
151
157
|
:cvv_result => fraud['cvv'],
|
152
158
|
:test => test?
|
@@ -156,27 +162,52 @@ module ActiveMerchant #:nodoc:
|
|
156
162
|
end
|
157
163
|
end
|
158
164
|
|
159
|
-
def
|
160
|
-
|
165
|
+
def build_authorize_request(money, creditcard_or_token, options)
|
166
|
+
hash = create_hash(money, options)
|
167
|
+
|
168
|
+
add_credit_card_or_token_hash(hash, creditcard_or_token)
|
169
|
+
|
170
|
+
hash
|
171
|
+
end
|
172
|
+
|
173
|
+
def build_purchase_request(money, creditcard_or_token, options)
|
174
|
+
hash = create_hash(money, options)
|
175
|
+
|
176
|
+
add_credit_card_or_token_hash(hash, creditcard_or_token)
|
161
177
|
|
162
|
-
|
178
|
+
hash
|
179
|
+
end
|
163
180
|
|
164
|
-
|
165
|
-
|
181
|
+
def add_credit_card_or_token_hash(hash, creditcard_or_token)
|
182
|
+
if creditcard_or_token.is_a?(String)
|
183
|
+
add_token_hash(hash, creditcard_or_token)
|
166
184
|
else
|
167
|
-
|
185
|
+
add_credit_card_hash(hash, creditcard_or_token)
|
168
186
|
end
|
187
|
+
end
|
169
188
|
|
170
|
-
|
189
|
+
def add_token_hash(hash, creditcard_or_token)
|
190
|
+
token_info = {
|
191
|
+
'litleToken' => creditcard_or_token
|
192
|
+
}
|
193
|
+
|
194
|
+
hash['token'] = token_info
|
195
|
+
hash
|
196
|
+
end
|
197
|
+
|
198
|
+
def add_credit_card_hash(hash, creditcard)
|
199
|
+
cc_type = CARD_TYPE[creditcard.brand]
|
200
|
+
exp_date_yr = creditcard.year.to_s[2..3]
|
201
|
+
exp_date_mo = '%02d' % creditcard.month.to_i
|
202
|
+
exp_date = exp_date_mo + exp_date_yr
|
171
203
|
|
172
204
|
card_info = {
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
205
|
+
'type' => cc_type,
|
206
|
+
'number' => creditcard.number,
|
207
|
+
'expDate' => exp_date,
|
208
|
+
'cardValidationNum' => creditcard.verification_value
|
177
209
|
}
|
178
210
|
|
179
|
-
hash = create_hash(money, options)
|
180
211
|
hash['card'] = card_info
|
181
212
|
hash
|
182
213
|
end
|
@@ -258,7 +289,7 @@ module ActiveMerchant #:nodoc:
|
|
258
289
|
'customerId' => options[:customer],
|
259
290
|
'reportGroup' => (options[:merchant] || @options[:merchant]),
|
260
291
|
'merchantId' => (options[:merchant_id] || @options[:merchant_id]),
|
261
|
-
'orderSource' => 'ecommerce',
|
292
|
+
'orderSource' => (options[:order_source] || 'ecommerce'),
|
262
293
|
'enhancedData' => enhanced_data,
|
263
294
|
'fraudCheckType' => fraud_check_type,
|
264
295
|
'user' => (options[:user] || @options[:user]),
|