workarea-sezzle 1.0.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.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +405 -0
- data/.scss-lint.yml +204 -0
- data/Gemfile +17 -0
- data/LICENSE +7 -0
- data/README.md +95 -0
- data/Rakefile +56 -0
- data/Workarea +0 -0
- data/app/assets/images/workarea/admin/sezzle/.keep +0 -0
- data/app/assets/images/workarea/sezzle_logo_white.svg +1 -0
- data/app/assets/images/workarea/storefront/sezzle/.keep +0 -0
- data/app/assets/javascripts/workarea/admin/sezzle/.keep +0 -0
- data/app/assets/javascripts/workarea/storefront/sezzle/.keep +0 -0
- data/app/assets/stylesheets/workarea/admin/sezzle/.keep +0 -0
- data/app/assets/stylesheets/workarea/admin/sezzle/components/_payment_icon.scss +13 -0
- data/app/assets/stylesheets/workarea/storefront/sezzle/.keep +0 -0
- data/app/assets/stylesheets/workarea/storefront/sezzle/components/_payment_icon.scss +13 -0
- data/app/assets/stylesheets/workarea/storefront/sezzle/components/_sezzle.scss +13 -0
- data/app/controllers/.keep +0 -0
- data/app/controllers/workarea/storefront/checkout/place_order_controller.decorator +11 -0
- data/app/controllers/workarea/storefront/sezzle_controller.rb +109 -0
- data/app/helpers/.keep +0 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/models/workarea/payment/authorize/sezzle.rb +32 -0
- data/app/models/workarea/payment/capture/sezzle.rb +85 -0
- data/app/models/workarea/payment/purchase/sezzle.rb +30 -0
- data/app/models/workarea/payment/refund/sezzle.rb +47 -0
- data/app/models/workarea/payment/tender/sezzle.rb +15 -0
- data/app/models/workarea/paymentl.decorator +32 -0
- data/app/services/workarea/sezzle/order_builder.rb +135 -0
- data/app/view_models/workarea/storefront/checkout/payment_view_model.decorator +11 -0
- data/app/views/.keep +0 -0
- data/app/views/workarea/admin/orders/tenders/_sezzle.html.haml +3 -0
- data/app/views/workarea/storefront/carts/_sezzle_widget.html.haml +5 -0
- data/app/views/workarea/storefront/checkouts/_sezzle_payment.html.haml +8 -0
- data/app/views/workarea/storefront/order_mailer/tenders/_sezzle.html.haml +1 -0
- data/app/views/workarea/storefront/order_mailer/tenders/_sezzle.text.erb +1 -0
- data/app/views/workarea/storefront/orders/tenders/_sezzle.html.haml +4 -0
- data/app/views/workarea/storefront/products/_sezzle_widget.html.haml +10 -0
- data/app/views/workarea/storefront/sezzle/_script.html.haml +22 -0
- data/bin/rails +25 -0
- data/config/initializers/appends.rb +30 -0
- data/config/initializers/configurations.rb +41 -0
- data/config/initializers/workarea.rb +21 -0
- data/config/locales/en.yml +43 -0
- data/config/routes.rb +5 -0
- data/lib/workarea/sezzle.rb +53 -0
- data/lib/workarea/sezzle/authentication.rb +49 -0
- data/lib/workarea/sezzle/bogus_gateway.rb +128 -0
- data/lib/workarea/sezzle/engine.rb +10 -0
- data/lib/workarea/sezzle/gateway.rb +90 -0
- data/lib/workarea/sezzle/response.rb +27 -0
- data/lib/workarea/sezzle/version.rb +5 -0
- data/module +0 -0
- data/test/dummy/.ruby-version +1 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +2 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +2 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/javascript/packs/application.js +14 -0
- data/test/dummy/app/jobs/application_job.rb +7 -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/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +25 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +34 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +53 -0
- data/test/dummy/config/environments/production.rb +101 -0
- data/test/dummy/config/environments/test.rb +47 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/test/dummy/config/initializers/assets.rb +12 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/content_security_policy.rb +28 -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 +38 -0
- data/test/dummy/config/routes.rb +5 -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/integration/workarea/storefront/sezzle_integration_test.rb +205 -0
- data/test/models/workarea/payment/sezzle_payment_integration_test.rb +82 -0
- data/test/services/workarea/sezzle/order_builder_test.rb +116 -0
- data/test/teaspoon_env.rb +6 -0
- data/test/test_helper.rb +10 -0
- data/workarea-sezzle.gemspec +20 -0
- metadata +163 -0
data/app/views/.keep
ADDED
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
.checkout-payment__primary-method{ class: ('checkout-payment__primary-method--selected' if @step.sezzle?) }
|
|
2
|
+
.button-property
|
|
3
|
+
= hidden_field_tag 'from_checkout', 'from_checkout', id: nil
|
|
4
|
+
.value= radio_button_tag 'payment', 'sezzle', step.sezzle?
|
|
5
|
+
= label_tag 'payment[sezzle]', nil, class: 'button-property__name' do
|
|
6
|
+
%span.button-property__text= inline_svg('workarea/sezzle_logo_white.svg', class: 'payment-icon payment-icon--sezzle')
|
|
7
|
+
%p.checkout-payment__primary-method-description
|
|
8
|
+
%span= t('workarea.storefront.sezzle.on_continue')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
%p= t('workarea.storefront.sezzle.paid_with_sezzle')
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= t('workarea.sezzle.tender_description') %>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
- if Workarea.config.sezzle_merchant_id.present?
|
|
2
|
+
#sezzle.sezzle.sezzle--product
|
|
3
|
+
.sezzle__prices
|
|
4
|
+
- if product.show_sell_range?
|
|
5
|
+
%span.sezzle__price= number_to_currency(product.sell_min_price)
|
|
6
|
+
–
|
|
7
|
+
%span.sezzle__price= number_to_currency(product.sell_max_price)
|
|
8
|
+
- else
|
|
9
|
+
%span.sezzle__price
|
|
10
|
+
= number_to_currency(product.sell_min_price)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
- if Workarea.config.sezzle_merchant_id.present?
|
|
2
|
+
:javascript
|
|
3
|
+
document.sezzleConfig = {
|
|
4
|
+
configGroups: [
|
|
5
|
+
{
|
|
6
|
+
targetXPath: "#{Workarea.config.sezzle.product_config[:target_xpath]}",
|
|
7
|
+
renderToPath: "#{Workarea.config.sezzle.product_config[:render_to_path]}",
|
|
8
|
+
urlMatch: "#{Workarea.config.sezzle.product_config[:url_match]}",
|
|
9
|
+
splitPriceElementsOn: "#{Workarea.config.sezzle.product_config[:split_price_elements_on]}"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
targetXPath: "#{Workarea.config.sezzle.cart_config[:target_xpath]}",
|
|
13
|
+
renderToPath: "#{Workarea.config.sezzle.cart_config[:render_to_path]}",
|
|
14
|
+
urlMatch: "#{Workarea.config.sezzle.cart_config[:url_match]}",
|
|
15
|
+
altVersionTemplate: {
|
|
16
|
+
'en': '4 interest-free payments of %%price%% with %%logo%% %%info%%',
|
|
17
|
+
'fr': '4 paiements de %%price%% sans intérêts avec %%logo%% %%info%%'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
%script{ src: "https://widget.sezzle.com/v1/javascript/price-widget?uuid=#{Workarea.config.sezzle_merchant_id}" }
|
data/bin/rails
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
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('..', __dir__)
|
|
6
|
+
ENGINE_PATH = File.expand_path('../lib/workarea/sezzle/engine', __dir__)
|
|
7
|
+
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
|
|
8
|
+
|
|
9
|
+
# Set up gems listed in the Gemfile.
|
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
|
12
|
+
|
|
13
|
+
require 'rails'
|
|
14
|
+
# Pick the frameworks you want:
|
|
15
|
+
require 'active_model/railtie'
|
|
16
|
+
require 'active_job/railtie'
|
|
17
|
+
# require "active_record/railtie"
|
|
18
|
+
# require "active_storage/engine"
|
|
19
|
+
require 'action_controller/railtie'
|
|
20
|
+
require 'action_mailer/railtie'
|
|
21
|
+
require 'action_view/railtie'
|
|
22
|
+
# require "action_cable/engine"
|
|
23
|
+
require 'sprockets/railtie'
|
|
24
|
+
require 'rails/test_unit/railtie'
|
|
25
|
+
require 'rails/engine/commands'
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
Workarea::Plugin.append_stylesheets(
|
|
2
|
+
'admin.components',
|
|
3
|
+
'workarea/storefront/sezzle/components/payment_icon'
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
Workarea::Plugin.append_stylesheets(
|
|
7
|
+
'storefront.components',
|
|
8
|
+
'workarea/storefront/sezzle/components/sezzle',
|
|
9
|
+
'workarea/storefront/sezzle/components/payment_icon'
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
Workarea::Plugin.append_partials(
|
|
13
|
+
'storefront.payment_method',
|
|
14
|
+
'workarea/storefront/checkouts/sezzle_payment'
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
Workarea::Plugin.append_partials(
|
|
18
|
+
'storefront.javascript',
|
|
19
|
+
'workarea/storefront/sezzle/script'
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
Workarea::Plugin.append_partials(
|
|
23
|
+
'storefront.product_pricing_details',
|
|
24
|
+
'workarea/storefront/products/sezzle_widget'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
Workarea::Plugin.append_partials(
|
|
28
|
+
'storefront.cart_additional_information',
|
|
29
|
+
'workarea/storefront/carts/sezzle_widget'
|
|
30
|
+
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
if Workarea::Configuration.respond_to?(:define_fields)
|
|
2
|
+
Workarea::Configuration.define_fields do
|
|
3
|
+
fieldset 'Sezzle', namespaced: true do
|
|
4
|
+
field 'Public Key',
|
|
5
|
+
type: :string,
|
|
6
|
+
description: 'Public Key from merchant dashboard.',
|
|
7
|
+
allow_blank: false,
|
|
8
|
+
encrypted: false
|
|
9
|
+
|
|
10
|
+
field 'Private Key',
|
|
11
|
+
type: :string,
|
|
12
|
+
description: 'Private Key from merchant dashboard.',
|
|
13
|
+
allow_blank: false,
|
|
14
|
+
encrypted: true
|
|
15
|
+
|
|
16
|
+
field 'Merchant ID',
|
|
17
|
+
type: :string,
|
|
18
|
+
default: 'TODO',
|
|
19
|
+
description: 'Merchant ID from merchant dashboard.',
|
|
20
|
+
allow_blank: false,
|
|
21
|
+
encrypted: false
|
|
22
|
+
|
|
23
|
+
field 'Payment Action',
|
|
24
|
+
type: :string,
|
|
25
|
+
description: 'Determines if the order payment is authorized or immediately catpured.',
|
|
26
|
+
allow_blank: false,
|
|
27
|
+
encrypted: false,
|
|
28
|
+
default: 'AUTH'
|
|
29
|
+
|
|
30
|
+
field 'Test Mode',
|
|
31
|
+
type: :boolean,
|
|
32
|
+
description: 'Uses the sandbox API endpoints if set to true. Contact your Sezzle representative for sandbox credentials.',
|
|
33
|
+
default: !Rails.env.production?
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
|
|
38
|
+
Workarea.config.sezzle_test_mode = !Rails.env.production?
|
|
39
|
+
Workarea.config.sezzle_payment_action = 'AUTH'
|
|
40
|
+
Workarea.config.sezzle_merchant_id = nil # Host apps are responsible for adding this configuration
|
|
41
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Workarea.configure do |config|
|
|
2
|
+
|
|
3
|
+
config.tender_types.append(:sezzle)
|
|
4
|
+
|
|
5
|
+
config.sezzle = ActiveSupport::Configurable::Configuration.new
|
|
6
|
+
config.sezzle.api_timeout = 10
|
|
7
|
+
config.sezzle.open_timeout = 10
|
|
8
|
+
|
|
9
|
+
config.sezzle.product_config = {
|
|
10
|
+
target_xpath: '#sezzle/.sezzle__prices',
|
|
11
|
+
render_to_path: './',
|
|
12
|
+
url_match: 'products',
|
|
13
|
+
split_price_elements_on: '–'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
config.sezzle.cart_config = {
|
|
17
|
+
target_xpath: '#sezzle/.sezzle__prices',
|
|
18
|
+
render_to_path: './',
|
|
19
|
+
url_match: 'cart'
|
|
20
|
+
}
|
|
21
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
en:
|
|
3
|
+
workarea:
|
|
4
|
+
admin:
|
|
5
|
+
orders:
|
|
6
|
+
tenders:
|
|
7
|
+
sezzle:
|
|
8
|
+
title: Sezzle
|
|
9
|
+
storefront:
|
|
10
|
+
orders:
|
|
11
|
+
tenders:
|
|
12
|
+
sezzle: Sezzle
|
|
13
|
+
carts:
|
|
14
|
+
sezzle: "Pay %{installment_count} interest free payments of %{installment_price} with"
|
|
15
|
+
checkouts:
|
|
16
|
+
sezzle: Pay With Sezzle
|
|
17
|
+
products:
|
|
18
|
+
sezzle: "Or %{installment_count} payments of %{installment_price} with"
|
|
19
|
+
sezzle:
|
|
20
|
+
address_error: We can not ship to this address. Please enter a new address.
|
|
21
|
+
cancel_message: Your Sezzle order has been cancelled. Please select another payment method.
|
|
22
|
+
check_out: Check Out with sezzle
|
|
23
|
+
checkout_submit_text: Continue to Sezzle
|
|
24
|
+
on_continue: When you continue, you will be taken to the Sezzle website to complete your order.
|
|
25
|
+
paid_with_sezzle: Paid with Sezzle
|
|
26
|
+
payment_error: There was a problem processing your Sezzle payment, you have not been charged. Please try again or select
|
|
27
|
+
another payment method.
|
|
28
|
+
sezzle: Sezzle
|
|
29
|
+
learn_more: Learn More
|
|
30
|
+
sezzle:
|
|
31
|
+
authorize: "%{amount} has been captured"
|
|
32
|
+
pre_authorized_message: "Authorization happens in the Sezzle checkout process. No API response to record. %{amount} was authorized by Sezzle."
|
|
33
|
+
pre_captured_message: "Capture occurred in the Sezzle checkout process. No API response to record. %{amount} was captured by Sezzle."
|
|
34
|
+
pre_purchased_message: "Authorize and Capture occurred in the Sezzle checkout process. No API response to record. %{amount} was captured by Sezzle."
|
|
35
|
+
capture: "%{amount} has been captured"
|
|
36
|
+
purchase: "%{amount} has been purchased"
|
|
37
|
+
refund: "%{amount} has been refunded"
|
|
38
|
+
void: Sezzle Transaction has been voided
|
|
39
|
+
authorize_failure: Sezzle authorize has failed
|
|
40
|
+
capture_failure: Sezzle capture has failed
|
|
41
|
+
purchase_failure: Sezzle purchase has failed
|
|
42
|
+
refund_failure: Sezzle refund has failed
|
|
43
|
+
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'workarea'
|
|
2
|
+
require 'workarea/storefront'
|
|
3
|
+
require 'workarea/admin'
|
|
4
|
+
|
|
5
|
+
require 'workarea/sezzle/engine'
|
|
6
|
+
require 'workarea/sezzle/version'
|
|
7
|
+
|
|
8
|
+
require 'workarea/sezzle/bogus_gateway'
|
|
9
|
+
require 'workarea/sezzle/authentication'
|
|
10
|
+
require 'workarea/sezzle/gateway'
|
|
11
|
+
require 'workarea/sezzle/response'
|
|
12
|
+
|
|
13
|
+
module Workarea
|
|
14
|
+
module Sezzle
|
|
15
|
+
def self.config
|
|
16
|
+
Workarea.config.sezzle
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# used for <= 3.5, these creds come from secrets isntead of encrypted in the
|
|
20
|
+
# 3.5 configurations system.
|
|
21
|
+
def self.credentials
|
|
22
|
+
(Rails.application.secrets.sezzle || {}).deep_symbolize_keys
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.api_public_key
|
|
26
|
+
Workarea.config.sezzle_public_key || credentials[:api_public_key]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.api_private_key
|
|
30
|
+
Workarea.config.sezzle_private_key || credentials[:api_private_key]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.api_configured?
|
|
34
|
+
api_public_key.present? && api_private_key.present?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.test?
|
|
38
|
+
Workarea.config.sezzle_test_mode || credentials[:test]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.gateway
|
|
42
|
+
if Rails.env.test?
|
|
43
|
+
Sezzle::BogusGateway.new
|
|
44
|
+
else
|
|
45
|
+
Sezzle::Gateway.new(
|
|
46
|
+
api_public_key: api_public_key,
|
|
47
|
+
api_private_key: api_private_key,
|
|
48
|
+
test: test?
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
module Sezzle
|
|
3
|
+
module Authentication
|
|
4
|
+
class AuthenticationError < StandardError; end
|
|
5
|
+
def token
|
|
6
|
+
response = get_token
|
|
7
|
+
body = JSON.parse(response.body)
|
|
8
|
+
|
|
9
|
+
raise AuthenticationError, response.body.to_s unless response.success?
|
|
10
|
+
body['token']
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def get_token
|
|
16
|
+
Rails.cache.fetch(token_cache_key, expires_in: 5.minutes) do
|
|
17
|
+
|
|
18
|
+
body = {
|
|
19
|
+
public_key: api_public_key,
|
|
20
|
+
private_key: api_private_key
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
conn = Faraday.new(url: rest_endpoint)
|
|
24
|
+
conn.post do |req|
|
|
25
|
+
req.url 'v2/authentication'
|
|
26
|
+
req.headers['Content-Type'] = 'application/json'
|
|
27
|
+
req.body = body.to_json
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def api_public_key
|
|
33
|
+
options[:api_public_key]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def api_private_key
|
|
37
|
+
options[:api_private_key]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test
|
|
41
|
+
options[:test]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def token_cache_key
|
|
45
|
+
Digest::MD5.hexdigest "#{api_public_key}#{api_private_key}#{test}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module Workarea
|
|
2
|
+
module Sezzle
|
|
3
|
+
class BogusGateway
|
|
4
|
+
def initialize(*)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def create_session(order)
|
|
8
|
+
b = {
|
|
9
|
+
"uuid": 'fadbc642-05a4-4e38-9e74-80e325623af9',
|
|
10
|
+
"links": [
|
|
11
|
+
{
|
|
12
|
+
"href": 'https://gateway.sezzle.com/v2/session/fadbc642-05a4-4e38-9e74-80e325623af9',
|
|
13
|
+
"method": 'GET',
|
|
14
|
+
"rel": 'self'
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"order": {
|
|
18
|
+
"uuid": '12a34bc5-6de7-890f-g123-4hi1238jk902',
|
|
19
|
+
"intent": 'CAPTURE',
|
|
20
|
+
"checkout_url": 'https://checkout.sezzle.com/?id=12a34bc5-6de7-890f-g123-4hi1238jk902',
|
|
21
|
+
"links": [
|
|
22
|
+
{
|
|
23
|
+
"href": 'https://gateway.sezzle.com/v2/order/12a34bc5-6de7-890f-g123-4hi1238jk902',
|
|
24
|
+
"method": 'GET',
|
|
25
|
+
"rel": 'self'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"href": 'https://gateway.sezzle.com/v2/order/12a34bc5-6de7-890f-g123-4hi1238jk902',
|
|
29
|
+
"method": 'PATCH',
|
|
30
|
+
"rel": 'self'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"href": 'https://gateway.sezzle.com/v2/order/12a34bc5-6de7-890f-g123-4hi1238jk902/release',
|
|
34
|
+
"method": 'POST',
|
|
35
|
+
"rel": 'release'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"href": 'https://gateway.sezzle.com/v2/order/12a34bc5-6de7-890f-g123-4hi1238jk902/capture',
|
|
39
|
+
"method": 'POST',
|
|
40
|
+
"rel": 'capture'
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"href": 'https://gateway.sezzle.com/v2/order/12a34bc5-6de7-890f-g123-4hi1238jk902/refund',
|
|
44
|
+
"method": 'POST',
|
|
45
|
+
"rel": 'refund'
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"tokenize": {
|
|
50
|
+
"token": '7ec98824-67cc-469c-86ab-f9e047f9cf1a',
|
|
51
|
+
"expiration": '2020-04-27T14:46:59Z',
|
|
52
|
+
"approval_url": 'https://dashboard.sezzle.com/customer/checkout-approval?merchant-request-id=3f3244fd-78ce-4994-af0c-b8c760d47794',
|
|
53
|
+
"links": [
|
|
54
|
+
{
|
|
55
|
+
"href": 'https://gateway.sezzle.com/v2/token/7ec98824-67cc-469c-86ab-f9e047f9cf1a/session ',
|
|
56
|
+
"method": 'GET',
|
|
57
|
+
"rel": 'token'
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
Response.new(response(b))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def capture(id, attrs)
|
|
67
|
+
if id == 'error'
|
|
68
|
+
Response.new(response(error_response_body, 400))
|
|
69
|
+
else
|
|
70
|
+
Response.new(response(payment_response_body, 200))
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def authorize(id, attrs)
|
|
75
|
+
if id == 'error'
|
|
76
|
+
Response.new(response(error_response_body, 400))
|
|
77
|
+
elsif id == 'timeout_token'
|
|
78
|
+
Response.new(response(nil, 502))
|
|
79
|
+
else
|
|
80
|
+
Response.new(response(payment_response_body, 200))
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def purchase(id, attrs)
|
|
85
|
+
if id == 'error'
|
|
86
|
+
Response.new(response(error_response_body, 402))
|
|
87
|
+
else
|
|
88
|
+
Response.new(response(payment_response_body, 200))
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def refund(id, attrs)
|
|
93
|
+
Response.new(response(payment_response_body, 200))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def void(payment_id)
|
|
97
|
+
Response.new(response(payment_response_body))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
private
|
|
101
|
+
|
|
102
|
+
def response(body, status = 200)
|
|
103
|
+
response = Faraday.new do |builder|
|
|
104
|
+
builder.adapter :test do |stub|
|
|
105
|
+
stub.get('/v1/bogus') { |env| [ status, {}, body.to_json ] }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
response.get('/v1/bogus')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def error_response_body
|
|
112
|
+
[
|
|
113
|
+
{
|
|
114
|
+
"code": 'invalid',
|
|
115
|
+
"message": 'Order must have a valid intent',
|
|
116
|
+
"location": 'order.intent'
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def payment_response_body(status: 'APPROVED')
|
|
122
|
+
{
|
|
123
|
+
"uuid": '6c9db5d4-d09a-4224-860a-b5438ac32ca8'
|
|
124
|
+
}
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|