yetanothernguyen-activemerchant 1.16.0 → 1.21.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 +95 -0
- data/CONTRIBUTORS +29 -0
- data/lib/active_merchant/billing/credit_card.rb +105 -19
- data/lib/active_merchant/billing/credit_card_methods.rb +5 -1
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +24 -2
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +104 -18
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +110 -4
- data/lib/active_merchant/billing/gateways/beanstream.rb +29 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +9 -4
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +4 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +279 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +9 -9
- data/lib/active_merchant/billing/gateways/elavon.rb +2 -1
- data/lib/active_merchant/billing/gateways/epay.rb +12 -6
- data/lib/active_merchant/billing/gateways/eway_managed.rb +46 -12
- data/lib/active_merchant/billing/gateways/exact.rb +5 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +3 -3
- data/lib/active_merchant/billing/gateways/ipay88.rb +157 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +3 -3
- data/lib/active_merchant/billing/gateways/itransact.rb +450 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +1 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +4 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +244 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +94 -56
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +57 -34
- data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -1
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +2 -2
- data/lib/active_merchant/billing/gateways/payflow.rb +10 -2
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +8 -5
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +43 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +93 -40
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +8 -3
- data/lib/active_merchant/billing/gateways/qbms.rb +4 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +97 -22
- data/lib/active_merchant/billing/gateways/realex.rb +5 -1
- data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +136 -49
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +1 -1
- data/lib/active_merchant/billing/gateways/skip_jack.rb +7 -2
- data/lib/active_merchant/billing/gateways/stripe.rb +51 -19
- data/lib/active_merchant/billing/gateways/usa_epay.rb +13 -184
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +206 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +2 -2
- data/lib/active_merchant/billing/gateways/viaklix.rb +1 -1
- data/lib/active_merchant/billing/gateways/worldpay.rb +1 -1
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +6 -2
- data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +4 -4
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
- data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
- data/lib/active_merchant/billing/integrations/helper.rb +19 -2
- data/lib/active_merchant/billing/integrations/ipay88/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/ipay88/return.rb +121 -0
- data/lib/active_merchant/billing/integrations/ipay88.rb +40 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +1 -1
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
- data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +4 -4
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +18 -2
- data/lib/active_merchant/billing/integrations/two_checkout.rb +1 -2
- data/lib/active_merchant/railtie.rb +7 -7
- data/lib/active_merchant/railtie.rb.orig +19 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/active_merchant.rb +23 -10
- data/lib/active_merchant.rb.orig +78 -0
- metadata +147 -63
- data/lib/active_merchant/common/connection.rb +0 -177
- data/lib/active_merchant/common/country.rb +0 -328
- data/lib/active_merchant/common/error.rb +0 -26
- data/lib/active_merchant/common/post_data.rb +0 -24
- data/lib/active_merchant/common/posts_data.rb +0 -63
- data/lib/active_merchant/common/requires_parameters.rb +0 -16
- data/lib/active_merchant/common/utils.rb +0 -22
- data/lib/active_merchant/common/validateable.rb +0 -81
- data/lib/active_merchant/common.rb +0 -14
- data/lib/certs/cacert.pem +0 -7815
@@ -41,6 +41,12 @@ module ActiveMerchant #:nodoc:
|
|
41
41
|
commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
|
42
42
|
end
|
43
43
|
|
44
|
+
def reference_transaction(money, options = {})
|
45
|
+
requires!(options, :reference_id, :payment_type, :invoice_id, :description, :ip)
|
46
|
+
|
47
|
+
commit 'DoReferenceTransaction', build_reference_transaction_request('Sale', money, options)
|
48
|
+
end
|
49
|
+
|
44
50
|
private
|
45
51
|
def build_get_details_request(token)
|
46
52
|
xml = Builder::XmlMarkup.new :indent => 2
|
@@ -80,6 +86,8 @@ module ActiveMerchant #:nodoc:
|
|
80
86
|
xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
|
81
87
|
xml.tag! 'n2:InvoiceID', options[:order_id]
|
82
88
|
xml.tag! 'n2:OrderDescription', options[:description]
|
89
|
+
|
90
|
+
add_items_xml(xml, options, currency_code) if options[:items]
|
83
91
|
end
|
84
92
|
end
|
85
93
|
end
|
@@ -96,12 +104,40 @@ module ActiveMerchant #:nodoc:
|
|
96
104
|
xml.tag! 'SetExpressCheckoutRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
97
105
|
xml.tag! 'n2:Version', API_VERSION
|
98
106
|
xml.tag! 'n2:SetExpressCheckoutRequestDetails' do
|
107
|
+
xml.tag! 'n2:ReturnURL', options[:return_url]
|
108
|
+
xml.tag! 'n2:CancelURL', options[:cancel_return_url]
|
99
109
|
if options[:max_amount]
|
100
110
|
xml.tag! 'n2:MaxAmount', localized_amount(options[:max_amount], currency_code), 'currencyID' => currency_code
|
101
111
|
end
|
112
|
+
xml.tag! 'n2:NoShipping', options[:no_shipping] ? '1' : '0'
|
113
|
+
xml.tag! 'n2:AddressOverride', options[:address_override] ? '1' : '0'
|
114
|
+
xml.tag! 'n2:LocaleCode', options[:locale] unless options[:locale].blank?
|
115
|
+
xml.tag! 'n2:BrandName', options[:brand_name] unless options[:brand_name].blank?
|
116
|
+
# Customization of the payment page
|
117
|
+
xml.tag! 'n2:PageStyle', options[:page_style] unless options[:page_style].blank?
|
118
|
+
xml.tag! 'n2:cpp-header-image', options[:header_image] unless options[:header_image].blank?
|
119
|
+
xml.tag! 'n2:cpp-header-border-color', options[:header_border_color] unless options[:header_border_color].blank?
|
120
|
+
xml.tag! 'n2:cpp-header-back-color', options[:header_background_color] unless options[:header_background_color].blank?
|
121
|
+
xml.tag! 'n2:cpp-payflow-color', options[:background_color] unless options[:background_color].blank?
|
122
|
+
if options[:allow_guest_checkout]
|
123
|
+
xml.tag! 'n2:SolutionType', 'Sole'
|
124
|
+
xml.tag! 'n2:LandingPage', 'Billing'
|
125
|
+
end
|
126
|
+
xml.tag! 'n2:BuyerEmail', options[:email] unless options[:email].blank?
|
127
|
+
|
128
|
+
if options[:billing_agreement]
|
129
|
+
xml.tag! 'n2:BillingAgreementDetails' do
|
130
|
+
xml.tag! 'n2:BillingType', options[:billing_agreement][:type]
|
131
|
+
xml.tag! 'n2:BillingAgreementDescription', options[:billing_agreement][:description]
|
132
|
+
xml.tag! 'n2:PaymentType', options[:billing_agreement][:payment_type] || 'InstantOnly'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
102
136
|
if !options[:allow_note].nil?
|
103
137
|
xml.tag! 'n2:AllowNote', options[:allow_note] ? '1' : '0'
|
104
138
|
end
|
139
|
+
xml.tag! 'n2:CallbackURL', options[:callback_url] unless options[:callback_url].blank?
|
140
|
+
|
105
141
|
xml.tag! 'n2:PaymentDetails' do
|
106
142
|
xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? localized_amount(100, currency_code) : localized_amount(money, currency_code), 'currencyID' => currency_code
|
107
143
|
# All of the values must be included together and add up to the order total
|
@@ -115,53 +151,26 @@ module ActiveMerchant #:nodoc:
|
|
115
151
|
xml.tag! 'n2:OrderDescription', options[:description]
|
116
152
|
xml.tag! 'n2:InvoiceID', options[:order_id]
|
117
153
|
|
118
|
-
if options[:items]
|
119
|
-
options[:items].each do |item|
|
120
|
-
xml.tag! 'n2:PaymentDetailsItem' do
|
121
|
-
xml.tag! 'n2:Name', item[:name]
|
122
|
-
xml.tag! 'n2:Number', item[:number]
|
123
|
-
xml.tag! 'n2:Quantity', item[:quantity]
|
124
|
-
if item[:amount]
|
125
|
-
xml.tag! 'n2:Amount', localized_amount(item[:amount], currency_code), 'currencyID' => currency_code
|
126
|
-
end
|
127
|
-
xml.tag! 'n2:Description', item[:description]
|
128
|
-
xml.tag! 'n2:ItemURL', item[:url]
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
154
|
add_address(xml, 'n2:ShipToAddress', options[:shipping_address] || options[:address])
|
133
155
|
|
156
|
+
add_items_xml(xml, options, currency_code) if options[:items]
|
157
|
+
|
134
158
|
xml.tag! 'n2:PaymentAction', action
|
159
|
+
xml.tag! 'n2:Custom', options[:custom] unless options[:custom].blank?
|
135
160
|
end
|
136
161
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
if options[:billing_agreement]
|
145
|
-
xml.tag! 'n2:BillingAgreementDetails' do
|
146
|
-
xml.tag! 'n2:BillingType', options[:billing_agreement][:type]
|
147
|
-
xml.tag! 'n2:BillingAgreementDescription', options[:billing_agreement][:description]
|
148
|
-
xml.tag! 'n2:PaymentType', options[:billing_agreement][:payment_type] || 'InstantOnly'
|
162
|
+
if options[:shipping_options]
|
163
|
+
options[:shipping_options].each do |shipping_option|
|
164
|
+
xml.tag! 'n2:FlatRateShippingOptions' do
|
165
|
+
xml.tag! 'n2:ShippingOptionIsDefault', shipping_option[:default]
|
166
|
+
xml.tag! 'n2:ShippingOptionAmount', localized_amount(shipping_option[:amount], currency_code), 'currencyID' => currency_code
|
167
|
+
xml.tag! 'n2:ShippingOptionName', shipping_option[:name]
|
168
|
+
end
|
149
169
|
end
|
150
170
|
end
|
151
|
-
|
152
|
-
|
153
|
-
xml.tag! 'n2:
|
154
|
-
xml.tag! 'n2:cpp-header-image', options[:header_image] unless options[:header_image].blank?
|
155
|
-
xml.tag! 'n2:cpp-header-back-color', options[:header_background_color] unless options[:header_background_color].blank?
|
156
|
-
xml.tag! 'n2:cpp-header-border-color', options[:header_border_color] unless options[:header_border_color].blank?
|
157
|
-
xml.tag! 'n2:cpp-payflow-color', options[:background_color] unless options[:background_color].blank?
|
158
|
-
|
159
|
-
if options[:allow_guest_checkout]
|
160
|
-
xml.tag! 'n2:SolutionType', 'Sole'
|
161
|
-
xml.tag! 'n2:LandingPage', 'Billing'
|
162
|
-
end
|
163
|
-
|
164
|
-
xml.tag! 'n2:LocaleCode', options[:locale] unless options[:locale].blank?
|
171
|
+
|
172
|
+
xml.tag! 'n2:CallbackTimeout', options[:callback_timeout] unless options[:callback_timeout].blank?
|
173
|
+
xml.tag! 'n2:CallbackVersion', options[:callback_version] unless options[:callback_version].blank?
|
165
174
|
end
|
166
175
|
end
|
167
176
|
end
|
@@ -169,9 +178,53 @@ module ActiveMerchant #:nodoc:
|
|
169
178
|
xml.target!
|
170
179
|
end
|
171
180
|
|
181
|
+
def build_reference_transaction_request(action, money, options)
|
182
|
+
currency_code = options[:currency] || currency(money)
|
183
|
+
|
184
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
185
|
+
xml.tag! 'DoReferenceTransactionReq', 'xmlns' => PAYPAL_NAMESPACE do
|
186
|
+
xml.tag! 'DoReferenceTransactionRequest', 'xmlns:n2' => EBAY_NAMESPACE do
|
187
|
+
xml.tag! 'n2:Version', API_VERSION
|
188
|
+
xml.tag! 'n2:DoReferenceTransactionRequestDetails' do
|
189
|
+
xml.tag! 'n2:ReferenceID', options[:reference_id]
|
190
|
+
xml.tag! 'n2:PaymentAction', action
|
191
|
+
xml.tag! 'n2:PaymentType', options[:payment_type] || 'Any'
|
192
|
+
xml.tag! 'n2:PaymentDetails' do
|
193
|
+
xml.tag! 'n2:OrderTotal', amount(money).to_f.zero? ? localized_amount(100, currency_code) : localized_amount(money, currency_code), 'currencyID' => currency_code
|
194
|
+
xml.tag! 'n2:OrderDescription', options[:description]
|
195
|
+
xml.tag! 'n2:InvoiceID', options[:invoice_id]
|
196
|
+
xml.tag! 'n2:ButtonSource', 'ActiveMerchant'
|
197
|
+
xml.tag! 'n2:NotifyURL', ''
|
198
|
+
end
|
199
|
+
xml.tag! 'n2:IPAddress', options[:ip]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
xml.target!
|
205
|
+
end
|
206
|
+
|
172
207
|
def build_response(success, message, response, options = {})
|
173
208
|
PaypalExpressResponse.new(success, message, response, options)
|
174
209
|
end
|
210
|
+
|
211
|
+
private
|
212
|
+
|
213
|
+
def add_items_xml(xml, options, currency_code)
|
214
|
+
options[:items].each do |item|
|
215
|
+
xml.tag! 'n2:PaymentDetailsItem' do
|
216
|
+
xml.tag! 'n2:Name', item[:name]
|
217
|
+
xml.tag! 'n2:Number', item[:number]
|
218
|
+
xml.tag! 'n2:Quantity', item[:quantity]
|
219
|
+
if item[:amount]
|
220
|
+
xml.tag! 'n2:Amount', localized_amount(item[:amount], currency_code), 'currencyID' => currency_code
|
221
|
+
end
|
222
|
+
xml.tag! 'n2:Description', item[:description]
|
223
|
+
xml.tag! 'n2:ItemURL', item[:url]
|
224
|
+
xml.tag! 'n2:ItemCategory', item[:category] if item[:category]
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
175
228
|
end
|
176
229
|
end
|
177
230
|
end
|
@@ -2,8 +2,13 @@ module ActiveMerchant
|
|
2
2
|
module Billing
|
3
3
|
module PaypalExpressCommon
|
4
4
|
def self.included(base)
|
5
|
-
base.
|
6
|
-
|
5
|
+
if base.respond_to?(:class_attribute)
|
6
|
+
base.class_attribute :test_redirect_url
|
7
|
+
base.class_attribute :live_redirect_url
|
8
|
+
else
|
9
|
+
base.class_inheritable_accessor :test_redirect_url
|
10
|
+
base.class_inheritable_accessor :live_redirect_url
|
11
|
+
end
|
7
12
|
base.live_redirect_url = 'https://www.paypal.com/cgibin/webscr'
|
8
13
|
end
|
9
14
|
|
@@ -22,4 +27,4 @@ module ActiveMerchant
|
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
25
|
-
end
|
30
|
+
end
|
@@ -8,30 +8,91 @@ module ActiveMerchant #:nodoc:
|
|
8
8
|
|
9
9
|
self.default_currency = 'DKK'
|
10
10
|
self.money_format = :cents
|
11
|
-
self.supported_cardtypes = [
|
11
|
+
self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master, :american_express, :diners_club, :jcb, :maestro]
|
12
12
|
self.supported_countries = ['DK', 'SE']
|
13
13
|
self.homepage_url = 'http://quickpay.dk/'
|
14
14
|
self.display_name = 'Quickpay'
|
15
15
|
|
16
|
-
PROTOCOL = 3
|
17
|
-
|
18
16
|
MD5_CHECK_FIELDS = {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
3 => {
|
18
|
+
:authorize => %w(protocol msgtype merchant ordernumber amount
|
19
|
+
currency autocapture cardnumber expirationdate
|
20
|
+
cvd cardtypelock testmode),
|
21
|
+
|
22
|
+
:capture => %w(protocol msgtype merchant amount transaction),
|
23
|
+
|
24
|
+
:cancel => %w(protocol msgtype merchant transaction),
|
25
|
+
|
26
|
+
:refund => %w(protocol msgtype merchant amount transaction),
|
27
|
+
|
28
|
+
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
29
|
+
expirationdate cvd cardtypelock description testmode),
|
30
|
+
|
31
|
+
:recurring => %w(protocol msgtype merchant ordernumber amount
|
32
|
+
currency autocapture transaction),
|
33
|
+
|
34
|
+
:status => %w(protocol msgtype merchant transaction),
|
35
|
+
|
36
|
+
:chstatus => %w(protocol msgtype merchant)
|
37
|
+
},
|
38
|
+
|
39
|
+
4 => {
|
40
|
+
:authorize => %w(protocol msgtype merchant ordernumber amount
|
41
|
+
currency autocapture cardnumber expirationdate cvd
|
42
|
+
cardtypelock testmode fraud_remote_addr
|
43
|
+
fraud_http_accept fraud_http_accept_language
|
44
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
45
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
46
|
+
|
47
|
+
:capture => %w(protocol msgtype merchant amount transaction
|
48
|
+
fraud_remote_addr fraud_http_accept
|
49
|
+
fraud_http_accept_language fraud_http_accept_encoding
|
50
|
+
fraud_http_accept_charset fraud_http_referer
|
51
|
+
fraud_http_user_agent apikey),
|
52
|
+
|
53
|
+
:cancel => %w(protocol msgtype merchant transaction fraud_remote_addr
|
54
|
+
fraud_http_accept fraud_http_accept_language
|
55
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
56
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
57
|
+
|
58
|
+
:refund => %w(protocol msgtype merchant amount transaction
|
59
|
+
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
60
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
61
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
62
|
+
|
63
|
+
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
64
|
+
expirationdate cvd cardtypelock description testmode
|
65
|
+
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
66
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
67
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
68
|
+
|
69
|
+
:recurring => %w(protocol msgtype merchant ordernumber amount currency
|
70
|
+
autocapture transaction fraud_remote_addr fraud_http_accept
|
71
|
+
fraud_http_accept_language fraud_http_accept_encoding
|
72
|
+
fraud_http_accept_charset fraud_http_referer
|
73
|
+
fraud_http_user_agent apikey),
|
74
|
+
|
75
|
+
:status => %w(protocol msgtype merchant transaction fraud_remote_addr
|
76
|
+
fraud_http_accept fraud_http_accept_language
|
77
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
78
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
79
|
+
|
80
|
+
:chstatus => %w(protocol msgtype merchant fraud_remote_addr fraud_http_accept
|
81
|
+
fraud_http_accept_language fraud_http_accept_encoding
|
82
|
+
fraud_http_accept_charset fraud_http_referer
|
83
|
+
fraud_http_user_agent apikey)
|
84
|
+
}
|
27
85
|
}
|
28
86
|
|
29
87
|
APPROVED = '000'
|
30
88
|
|
31
89
|
# The login is the QuickpayId
|
32
|
-
# The password is the md5checkword from the Quickpay
|
90
|
+
# The password is the md5checkword from the Quickpay manager
|
91
|
+
# To use the API-key from the Quickpay manager, specify :api-key
|
92
|
+
# Using the API-key, requires that you use version 4. Specify :version => 4 in options.
|
33
93
|
def initialize(options = {})
|
34
94
|
requires!(options, :login, :password)
|
95
|
+
@protocol = options.delete(:version) || 3 # default to protocol version 3
|
35
96
|
@options = options
|
36
97
|
super
|
37
98
|
end
|
@@ -43,6 +104,7 @@ module ActiveMerchant #:nodoc:
|
|
43
104
|
add_invoice(post, options)
|
44
105
|
add_creditcard_or_reference(post, credit_card_or_reference, options)
|
45
106
|
add_autocapture(post, false)
|
107
|
+
add_fraud_parameters(post, options)
|
46
108
|
add_testmode(post)
|
47
109
|
|
48
110
|
commit(recurring_or_authorize(credit_card_or_reference), post)
|
@@ -54,6 +116,7 @@ module ActiveMerchant #:nodoc:
|
|
54
116
|
add_amount(post, money, options)
|
55
117
|
add_creditcard_or_reference(post, credit_card_or_reference, options)
|
56
118
|
add_invoice(post, options)
|
119
|
+
add_fraud_parameters(post, options)
|
57
120
|
add_autocapture(post, true)
|
58
121
|
|
59
122
|
commit(recurring_or_authorize(credit_card_or_reference), post)
|
@@ -64,6 +127,7 @@ module ActiveMerchant #:nodoc:
|
|
64
127
|
|
65
128
|
add_reference(post, authorization)
|
66
129
|
add_amount_without_currency(post, money)
|
130
|
+
add_fraud_parameters(post, options)
|
67
131
|
|
68
132
|
commit(:capture, post)
|
69
133
|
end
|
@@ -72,6 +136,7 @@ module ActiveMerchant #:nodoc:
|
|
72
136
|
post = {}
|
73
137
|
|
74
138
|
add_reference(post, identification)
|
139
|
+
add_fraud_parameters(post, options)
|
75
140
|
|
76
141
|
commit(:cancel, post)
|
77
142
|
end
|
@@ -81,6 +146,7 @@ module ActiveMerchant #:nodoc:
|
|
81
146
|
|
82
147
|
add_amount_without_currency(post, money)
|
83
148
|
add_reference(post, identification)
|
149
|
+
add_fraud_parameters(post, options)
|
84
150
|
|
85
151
|
commit(:refund, post)
|
86
152
|
end
|
@@ -96,6 +162,7 @@ module ActiveMerchant #:nodoc:
|
|
96
162
|
add_creditcard(post, creditcard, options)
|
97
163
|
add_invoice(post, options)
|
98
164
|
add_description(post, options)
|
165
|
+
add_fraud_parameters(post, options)
|
99
166
|
add_testmode(post)
|
100
167
|
|
101
168
|
commit(:subscribe, post)
|
@@ -148,8 +215,21 @@ module ActiveMerchant #:nodoc:
|
|
148
215
|
end
|
149
216
|
|
150
217
|
def add_testmode(post)
|
218
|
+
return if post[:transaction].present?
|
151
219
|
post[:testmode] = test? ? '1' : '0'
|
152
220
|
end
|
221
|
+
|
222
|
+
def add_fraud_parameters(post, options)
|
223
|
+
if @protocol == 4
|
224
|
+
post[:fraud_remote_addr] = options[:fraud_remote_addr] if options[:fraud_remote_addr]
|
225
|
+
post[:fraud_http_accept] = options[:fraud_http_accept] if options[:fraud_http_accept]
|
226
|
+
post[:fraud_http_accept_language] = options[:fraud_http_accept_language] if options[:fraud_http_accept_language]
|
227
|
+
post[:fraud_http_accept_encoding] = options[:fraud_http_accept_encoding] if options[:fraud_http_accept_encoding]
|
228
|
+
post[:fraud_http_accept_charset] = options[:fraud_http_accept_charset] if options[:fraud_http_accept_charset]
|
229
|
+
post[:fraud_http_referer] = options[:fraud_http_referer] if options[:fraud_http_referer]
|
230
|
+
post[:fraud_http_user_agent] = options[:fraud_http_user_agent] if options[:fraud_http_user_agent]
|
231
|
+
end
|
232
|
+
end
|
153
233
|
|
154
234
|
def commit(action, params)
|
155
235
|
response = parse(ssl_post(URL, post_data(action, params)))
|
@@ -177,27 +257,22 @@ module ActiveMerchant #:nodoc:
|
|
177
257
|
end
|
178
258
|
|
179
259
|
def message_from(response)
|
180
|
-
|
181
|
-
when '008' # Error in request data
|
182
|
-
response[:qpstatmsg].to_s
|
183
|
-
#.scan(/[A-Z][a-z0-9 \/]+/).to_sentence
|
184
|
-
else
|
185
|
-
response[:qpstatmsg].to_s
|
186
|
-
end
|
260
|
+
response[:qpstatmsg].to_s
|
187
261
|
end
|
188
262
|
|
189
263
|
def post_data(action, params = {})
|
190
|
-
params[:protocol] =
|
264
|
+
params[:protocol] = @protocol
|
191
265
|
params[:msgtype] = action.to_s
|
192
266
|
params[:merchant] = @options[:login]
|
267
|
+
params[:apikey] = @options[:apikey] if @options[:apikey]
|
193
268
|
params[:md5check] = generate_check_hash(action, params)
|
194
269
|
|
195
270
|
params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
196
271
|
end
|
197
272
|
|
198
273
|
def generate_check_hash(action, params)
|
199
|
-
string = MD5_CHECK_FIELDS[action].collect do |key|
|
200
|
-
params[key]
|
274
|
+
string = MD5_CHECK_FIELDS[@protocol][action].collect do |key|
|
275
|
+
params[key.to_sym]
|
201
276
|
end.join('')
|
202
277
|
|
203
278
|
# Add the md5checkword
|
@@ -197,7 +197,7 @@ module ActiveMerchant
|
|
197
197
|
|
198
198
|
if shipping_address
|
199
199
|
xml.tag! 'address', 'type' => 'shipping' do
|
200
|
-
xml.tag! 'code', shipping_address[:zip]
|
200
|
+
xml.tag! 'code', format_shipping_zip_code(shipping_address[:zip])
|
201
201
|
xml.tag! 'country', shipping_address[:country]
|
202
202
|
end
|
203
203
|
end
|
@@ -247,6 +247,10 @@ module ActiveMerchant
|
|
247
247
|
address.values_at(:zip, :address1).map{ |v| extract_digits(v) }.join('|')
|
248
248
|
end
|
249
249
|
|
250
|
+
def format_shipping_zip_code(zip)
|
251
|
+
zip.to_s.gsub(/\W/, '')
|
252
|
+
end
|
253
|
+
|
250
254
|
def extract_digits(string)
|
251
255
|
return "" if string.nil?
|
252
256
|
string.gsub(/[\D]/,'')
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class SamuraiGateway < Gateway
|
4
|
+
|
5
|
+
self.homepage_url = 'https://samurai.feefighters.com'
|
6
|
+
self.display_name = 'Samurai'
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
|
9
|
+
self.default_currency = 'USD'
|
10
|
+
self.money_format = :dollars
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
begin
|
14
|
+
require 'samurai'
|
15
|
+
rescue LoadError
|
16
|
+
raise "Could not load the samurai gem (>= 0.2.25). Use `gem install samurai` to install it."
|
17
|
+
end
|
18
|
+
|
19
|
+
requires!(options, :login, :password, :processor_token)
|
20
|
+
@options = options
|
21
|
+
Samurai.options = {
|
22
|
+
:merchant_key => options[:login],
|
23
|
+
:merchant_password => options[:password],
|
24
|
+
:processor_token => options[:processor_token]
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def test?
|
29
|
+
@options[:test] || super
|
30
|
+
end
|
31
|
+
|
32
|
+
def authorize(money, credit_card_or_vault_id, options = {})
|
33
|
+
token = payment_method_token(credit_card_or_vault_id, options)
|
34
|
+
return token if token.is_a?(Response)
|
35
|
+
|
36
|
+
authorize = Samurai::Processor.authorize(token, amount(money), processor_options(options))
|
37
|
+
handle_result(authorize)
|
38
|
+
end
|
39
|
+
|
40
|
+
def purchase(money, credit_card_or_vault_id, options = {})
|
41
|
+
token = payment_method_token(credit_card_or_vault_id, options)
|
42
|
+
return token if token.is_a?(Response)
|
43
|
+
|
44
|
+
purchase = Samurai::Processor.purchase(token, amount(money), processor_options(options))
|
45
|
+
handle_result(purchase)
|
46
|
+
end
|
47
|
+
|
48
|
+
def capture(money, authorization_id, options = {})
|
49
|
+
transaction = Samurai::Transaction.find(authorization_id)
|
50
|
+
handle_result(transaction.capture(amount(money)))
|
51
|
+
end
|
52
|
+
|
53
|
+
def refund(money, transaction_id, options = {})
|
54
|
+
transaction = Samurai::Transaction.find(transaction_id)
|
55
|
+
handle_result(transaction.credit(amount(money)))
|
56
|
+
end
|
57
|
+
|
58
|
+
def void(transaction_id, options = {})
|
59
|
+
transaction = Samurai::Transaction.find(transaction_id)
|
60
|
+
handle_result(transaction.void)
|
61
|
+
end
|
62
|
+
|
63
|
+
def store(creditcard, options = {})
|
64
|
+
address = options[:billing_address] || options[:address] || {}
|
65
|
+
|
66
|
+
result = Samurai::PaymentMethod.create({
|
67
|
+
:card_number => creditcard.number,
|
68
|
+
:expiry_month => creditcard.month.to_s.rjust(2, "0"),
|
69
|
+
:expiry_year => creditcard.year.to_s,
|
70
|
+
:cvv => creditcard.verification_value,
|
71
|
+
:first_name => creditcard.first_name,
|
72
|
+
:last_name => creditcard.last_name,
|
73
|
+
:address_1 => address[:address1],
|
74
|
+
:address_2 => address[:address2],
|
75
|
+
:city => address[:city],
|
76
|
+
:zip => address[:zip],
|
77
|
+
:sandbox => test?
|
78
|
+
})
|
79
|
+
result.retain if options[:retain] && result.is_sensitive_data_valid && result.payment_method_token
|
80
|
+
|
81
|
+
Response.new(result.is_sensitive_data_valid,
|
82
|
+
message_from_result(result),
|
83
|
+
{ :payment_method_token => result.is_sensitive_data_valid && result.payment_method_token })
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def payment_method_token(credit_card_or_vault_id, options)
|
89
|
+
return credit_card_or_vault_id if credit_card_or_vault_id.is_a?(String)
|
90
|
+
store_result = store(credit_card_or_vault_id, options)
|
91
|
+
store_result.success? ? store_result.params["payment_method_token"] : store_result
|
92
|
+
end
|
93
|
+
|
94
|
+
def handle_result(result)
|
95
|
+
response_params, response_options = {}, {}
|
96
|
+
if result.success?
|
97
|
+
response_options[:test] = test?
|
98
|
+
response_options[:authorization] = result.reference_id
|
99
|
+
response_params[:reference_id] = result.reference_id
|
100
|
+
response_params[:transaction_token] = result.transaction_token
|
101
|
+
response_params[:payment_method_token] = result.payment_method.payment_method_token
|
102
|
+
end
|
103
|
+
|
104
|
+
response_options[:avs_result] = { :code => result.processor_response && result.processor_response.avs_result_code }
|
105
|
+
response_options[:cvv_result] = result.processor_response && result.processor_response.cvv_result_code
|
106
|
+
|
107
|
+
message = message_from_result(result)
|
108
|
+
Response.new(result.success?, message, response_params, response_options)
|
109
|
+
end
|
110
|
+
|
111
|
+
def message_from_result(result)
|
112
|
+
return "OK" if result.success?
|
113
|
+
result.errors.map {|_, messages| messages }.join(" ")
|
114
|
+
end
|
115
|
+
|
116
|
+
def processor_options(options)
|
117
|
+
options.slice(:billing_reference, :customer_reference, :custom, :descriptor)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|