workarea-worldpay_xml 1.0.1
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.
- checksums.yaml +7 -0
- data/.editorconfig +20 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +19 -0
- data/.rails-rubocop.yml +130 -0
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +21 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +10 -0
- data/LICENSE +52 -0
- data/README.md +63 -0
- data/Rakefile +60 -0
- data/app/models/workarea/payment/authorize/credit_card.decorator +36 -0
- data/app/models/workarea/payment/credit_card_data.rb +48 -0
- data/app/models/workarea/payment/purchase/credit_card.decorator +36 -0
- data/app/models/workarea/payment/refund/credit_card.decorator +28 -0
- data/app/models/workarea/payment/store_credit_card.decorator +27 -0
- data/app/models/workarea/payment/tender/credit_card.decorator +7 -0
- data/bin/rails +20 -0
- data/config/initializers/workarea.rb +1 -0
- data/lib/active_merchant/billing/bogus_worldpay_gateway.rb +65 -0
- data/lib/active_merchant/billing/worldpay_tokenize.rb +118 -0
- data/lib/workarea/worldpay_xml.rb +48 -0
- data/lib/workarea/worldpay_xml/engine.rb +8 -0
- data/lib/workarea/worldpay_xml/version.rb +5 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +4 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +30 -0
- data/test/dummy/bin/update +26 -0
- data/test/dummy/bin/yarn +11 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +31 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +51 -0
- data/test/dummy/config/environments/production.rb +88 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +14 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/test/dummy/config/locales/en.yml +33 -0
- data/test/dummy/config/puma.rb +56 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +32 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/package.json +5 -0
- data/test/models/workarea/payment/authorize/credit_card_test.decorator +40 -0
- data/test/models/workarea/payment/capture_test.decorator +10 -0
- data/test/models/workarea/payment/credit_card_integration_test.decorator +24 -0
- data/test/models/workarea/payment/purchase/credit_card_test.decorator +25 -0
- data/test/models/workarea/payment/refund/credit_card_test.decorator +24 -0
- data/test/models/workarea/payment/refund_test.decorator +10 -0
- data/test/models/workarea/payment/store_credit_card_test.decorator +11 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/test/workers/workarea/send_refund_email_test.decorator +29 -0
- data/workarea-worldpay_xml.gemspec +17 -0
- metadata +141 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Payment::Authorize::CreditCard, with: :worldpay_xml_api do
|
3
|
+
decorated do
|
4
|
+
include Payment::CreditCardData
|
5
|
+
delegate :address, to: :tender
|
6
|
+
end
|
7
|
+
|
8
|
+
def complete!
|
9
|
+
return unless Payment::StoreCreditCard.new(tender, options).save!
|
10
|
+
|
11
|
+
transaction.response = handle_active_merchant_errors do
|
12
|
+
gateway.authorize(
|
13
|
+
transaction.amount.cents,
|
14
|
+
tender.to_token_or_active_merchant,
|
15
|
+
transaction_options
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def transaction_options
|
23
|
+
{
|
24
|
+
order_id: order_id,
|
25
|
+
pay_by_token: true,
|
26
|
+
token: tender.token,
|
27
|
+
shopper_id: tender.profile.email,
|
28
|
+
email: tender.profile.email,
|
29
|
+
address: billing_address,
|
30
|
+
order_content: order_content,
|
31
|
+
currency: currency_code
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Workarea
|
2
|
+
class Payment
|
3
|
+
module CreditCardData
|
4
|
+
def billing_address
|
5
|
+
{
|
6
|
+
name: "#{address.first_name} #{address.last_name}",
|
7
|
+
company: address.company,
|
8
|
+
address1: address.street,
|
9
|
+
city: address.city,
|
10
|
+
state: address.region,
|
11
|
+
country: address.country.try(:alpha2),
|
12
|
+
zip: address.postal_code,
|
13
|
+
phone: nil
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def order
|
18
|
+
@order ||= Workarea::Order.find(tender.payment.id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def order_content
|
22
|
+
@order_content ||= begin
|
23
|
+
contents = order.items.map { |oi| oi.sku }.join(',')
|
24
|
+
"Env: #{Rails.env}, Items: #{contents}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def currency_code
|
29
|
+
@currency_code = order.total_price.currency.iso_code
|
30
|
+
end
|
31
|
+
|
32
|
+
# Worldpay requires a unique order code per transaction, even
|
33
|
+
# if the transaction was a failure and a new card is used.
|
34
|
+
# Appending the time stamp gives some historical context
|
35
|
+
# in the payment admin
|
36
|
+
#
|
37
|
+
# !!!! A duplicate order code could cause a users credit card
|
38
|
+
# to be charged multiple times. Make sure this method returns a unique
|
39
|
+
# value each time. !!!!
|
40
|
+
def order_id
|
41
|
+
@order_id ||= begin
|
42
|
+
stamp = DateTime.now.strftime('%Y_%m_%d_%H_%M_%S')
|
43
|
+
"#{tender.payment.id}_#{stamp}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Payment::Purchase::CreditCard, with: :worldpay_xml_api do
|
3
|
+
decorated do
|
4
|
+
include Payment::CreditCardData
|
5
|
+
delegate :address, to: :tender
|
6
|
+
end
|
7
|
+
|
8
|
+
def complete!
|
9
|
+
return unless Workarea::Payment::StoreCreditCard.new(tender, options).save!
|
10
|
+
|
11
|
+
transaction.response = handle_active_merchant_errors do
|
12
|
+
gateway.purchase(
|
13
|
+
transaction.amount.cents,
|
14
|
+
tender.to_token_or_active_merchant,
|
15
|
+
transaction_options
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def transaction_options
|
23
|
+
{
|
24
|
+
order_id: order_id,
|
25
|
+
pay_by_token: true,
|
26
|
+
token: tender.token,
|
27
|
+
shopper_id: tender.profile.email,
|
28
|
+
email: tender.profile.email,
|
29
|
+
address: billing_address,
|
30
|
+
order_content: order_content,
|
31
|
+
currency: currency_code
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Payment::Refund::CreditCard, with: :worldpay_xml_api do
|
3
|
+
decorated do
|
4
|
+
include Payment::CreditCardData
|
5
|
+
delegate :address, to: :tender
|
6
|
+
end
|
7
|
+
|
8
|
+
def complete!
|
9
|
+
validate_reference!
|
10
|
+
|
11
|
+
transaction.response = handle_active_merchant_errors do
|
12
|
+
gateway.refund(
|
13
|
+
transaction.amount.cents,
|
14
|
+
transaction.reference.response.authorization,
|
15
|
+
transaction_options
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def transaction_options
|
23
|
+
{
|
24
|
+
currency: currency_code
|
25
|
+
}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Payment::StoreCreditCard, with: :worldpay_xml_api do
|
3
|
+
decorated do
|
4
|
+
include Payment::CreditCardData
|
5
|
+
delegate :address, to: :tender
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform!
|
9
|
+
return true if @credit_card.token.present?
|
10
|
+
|
11
|
+
response = handle_active_merchant_errors do
|
12
|
+
gateway.create_token(@credit_card.to_active_merchant, token_options)
|
13
|
+
end
|
14
|
+
|
15
|
+
@credit_card.token = response.params["payment_token_id"]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def token_options
|
21
|
+
{
|
22
|
+
shopper_id: @credit_card.profile.email,
|
23
|
+
order_id: @credit_card.profile.reference
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/bin/rails
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
+
# installed from the root of your application.
|
4
|
+
|
5
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
6
|
+
ENGINE_PATH = File.expand_path('../../lib/workarea/worldpay_xml/engine', __FILE__)
|
7
|
+
APP_PATH = File.expand_path('../../test/dummy/config/application', __FILE__)
|
8
|
+
|
9
|
+
# Set up gems listed in the Gemfile.
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
12
|
+
|
13
|
+
require "action_controller/railtie"
|
14
|
+
require "action_view/railtie"
|
15
|
+
require "action_mailer/railtie"
|
16
|
+
require "rails/test_unit/railtie"
|
17
|
+
require "sprockets/railtie"
|
18
|
+
require 'teaspoon-mocha'
|
19
|
+
|
20
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1 @@
|
|
1
|
+
Workarea::WorldpayXml.auto_initialize_gateway
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ActiveMerchant
|
2
|
+
module Billing
|
3
|
+
class BogusWorldpayGateway < BogusGateway
|
4
|
+
def create_token(paysource, options= {})
|
5
|
+
case normalize(paysource)
|
6
|
+
when /1$/
|
7
|
+
Response.new(
|
8
|
+
true,
|
9
|
+
SUCCESS_MESSAGE,
|
10
|
+
{ payment_token_id: SecureRandom.hex(10).upcase + '1' },
|
11
|
+
:test => true,
|
12
|
+
:authorization => AUTHORIZATION
|
13
|
+
)
|
14
|
+
when /2$/
|
15
|
+
Response.new(
|
16
|
+
false,
|
17
|
+
FAILURE_MESSAGE,
|
18
|
+
{ payment_token_id: nil, error: FAILURE_MESSAGE },
|
19
|
+
:test => true,
|
20
|
+
:error_code => STANDARD_ERROR_CODE[:processing_error]
|
21
|
+
)
|
22
|
+
else
|
23
|
+
raise Error, error_message(paysource)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def authorize_swipe(money, paysource, options = {})
|
28
|
+
money = amount(money)
|
29
|
+
case normalize(paysource)
|
30
|
+
when /2$/
|
31
|
+
Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
|
32
|
+
when /3$/
|
33
|
+
Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
|
34
|
+
else
|
35
|
+
Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money}, :test => true, :authorization => AUTHORIZATION )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def purchase_swipe(money, paysource, options = {})
|
40
|
+
money = amount(money)
|
41
|
+
case normalize(paysource)
|
42
|
+
when /3$/
|
43
|
+
raise Error, error_message(paysource)
|
44
|
+
when /2$/
|
45
|
+
Response.new(
|
46
|
+
false,
|
47
|
+
FAILURE_MESSAGE,
|
48
|
+
{:paid_amount => money, :error => FAILURE_MESSAGE },
|
49
|
+
:test => true,
|
50
|
+
:error_code => STANDARD_ERROR_CODE[:processing_error]
|
51
|
+
)
|
52
|
+
else
|
53
|
+
Response.new(
|
54
|
+
true,
|
55
|
+
SUCCESS_MESSAGE,
|
56
|
+
{:paid_amount => money},
|
57
|
+
:test => true,
|
58
|
+
:authorization => AUTHORIZATION
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
ActiveMerchant::Billing::WorldpayGateway.class_eval do
|
2
|
+
def create_token(payment_method, options = {})
|
3
|
+
requires!(options, :order_id)
|
4
|
+
create_token_request(payment_method, options)
|
5
|
+
end
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def create_token_request(payment_method, options)
|
10
|
+
commit('payment_token_create', build_create_token_request(payment_method, options), nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
def build_create_token_request(payment_method, options)
|
14
|
+
build_request do |xml|
|
15
|
+
xml.tag! 'submit' do
|
16
|
+
xml.tag! 'paymentTokenCreate' do
|
17
|
+
xml.tag! 'authenticatedShopperID', options[:shopper_id]
|
18
|
+
add_token_details(xml, options)
|
19
|
+
add_token_payment_method(xml, payment_method, options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_token_details(xml, options)
|
26
|
+
return unless options[:order_id]
|
27
|
+
xml.tag! 'createToken' do
|
28
|
+
xml.tag! 'tokenEventReference', options[:order_id]
|
29
|
+
xml.tag! 'tokenReason', 'Saved payment method'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_token_payment_method(xml, payment_method, options)
|
34
|
+
return unless options[:order_id]
|
35
|
+
xml.tag! 'paymentInstrument' do
|
36
|
+
xml.tag! 'cardDetails' do
|
37
|
+
xml.tag! 'cardNumber', payment_method.number
|
38
|
+
xml.tag! 'expiryDate' do
|
39
|
+
xml.tag! 'date', 'month' => format(payment_method.month, :two_digits), 'year' => format(payment_method.year, :four_digits)
|
40
|
+
end
|
41
|
+
xml.tag! 'cardHolderName', payment_method.name
|
42
|
+
xml.tag! 'cvc', payment_method.verification_value
|
43
|
+
end
|
44
|
+
add_address(xml, (options[:billing_address] || options[:address]))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# success_criteria can be:
|
49
|
+
# - a string or an array of strings (if one of many responses)
|
50
|
+
# - An array of strings if one of many responses could be considered a
|
51
|
+
# success.
|
52
|
+
# - if empty then look for error codes
|
53
|
+
def success_and_message_from(raw, success_criteria)
|
54
|
+
success = if success_criteria.compact.empty?
|
55
|
+
!(raw[:error].present? && raw[:error_code].present?)
|
56
|
+
else
|
57
|
+
(success_criteria.include?(raw[:last_event]) || raw[:ok].present?)
|
58
|
+
end
|
59
|
+
|
60
|
+
if success
|
61
|
+
message = "SUCCESS"
|
62
|
+
else
|
63
|
+
message = (raw[:iso8583_return_code_description] || raw[:error] || required_status_message(raw, success_criteria))
|
64
|
+
end
|
65
|
+
|
66
|
+
[ success, message ]
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_payment_method(xml, amount, payment_method, options)
|
70
|
+
if payment_method.is_a?(String)
|
71
|
+
if options[:merchant_code]
|
72
|
+
xml.tag! 'payAsOrder', 'orderCode' => payment_method, 'merchantCode' => options[:merchant_code] do
|
73
|
+
add_amount(xml, amount, options)
|
74
|
+
end
|
75
|
+
elsif options[:pay_by_token]
|
76
|
+
xml.tag! 'paymentDetails' do
|
77
|
+
xml.tag! 'TOKEN-SSL', 'tokenScope' => 'shopper' do
|
78
|
+
xml.tag! 'paymentTokenID', payment_method
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
xml.tag! 'payAsOrder', 'orderCode' => payment_method do
|
83
|
+
add_amount(xml, amount, options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
else
|
87
|
+
xml.tag! 'paymentDetails' do
|
88
|
+
xml.tag! CARD_CODES[card_brand(payment_method)] do
|
89
|
+
xml.tag! 'cardNumber', payment_method.number
|
90
|
+
xml.tag! 'expiryDate' do
|
91
|
+
xml.tag! 'date', 'month' => format(payment_method.month, :two_digits), 'year' => format(payment_method.year, :four_digits)
|
92
|
+
end
|
93
|
+
|
94
|
+
xml.tag! 'cardHolderName', payment_method.name
|
95
|
+
xml.tag! 'cvc', payment_method.verification_value
|
96
|
+
|
97
|
+
add_address(xml, (options[:billing_address] || options[:address]))
|
98
|
+
end
|
99
|
+
if options[:ip] && options[:session_id]
|
100
|
+
xml.tag! 'session', 'shopperIPAddress' => options[:ip], 'id' => options[:session_id]
|
101
|
+
else
|
102
|
+
xml.tag! 'session', 'shopperIPAddress' => options[:ip] if options[:ip]
|
103
|
+
xml.tag! 'session', 'id' => options[:session_id] if options[:session_id]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def add_email(xml, options)
|
110
|
+
return unless options[:email]
|
111
|
+
xml.tag! 'shopper' do
|
112
|
+
xml.tag! 'shopperEmailAddress', options[:email]
|
113
|
+
if options[:pay_by_token]
|
114
|
+
xml.tag! 'authenticatedShopperID', options[:shopper_id]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'workarea'
|
2
|
+
require 'workarea/storefront'
|
3
|
+
require 'workarea/admin'
|
4
|
+
|
5
|
+
require 'workarea/worldpay_xml/engine'
|
6
|
+
require 'workarea/worldpay_xml/version'
|
7
|
+
|
8
|
+
require 'active_merchant/billing/bogus_worldpay_gateway'
|
9
|
+
require 'active_merchant/billing/worldpay_tokenize'
|
10
|
+
|
11
|
+
|
12
|
+
module Workarea
|
13
|
+
module WorldpayXml
|
14
|
+
# Credentials for WorldpayGateway from Rails secrets.
|
15
|
+
#
|
16
|
+
# @return [Hash]
|
17
|
+
def self.credentials
|
18
|
+
return {} unless Rails.application.secrets.worldpay.present?
|
19
|
+
Rails.application.secrets.worldpay.symbolize_keys
|
20
|
+
end
|
21
|
+
|
22
|
+
# Conditionally use the real gateway when secrets are present.
|
23
|
+
# Otherwise, use the bogus gateway.
|
24
|
+
#
|
25
|
+
# @return [ActiveMerchant::Billing::Gateway]
|
26
|
+
def self.gateway
|
27
|
+
Workarea.config.gateways.credit_card
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.gateway=(gateway)
|
31
|
+
Workarea.config.gateways.credit_card = gateway
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.auto_initialize_gateway
|
35
|
+
if credentials.present?
|
36
|
+
if ENV['HTTP_PROXY'].present?
|
37
|
+
uri = URI.parse(ENV['HTTP_PROXY'])
|
38
|
+
ActiveMerchant::Billing::WorldpayGateway.proxy_address = uri.host
|
39
|
+
ActiveMerchant::Billing::WorldpayGateway.proxy_port = uri.port
|
40
|
+
end
|
41
|
+
|
42
|
+
self.gateway = ActiveMerchant::Billing::WorldpayGateway.new credentials
|
43
|
+
else
|
44
|
+
self.gateway = ActiveMerchant::Billing::BogusWorldpayGateway.new
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|