solidus_afterpay 0.1.0 → 0.2.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -23
  3. data/app/assets/javascripts/solidus_afterpay/afterpay_checkout.js +11 -11
  4. data/app/assets/javascripts/solidus_afterpay/afterpay_checkout_button.js +85 -0
  5. data/app/assets/javascripts/solidus_afterpay/afterpay_init.js +12 -0
  6. data/app/assets/javascripts/solidus_afterpay/backend/afterpay_autocomplete.js +9 -0
  7. data/app/assets/javascripts/spree/backend/solidus_afterpay.js +3 -1
  8. data/app/assets/javascripts/spree/frontend/solidus_afterpay.js +2 -0
  9. data/app/controllers/solidus_afterpay/checkouts_controller.rb +8 -2
  10. data/app/controllers/solidus_afterpay/express_callbacks_controller.rb +61 -0
  11. data/app/decorators/controllers/solidus_afterpay/spree/orders_controller_decorator.rb +13 -0
  12. data/app/helpers/solidus_afterpay/afterpay_helper.rb +5 -4
  13. data/app/models/solidus_afterpay/gateway.rb +37 -10
  14. data/app/models/solidus_afterpay/order_component_builder.rb +34 -5
  15. data/app/models/solidus_afterpay/payment_method.rb +43 -10
  16. data/app/models/solidus_afterpay/payment_source.rb +1 -1
  17. data/app/presentes/solidus_afterpay/order_presenter.rb +17 -0
  18. data/app/presentes/solidus_afterpay/shipping_rate_presenter.rb +28 -0
  19. data/app/services/solidus_afterpay/base_service.rb +13 -0
  20. data/app/services/solidus_afterpay/shipping_rate_builder_service.rb +32 -0
  21. data/app/services/solidus_afterpay/update_order_addresses_service.rb +45 -0
  22. data/app/services/solidus_afterpay/update_order_attributes_service.rb +49 -0
  23. data/app/views/solidus_afterpay/_afterpay_checkout_button.html.erb +9 -0
  24. data/app/views/solidus_afterpay/_afterpay_javascript.html.erb +4 -1
  25. data/app/views/spree/api/payments/source_views/_afterpay.json.jbuilder +1 -1
  26. data/app/views/spree/shared/_afterpay_messaging.html.erb +14 -12
  27. data/config/locales/en.yml +4 -0
  28. data/config/routes.rb +2 -0
  29. data/lib/generators/solidus_afterpay/install/templates/initializer.rb +12 -0
  30. data/lib/solidus_afterpay/configuration.rb +22 -0
  31. data/lib/solidus_afterpay/testing_support/factories.rb +20 -0
  32. data/lib/solidus_afterpay/version.rb +1 -1
  33. data/solidus_afterpay.gemspec +1 -1
  34. data/spec/fixtures/vcr_casettes/find_order/invalid.yml +64 -0
  35. data/spec/fixtures/vcr_casettes/find_order/valid.yml +120 -0
  36. data/spec/helpers/solidus_afterpay/afterpay_helper_spec.rb +18 -2
  37. data/spec/models/solidus_afterpay/gateway_spec.rb +86 -12
  38. data/spec/models/solidus_afterpay/order_component_builder_spec.rb +67 -6
  39. data/spec/models/solidus_afterpay/payment_method_spec.rb +103 -39
  40. data/spec/models/solidus_afterpay/payment_source_spec.rb +3 -3
  41. data/spec/presenters/solidus_afterpay/order_presenter_spec.rb +34 -0
  42. data/spec/presenters/solidus_afterpay/shipping_rate_presenter_spec.rb +28 -0
  43. data/spec/requests/solidus_afterpay/checkouts_controller_spec.rb +72 -4
  44. data/spec/requests/solidus_afterpay/express_callbacks_controller_spec.rb +167 -0
  45. data/spec/services/solidus_afterpay/base_service_spec.rb +13 -0
  46. data/spec/services/solidus_afterpay/shipping_rate_builder_service_spec.rb +34 -0
  47. data/spec/services/solidus_afterpay/update_order_addresses_service_spec.rb +82 -0
  48. data/spec/services/solidus_afterpay/update_order_attributes_service_spec.rb +58 -0
  49. data/spec/support/cache.rb +5 -0
  50. data/spec/support/solidus.rb +1 -0
  51. data/spec/views/solidus_afterpay/express_checkout_button_spec.rb +33 -0
  52. data/spec/views/spree/shared/afterpay_messaging_spec.rb +44 -0
  53. metadata +42 -4
@@ -4,11 +4,9 @@ module SolidusAfterpay
4
4
  class PaymentMethod < SolidusSupport.payment_method_parent_class
5
5
  preference :merchant_id, :string
6
6
  preference :secret_key, :string
7
- preference :deferred, :boolean
8
7
  preference :popup_window, :boolean
9
- preference :minimum_amount, :decimal
10
- preference :maximum_amount, :decimal
11
- preference :currency, :string
8
+ preference :merchant_key, :string
9
+ preference :excluded_products, :string
12
10
 
13
11
  def gateway_class
14
12
  SolidusAfterpay::Gateway
@@ -33,24 +31,59 @@ module SolidusAfterpay
33
31
  end
34
32
 
35
33
  def available_for_order?(order)
34
+ return false if order.line_items.any?{ |item| excluded_product_ids.include? item.variant.product_id }
35
+
36
36
  available_payment_currency == order.currency && available_payment_range.include?(order.total)
37
37
  end
38
38
 
39
+ def excluded_product?(product)
40
+ excluded_product_ids.include? product.id
41
+ end
42
+
39
43
  private
40
44
 
41
- def available_payment_range
42
- min = preferred_minimum_amount || configuration&.minimumAmount&.amount.to_f
43
- max = preferred_maximum_amount || configuration&.maximumAmount&.amount.to_f
45
+ def excluded_product_ids
46
+ return [] if preferred_excluded_products.nil?
44
47
 
45
- min..max
48
+ preferred_excluded_products.split(",").map(&:to_i)
46
49
  end
47
50
 
48
- def available_payment_currency
49
- preferred_currency || configuration&.maximumAmount&.currency
51
+ def available_payment_range
52
+ minimum_amount..maximum_amount
50
53
  end
51
54
 
52
55
  def configuration
53
56
  @configuration ||= gateway.retrieve_configuration
54
57
  end
58
+
59
+ def minimum_amount
60
+ @minimum_amount ||= fetch_configuration(:minimumAmount, :amount).to_f
61
+ end
62
+
63
+ def maximum_amount
64
+ @maximum_amount ||= fetch_configuration(:maximumAmount, :amount).to_f
65
+ end
66
+
67
+ def available_payment_currency
68
+ @available_payment_currency = fetch_configuration(:maximumAmount, :currency)
69
+ end
70
+
71
+ def fetch_configuration(*keys)
72
+ cache_key = "solidus_afterpay_configuration_#{keys.join('_')}"
73
+
74
+ return Rails.cache.read(cache_key) if Rails.cache.exist?(cache_key)
75
+
76
+ value = configuration&.dig(*keys)
77
+
78
+ unless configuration.nil?
79
+ Rails.cache.write(
80
+ cache_key,
81
+ value,
82
+ expires_in: SolidusAfterpay.config.cache_expiry
83
+ )
84
+ end
85
+
86
+ value
87
+ end
55
88
  end
56
89
  end
@@ -13,7 +13,7 @@ module SolidusAfterpay
13
13
  def can_void?(payment)
14
14
  payment_method = payment.payment_method
15
15
 
16
- return false unless payment_method.preferred_deferred
16
+ return false if payment_method.auto_capture
17
17
 
18
18
  payment_state = payment_method.gateway.find_payment(order_id: payment.response_code).try(:[], :paymentState)
19
19
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAfterpay
4
+ class OrderPresenter
5
+ def initialize(order:)
6
+ @order = order
7
+ end
8
+
9
+ def line_items_tax_amount
10
+ order.line_item_adjustments.tax.eligible.sum(&:amount)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :order
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAfterpay
4
+ class ShippingRatePresenter
5
+ def initialize(shipping_rate:)
6
+ @shipping_rate = shipping_rate
7
+ end
8
+
9
+ def order_amount
10
+ shipping_rate.order.item_total.to_f +
11
+ shipping_rate.cost +
12
+ shipping_rate.taxes.sum(&:amount) +
13
+ order_presenter.line_items_tax_amount
14
+ end
15
+
16
+ def amount_with_taxes
17
+ shipping_rate.cost.to_f + shipping_rate.taxes.sum(&:amount)
18
+ end
19
+
20
+ private
21
+
22
+ def order_presenter
23
+ @order_presenter ||= SolidusAfterpay::OrderPresenter.new(order: shipping_rate.order)
24
+ end
25
+
26
+ attr_reader :shipping_rate
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAfterpay
4
+ class BaseService
5
+ def self.call(*args, **kws, &block)
6
+ new(*args, **kws, &block).call
7
+ end
8
+
9
+ def call
10
+ raise NotImplementedError
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAfterpay
4
+ class ShippingRateBuilderService < BaseService
5
+ def initialize(order:)
6
+ @order = order
7
+
8
+ super()
9
+ end
10
+
11
+ def call
12
+ order.shipments.map do |shipment|
13
+ shipment.shipping_rates.map do |rate|
14
+ shipping_rate_presenter = SolidusAfterpay::ShippingRatePresenter.new(shipping_rate: rate)
15
+
16
+ {
17
+ id: rate.id.to_s,
18
+ name: rate.name,
19
+ description: rate.display_price,
20
+ shipping_amount: shipping_rate_presenter.amount_with_taxes.round(4).to_s,
21
+ currency: rate.currency,
22
+ order_amount: shipping_rate_presenter.order_amount.round(4).to_s
23
+ }
24
+ end
25
+ end.flatten
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :order
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAfterpay
4
+ class UpdateOrderAddressesService < BaseService
5
+ def initialize(order:, address_params:)
6
+ @order = order
7
+ @address_params = address_params
8
+
9
+ super()
10
+ end
11
+
12
+ def call
13
+ order.state = 'address'
14
+ order.email = SolidusAfterpay.configuration.dummy_email if order.email.blank?
15
+ order.ship_address_attributes = address_object
16
+ order.bill_address_attributes = address_object
17
+ order.save
18
+ end
19
+
20
+ private
21
+
22
+ def address_object
23
+ {
24
+ address1: address_params[:address1],
25
+ address2: address_params[:address2],
26
+ name: address_params[:name],
27
+ city: address_params[:suburb],
28
+ zipcode: address_params[:postcode],
29
+ phone: address_params[:phoneNumber],
30
+ country: country,
31
+ state: state
32
+ }
33
+ end
34
+
35
+ def country
36
+ @country ||= ::Spree::Country.find_by(iso: address_params[:countryCode])
37
+ end
38
+
39
+ def state
40
+ @state ||= ::Spree::State.find_by(country_id: country.id, abbr: address_params[:state])
41
+ end
42
+
43
+ attr_reader :order, :address_params
44
+ end
45
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusAfterpay
4
+ class UpdateOrderAttributesService < BaseService
5
+ def initialize(order:, afterpay_order_token:, payment_method:, request_env:)
6
+ @order = order
7
+ @afterpay_order_token = afterpay_order_token
8
+ @payment_method = payment_method
9
+ @request_env = request_env
10
+
11
+ super()
12
+ end
13
+
14
+ def call
15
+ return false if afterpay_order.nil?
16
+
17
+ ::Spree::OrderUpdateAttributes.new(order, update_params, request_env: request_env).apply
18
+ end
19
+
20
+ private
21
+
22
+ def afterpay_order
23
+ @afterpay_order ||= payment_method.gateway.find_order(token: afterpay_order_token)
24
+ end
25
+
26
+ def shipping_rate
27
+ @shipping_rate ||= ::Spree::ShippingRate.find(afterpay_order.shippingOptionIdentifier.to_i)
28
+ end
29
+
30
+ def update_params
31
+ {
32
+ email: afterpay_order.consumer.email,
33
+ shipments_attributes: [{
34
+ selected_shipping_rate_id: shipping_rate.id,
35
+ id: shipping_rate.shipment.id
36
+ }],
37
+ payments_attributes: [{
38
+ payment_method_id: payment_method.id,
39
+ amount: afterpay_order.amount.amount,
40
+ source_attributes: {
41
+ token: afterpay_order_token
42
+ }
43
+ }]
44
+ }
45
+ end
46
+
47
+ attr_reader :order, :afterpay_order_token, :payment_method, :request_env
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ <% payment_method = SolidusAfterpay::PaymentMethod.active.first unless local_assigns[:payment_method] %>
2
+
3
+ <%= render partial: 'solidus_afterpay/afterpay_javascript', locals: { payment_method: payment_method } if Rails.env != "test" %>
4
+
5
+ <% if payment_method.present? && payment_method.available_for_order?(@order) %>
6
+ <button type="button" id="afterpay-button" data-afterpay-entry-point="cart" data-order-number="<%= @order.number %>" data-payment-method-id="<%= payment_method.id %>">
7
+ <%= I18n.t('solidus_afterpay.express_checkout.button') %>
8
+ </button>
9
+ <% end %>
@@ -1,5 +1,8 @@
1
+ <% payment_method = SolidusAfterpay::PaymentMethod.active.first unless local_assigns[:payment_method] %>
1
2
  <% if payment_method.present? %>
2
3
  <% content_for :head do %>
3
- <%= include_afterpay_js(test_mode: payment_method.preferred_test_mode) %>
4
+ <%= include_afterpay_js(
5
+ test_mode: payment_method.preferred_test_mode,
6
+ merchant_key: payment_method.preferred_merchant_key) %>
4
7
  <% end %>
5
8
  <% end %>
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.nil!
3
+ json.call(payment_source, :id, :token, :created_at)
@@ -1,13 +1,15 @@
1
- <% content_for :head do %>
2
- <script
3
- src="https://js.afterpay.com/afterpay-1.x.js"
4
- data-analytics-enabled
5
- async
6
- <% if max %>
7
- data-min="<%= min %>"
8
- data-max="<%= max %>"
9
- <% end %>
10
- ></script>
11
- <% end %>
1
+ <% if products.none? { |product| ::SolidusAfterpay::PaymentMethod.active.first.excluded_product?(product) } %>
2
+ <% content_for :head do %>
3
+ <script
4
+ src="https://js.afterpay.com/afterpay-1.x.js"
5
+ data-analytics-enabled
6
+ async
7
+ <% if max %>
8
+ data-min="<%= min %>"
9
+ data-max="<%= max %>"
10
+ <% end %>
11
+ ></script>
12
+ <% end %>
12
13
 
13
- <%= content_tag("afterpay-placement", nil, data: data) %>
14
+ <%= content_tag("afterpay-placement", nil, data: data) %>
15
+ <% end %>
@@ -10,3 +10,7 @@ en:
10
10
  resource_not_found: The resource you were looking for could not be found.
11
11
  order_token_not_found: Invalid order confirmation data passed in.
12
12
  unauthorized: You are not authorized to perform that action.
13
+ express_checkout:
14
+ errors:
15
+ unable_place_order: 'Unable to place the order!'
16
+ button: Checkout with Afterpay
data/config/routes.rb CHANGED
@@ -4,4 +4,6 @@ SolidusAfterpay::Engine.routes.draw do
4
4
  match '/callbacks/confirm', to: '/solidus_afterpay/callbacks#confirm', via: %i[get post]
5
5
  get '/callbacks/cancel', to: '/solidus_afterpay/callbacks#cancel'
6
6
  post '/checkouts', to: '/solidus_afterpay/checkouts#create'
7
+ patch '/express_callbacks/:order_number', to: '/solidus_afterpay/express_callbacks#update'
8
+ post '/express_callbacks/:order_number', to: '/solidus_afterpay/express_callbacks#create'
7
9
  end
@@ -2,4 +2,16 @@
2
2
 
3
3
  SolidusAfterpay.configure do |config|
4
4
  config.use_solidus_api = false
5
+ # A class that extend SolidusAfterpay::BaseService, respond to .call, accepting a Spree::Order
6
+ # and return an Afterpay shipping rate object (check the Afterpay documentation)
7
+ # config.shipping_rate_builder_service_class = 'SolidusAfterpay::ShippingRateBuilderService'
8
+
9
+ # A class that extend SolidusAfterpay::BaseService, respond to .call, accepting a Spree::Order
10
+ # and return true or false
11
+ # config.update_order_attributes_service_class = 'SolidusAfterpay::UpdateOrderAttributesService'
12
+
13
+ # There is a cache for retrieving the minimum amount, maximum amount and the currency from Afterpay
14
+ # the default value us set to 1.day, this is also recommended by Afterpay itself. If you prefer a shorter
15
+ # or longer time simply uncomment config.cache_expiry and add the preferred value.
16
+ # config.cache_expiry = 1.day
5
17
  end
@@ -3,6 +3,25 @@
3
3
  module SolidusAfterpay
4
4
  class Configuration
5
5
  attr_accessor :use_solidus_api
6
+ attr_writer :shipping_rate_builder_service_class, :cache_expiry
7
+
8
+ def dummy_email
9
+ 'afterpay@dummy.com'
10
+ end
11
+
12
+ def shipping_rate_builder_service_class
13
+ @shipping_rate_builder_service_class ||= 'SolidusAfterpay::ShippingRateBuilderService'
14
+ @shipping_rate_builder_service_class.constantize
15
+ end
16
+
17
+ def update_order_attributes_service_class
18
+ @update_order_attributes_service_class ||= 'SolidusAfterpay::UpdateOrderAttributesService'
19
+ @update_order_attributes_service_class.constantize
20
+ end
21
+
22
+ def cache_expiry
23
+ @cache_expiry ||= 1.day
24
+ end
6
25
  end
7
26
 
8
27
  class << self
@@ -21,5 +40,8 @@ module SolidusAfterpay
21
40
 
22
41
  SolidusAfterpay::BaseController
23
42
  end
43
+
44
+ delegate :shipping_rate_builder_service_class, to: :configuration
45
+ delegate :update_order_attributes_service_class, to: :configuration
24
46
  end
25
47
  end
@@ -18,3 +18,23 @@ FactoryBot.define do
18
18
  token { "12345678910" }
19
19
  end
20
20
  end
21
+
22
+ FactoryBot.define do
23
+ factory :order_with_variant_property, class: "Spree::Order", parent: :order_with_line_items do
24
+ after(:build) do |order|
25
+ variant_property_rule_value = create(:variant_property_rule_value, value: "2021-09-19",
26
+ property: create(:property, name: "estimatedShipmentDate"))
27
+ order.line_items.first.variant.product.variant_property_rules << variant_property_rule_value.variant_property_rule
28
+ order.line_items.first.variant.option_values << variant_property_rule_value.variant_property_rule
29
+ .option_values.first
30
+ end
31
+ end
32
+ end
33
+
34
+ FactoryBot.define do
35
+ factory :order_with_product_property, class: "Spree::Order", parent: :order_with_line_items do
36
+ after(:build) do |order|
37
+ order.line_items.first.product.set_property("estimatedShipmentDate", "2025-10-25")
38
+ end
39
+ end
40
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidusAfterpay
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
30
30
 
31
- spec.add_dependency 'afterpay', '~> 0.2.0'
31
+ spec.add_dependency 'afterpay', '~> 0.5.0'
32
32
  spec.add_dependency 'solidus_core', ['>= 2.0.0', '< 4']
33
33
  spec.add_dependency 'solidus_support', '~> 0.5'
34
34
 
@@ -0,0 +1,64 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://global-api-sandbox.afterpay.com/v2/checkouts/INVALID_TOKEN
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - SolidusAfterpay/0.1.0 (Solidus/3.1.0.alpha; Ruby/2.7.3; Merchant/100101481)
12
+ https://
13
+ Authorization:
14
+ - Basic <ENCODED_AUTH_HEADER>
15
+ Accept-Encoding:
16
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
17
+ Accept:
18
+ - "*/*"
19
+ response:
20
+ status:
21
+ code: 412
22
+ message: Precondition Failed
23
+ headers:
24
+ Date:
25
+ - Fri, 10 Sep 2021 12:55:37 GMT
26
+ Content-Type:
27
+ - application/json
28
+ Content-Length:
29
+ - '126'
30
+ Connection:
31
+ - keep-alive
32
+ Cf-Ray:
33
+ - 68c8cfcace07cd42-FCO
34
+ Cache-Control:
35
+ - private, no-cache, no-store, no-transform, must-revalidate, max-age=0
36
+ Strict-Transport-Security:
37
+ - max-age=31536000; includeSubDomains; preload
38
+ Cf-Cache-Status:
39
+ - DYNAMIC
40
+ Expect-Ct:
41
+ - max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
42
+ Http-Correlation-Id:
43
+ - n77tvm4ti5ngv6qbdz2o5vxan4
44
+ X-Envoy-Upstream-Service-Time:
45
+ - '9'
46
+ Set-Cookie:
47
+ - __cf_bm=u7iiZFdsOy9xrjOBMLoGsG1bhrLVARFRB1GlF.L_jLk-1631278537-0-ASztXHMHJmoTvt4gncQmxFsGkLaaD5ce0qXpvrva6GUGea4Y1iCdSXmzKOC2oEv/fB5Bj5W5TM3wHOEwof0LGNyGsWp0Oqb/cdPCJnsypwQJ;
48
+ path=/; expires=Fri, 10-Sep-21 13:25:37 GMT; domain=.afterpay.com; HttpOnly;
49
+ Secure; SameSite=None
50
+ Vary:
51
+ - Accept-Encoding
52
+ Server:
53
+ - cloudflare
54
+ body:
55
+ encoding: UTF-8
56
+ string: |-
57
+ {
58
+ "errorCode" : "invalid_token",
59
+ "errorId" : "632c34635772cf87",
60
+ "message" : "Invalid token",
61
+ "httpStatusCode" : 412
62
+ }
63
+ recorded_at: Fri, 10 Sep 2021 12:55:37 GMT
64
+ recorded_with: VCR 6.0.0
@@ -0,0 +1,120 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://global-api-sandbox.afterpay.com/v2/checkouts/002.cb9qevbs1o4el3adh817hqkotkbv4b8u1jkekofd3nb2m8lu
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - SolidusAfterpay/0.1.0 (Solidus/3.1.0.alpha; Ruby/2.7.3; Merchant/100101481)
12
+ https://
13
+ Authorization:
14
+ - Basic <ENCODED_AUTH_HEADER>
15
+ Accept-Encoding:
16
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
17
+ Accept:
18
+ - "*/*"
19
+ response:
20
+ status:
21
+ code: 200
22
+ message: OK
23
+ headers:
24
+ Date:
25
+ - Fri, 10 Sep 2021 12:55:37 GMT
26
+ Content-Type:
27
+ - application/json
28
+ Content-Length:
29
+ - '658'
30
+ Connection:
31
+ - keep-alive
32
+ Cf-Ray:
33
+ - 68c8cfcc9ab2cd22-FCO
34
+ Cache-Control:
35
+ - private, no-cache, no-store, no-transform, must-revalidate, max-age=0
36
+ Strict-Transport-Security:
37
+ - max-age=31536000; includeSubDomains; preload
38
+ Vary:
39
+ - Accept-Encoding
40
+ Cf-Cache-Status:
41
+ - DYNAMIC
42
+ Expect-Ct:
43
+ - max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
44
+ Http-Correlation-Id:
45
+ - rphr5wjy4lhxns243hqra4me7i
46
+ X-Envoy-Upstream-Service-Time:
47
+ - '10'
48
+ Set-Cookie:
49
+ - __cf_bm=QktDNLQZpZjhjrQQdeOBa7v_55ZFkHI18nQLWFQE6IE-1631278537-0-ASrEesj20zPAWBG+xXE/Kv0XFWsFTxlokJ+G3tawp7KedkMaZ08Sw78BcT+MQ1oDDQySJopfnSAXUwdlQ+canyDEGn3Q3nChBOb4BZyrwhky;
50
+ path=/; expires=Fri, 10-Sep-21 13:25:37 GMT; domain=.afterpay.com; HttpOnly;
51
+ Secure; SameSite=None
52
+ Server:
53
+ - cloudflare
54
+ body:
55
+ encoding: ASCII-8BIT
56
+ string: |-
57
+ {
58
+ "token" : "002.cb9qevbs1o4el3adh817hqkotkbv4b8u1jkekofd3nb2m8lu",
59
+ "expires" : "2021-09-10T15:54:05.463Z",
60
+ "redirectCheckoutUrl" : "https://portal.sandbox.afterpay.com/us/checkout/?token=002.cb9qevbs1o4el3adh817hqkotkbv4b8u1jkekofd3nb2m8lu",
61
+ "amount" : {
62
+ "amount" : "53.53",
63
+ "currency" : "USD"
64
+ },
65
+ "consumer" : {
66
+ "phoneNumber" : "",
67
+ "givenNames" : "John",
68
+ "surname" : "Doe",
69
+ "email" : "andreavassallo@nebulab.com"
70
+ },
71
+ "billing" : {
72
+ "name" : "John Doe",
73
+ "line1" : "8125 Centre St",
74
+ "line2" : "",
75
+ "area1" : "Citronelle",
76
+ "region" : "AL",
77
+ "postcode" : "36522",
78
+ "phoneNumber" : "12123234223"
79
+ },
80
+ "shipping" : {
81
+ "name" : "John Doe",
82
+ "line1" : "8125 Centre St",
83
+ "area1" : "Citronelle",
84
+ "region" : "AL",
85
+ "postcode" : "36522",
86
+ "countryCode" : "US",
87
+ "phoneNumber" : "12123234223"
88
+ },
89
+ "courier" : { },
90
+ "items" : [ {
91
+ "name" : "Solidus T-Shirt",
92
+ "sku" : "SOL-00003",
93
+ "quantity" : 1,
94
+ "price" : {
95
+ "amount" : "19.99",
96
+ "currency" : "USD"
97
+ }
98
+ }, {
99
+ "name" : "Solidus Snapback Cap",
100
+ "sku" : "SOL-SNC01",
101
+ "quantity" : 1,
102
+ "price" : {
103
+ "amount" : "15.99",
104
+ "currency" : "USD"
105
+ }
106
+ } ],
107
+ "merchant" : {
108
+ "redirectConfirmUrl" : "http://localhost:5000/solidus_afterpay/callbacks/confirm?order_number=R063381025&payment_method_id=4",
109
+ "redirectCancelUrl" : "http://localhost:5000/solidus_afterpay/callbacks/cancel?order_number=R063381025&payment_method_id=4",
110
+ "popupOriginUrl" : "http://localhost:5000/cart"
111
+ },
112
+ "discounts" : [ ],
113
+ "merchantReference" : "R063381025",
114
+ "shippingOptionIdentifier" : "999",
115
+ "shippingOptions" : {
116
+ "supportedShippingCountries" : [ ]
117
+ }
118
+ }
119
+ recorded_at: Fri, 10 Sep 2021 12:55:37 GMT
120
+ recorded_with: VCR 6.0.0
@@ -8,7 +8,15 @@ RSpec.describe SolidusAfterpay::AfterpayHelper, type: :helper do
8
8
  let(:test_mode) { false }
9
9
 
10
10
  it 'includes the production javascript' do
11
- is_expected.to eq('<script src="https://portal.afterpay.com/afterpay.js"></script>')
11
+ is_expected
12
+ .to eq(
13
+ <<-SCRIPT.squish
14
+ <script src="https://portal.afterpay.com/afterpay-async.js"
15
+ async="async"
16
+ defer="defer"
17
+ onload="initAfterpay()"></script>
18
+ SCRIPT
19
+ )
12
20
  end
13
21
  end
14
22
 
@@ -16,7 +24,15 @@ RSpec.describe SolidusAfterpay::AfterpayHelper, type: :helper do
16
24
  let(:test_mode) { true }
17
25
 
18
26
  it 'includes the sandbox javascript' do
19
- is_expected.to eq('<script src="https://portal.sandbox.afterpay.com/afterpay.js"></script>')
27
+ is_expected
28
+ .to eq(
29
+ <<-SCRIPT.squish
30
+ <script src="https://portal.sandbox.afterpay.com/afterpay-async.js"
31
+ async="async"
32
+ defer="defer"
33
+ onload="initAfterpay()"></script>
34
+ SCRIPT
35
+ )
20
36
  end
21
37
  end
22
38
  end