Skip to content
This repository was archived by the owner on Apr 19, 2022. It is now read-only.

Display and update shipping amount correctly #157

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ <h1>Order Summary</h1>
</div>
<div class="line-item shipping">
<p class="label">Shipping</p>
<p class="price">Free</p>
<p class="price" data-shipping></p>
</div>
<div class="line-item demo">
<div id="demo">
Expand Down
1 change: 1 addition & 0 deletions public/javascripts/payments.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
activeCurrency
);
updateSubmitButtonPayText(`Pay ${amount}`);
store.updateAmountSummary(activeCurrency);
});

// Create the Payment Request Button.
Expand Down
27 changes: 23 additions & 4 deletions public/javascripts/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -26,6 +27,11 @@ class Store {
);
}

async getDefaultShippingAmount() {
const config = await this.getConfig();
return config.shippingOptions[0].amount;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In practice shippingOptions[0] will just never be null or undefined?

}

// Expose the line items for the payment using products and skus stored in Stripe.
getLineItems() {
let items = [];
Expand Down Expand Up @@ -117,6 +123,8 @@ class Store {
items,
shippingOption
) {
this.shippingAmount = shippingOption.amount;

try {
const response = await fetch(
`/payment_intents/${paymentIntent}/shipping_change`,
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -218,10 +225,22 @@ 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);
orderTotal.querySelector('[data-shipping]').innerText = shippingAmount === 0 ? "Free" : this.formatPrice(shippingAmount, currency);
orderTotal.querySelector('[data-total]').innerText = this.formatPrice(total, currency);
}
}

Expand Down
3 changes: 2 additions & 1 deletion server/node/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
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
Expand Down
21 changes: 7 additions & 14 deletions server/ruby/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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'],
Expand Down
28 changes: 21 additions & 7 deletions server/ruby/inventory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -47,4 +61,4 @@ def self.products_exist(product_list)

product_list_data.length == 3 && products_present & valid_products == products_present
end
end
end