From 1279de711e8bed3ba097cc03ce10d06c2f6cd043 Mon Sep 17 00:00:00 2001 From: James Willock Date: Wed, 28 Oct 2020 09:52:53 +0000 Subject: [PATCH 1/3] Display and update shipping amount correctly --- public/index.html | 2 +- public/javascripts/payments.js | 1 + public/javascripts/store.js | 33 +++++++++++++++++++++++++++++---- server/node/routes.js | 3 ++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/public/index.html b/public/index.html index 11a940ba..bdcca13c 100644 --- a/public/index.html +++ b/public/index.html @@ -241,7 +241,7 @@

Order Summary

Shipping

-

Free

+

diff --git a/public/javascripts/payments.js b/public/javascripts/payments.js index 607b7a1f..7ab77ecd 100644 --- a/public/javascripts/payments.js +++ b/public/javascripts/payments.js @@ -246,6 +246,7 @@ activeCurrency ); updateSubmitButtonPayText(`Pay ${amount}`); + store.updateAmountSummary(activeCurrency); }); // Create the Payment Request Button. diff --git a/public/javascripts/store.js b/public/javascripts/store.js index 26c99599..130c131b 100644 --- a/public/javascripts/store.js +++ b/public/javascripts/store.js @@ -15,6 +15,7 @@ class Store { this.products = {}; this.productsFetchPromise = null; this.displayPaymentSummary(); + this.shippingAmount = null; } // Compute the total for the payment based on the line items (SKUs and quantity). @@ -26,6 +27,11 @@ class Store { ); } + async getDefaultShippingAmount() { + const config = await this.getConfig(); + return config.shippingOptions[0].amount; + } + // Expose the line items for the payment using products and skus stored in Stripe. getLineItems() { let items = []; @@ -117,6 +123,8 @@ class Store { items, shippingOption ) { + this.shippingAmount = shippingOption.amount; + try { const response = await fetch( `/payment_intents/${paymentIntent}/shipping_change`, @@ -187,7 +195,6 @@ class Store { // Fetch the products from the store to get all the details (name, price, etc.). await this.loadProducts(); const orderItems = document.getElementById('order-items'); - const orderTotal = document.getElementById('order-total'); let currency; // Build and append the line items to the payment summary. for (let [id, product] of Object.entries(this.products)) { @@ -218,10 +225,28 @@ class Store { quantity, }); } + + await this.updateAmountSummary(currency); + } + + async updateAmountSummary(currency) { + const orderTotal = document.getElementById('order-total'); + + // Fetch shipping amount and subtotal to calculate total + const shippingAmount = this.shippingAmount || await this.getDefaultShippingAmount(); + const subTotal = this.getPaymentTotal(); + const total = shippingAmount + subTotal; + // Add the subtotal and total to the payment summary. - const total = this.formatPrice(this.getPaymentTotal(), currency); - orderTotal.querySelector('[data-subtotal]').innerText = total; - orderTotal.querySelector('[data-total]').innerText = total; + orderTotal.querySelector('[data-subtotal]').innerText = this.formatPrice(subTotal, currency); + + if (shippingAmount === 0) { + orderTotal.querySelector('[data-shipping]').innerText = "Free"; + } else { + orderTotal.querySelector('[data-shipping]').innerText = this.formatPrice(shippingAmount, currency); + } + + orderTotal.querySelector('[data-total]').innerText = this.formatPrice(total, currency); } } diff --git a/server/node/routes.js b/server/node/routes.js index 19c92bec..cf104a8a 100644 --- a/server/node/routes.js +++ b/server/node/routes.js @@ -50,7 +50,8 @@ const calculatePaymentAmount = async items => { // Create the PaymentIntent on the backend. router.post('/payment_intents', async (req, res, next) => { let {currency, items} = req.body; - const amount = await calculatePaymentAmount(items); + let amount = await calculatePaymentAmount(items); + amount += products.getShippingCost(config.shippingOptions[0].id); try { //build initial payment methods which should exclude currency specific ones From 3382b71fa239030cc8e020930d542dea4470ae1a Mon Sep 17 00:00:00 2001 From: James Willock Date: Wed, 28 Oct 2020 13:21:03 +0000 Subject: [PATCH 2/3] PR comments --- public/javascripts/store.js | 8 +------- server/node/routes.js | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/public/javascripts/store.js b/public/javascripts/store.js index 130c131b..7c5d91a9 100644 --- a/public/javascripts/store.js +++ b/public/javascripts/store.js @@ -239,13 +239,7 @@ class Store { // Add the subtotal and total to the payment summary. orderTotal.querySelector('[data-subtotal]').innerText = this.formatPrice(subTotal, currency); - - if (shippingAmount === 0) { - orderTotal.querySelector('[data-shipping]').innerText = "Free"; - } else { - orderTotal.querySelector('[data-shipping]').innerText = this.formatPrice(shippingAmount, currency); - } - + orderTotal.querySelector('[data-shipping]').innerText = shippingAmount === 0 ? "Free" : this.formatPrice(shippingAmount, currency); orderTotal.querySelector('[data-total]').innerText = this.formatPrice(total, currency); } } diff --git a/server/node/routes.js b/server/node/routes.js index cf104a8a..71ec035e 100644 --- a/server/node/routes.js +++ b/server/node/routes.js @@ -50,8 +50,8 @@ const calculatePaymentAmount = async items => { // Create the PaymentIntent on the backend. router.post('/payment_intents', async (req, res, next) => { let {currency, items} = req.body; - let amount = await calculatePaymentAmount(items); - amount += products.getShippingCost(config.shippingOptions[0].id); + const shippingCost = products.getShippingCost(config.shippingOptions[0].id); + const amount = await calculatePaymentAmount(items) + shippingCost; try { //build initial payment methods which should exclude currency specific ones From 7f514c891b77ffa8199cd167c0aa650ffaaeffac Mon Sep 17 00:00:00 2001 From: James Willock Date: Wed, 28 Oct 2020 13:53:58 +0000 Subject: [PATCH 3/3] Update Ruby server implementation for shipping costs --- server/ruby/app.rb | 21 +++++++-------------- server/ruby/inventory.rb | 28 +++++++++++++++++++++------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/server/ruby/app.rb b/server/ruby/app.rb index 40004f74..1e7cf756 100644 --- a/server/ruby/app.rb +++ b/server/ruby/app.rb @@ -50,20 +50,7 @@ 'country': 'US', 'currency': 'eur', 'paymentMethods': ENV['PAYMENT_METHODS'] ? ENV['PAYMENT_METHODS'].split(', ') : ['card'], - 'shippingOptions': [ - { - 'id': 'free', - 'label': 'Free Shipping', - 'detail': 'Delivery within 5 days', - 'amount': 0, - }, - { - 'id': 'express', - 'label': 'Express Shipping', - 'detail': 'Next day delivery', - 'amount': 500, - } - ] + 'shippingOptions': Inventory.shipping_options, }.to_json end @@ -101,6 +88,12 @@ init_payment_methods = ENV['PAYMENT_METHODS'] ? ENV['PAYMENT_METHODS'].split(', ') : ['card'] init_payment_methods.delete('au_becs_debit') + # calculate amount + amount = Inventory.calculate_payment_amount(data['items']) + amount += Inventory.get_shipping_cost( + Inventory.shipping_options.first[:id] + ) + payment_intent = Stripe::PaymentIntent.create( amount: Inventory.calculate_payment_amount(data['items']), currency: data['currency'], diff --git a/server/ruby/inventory.rb b/server/ruby/inventory.rb index 718e5565..bda939c4 100644 --- a/server/ruby/inventory.rb +++ b/server/ruby/inventory.rb @@ -8,6 +8,23 @@ class Inventory + def self.shipping_options + [ + { + id: 'free', + label: 'Free Shipping', + detail: 'Delivery within 5 days', + amount: 0, + }, + { + id: 'express', + label: 'Express Shipping', + detail: 'Next day delivery', + amount: 500, + } + ] + end + def self.calculate_payment_amount(items) total = 0 items.each do |item| @@ -18,11 +35,8 @@ def self.calculate_payment_amount(items) end def self.get_shipping_cost(id) - shipping_cost = { - free: 0, - express: 500, - } - shipping_cost[id.to_sym] + option = shipping_options.find { |option| option[:id] == id.to_sym } + option[:amount] end def self.list_products @@ -33,7 +47,7 @@ def self.list_skus(product_id) Stripe::SKU.list( limit: 1, product: product_id - ) + ) end def self.retrieve_product(product_id) @@ -47,4 +61,4 @@ def self.products_exist(product_list) product_list_data.length == 3 && products_present & valid_products == products_present end -end \ No newline at end of file +end