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

Commit

Permalink
Node: Decouple product setup. (#70)
Browse files Browse the repository at this point in the history
* Make server/node/setup.js standalone script.
* Remove product exist checking which relies on hardcoded product names.
* Run product setup script on postinstall hook.
  • Loading branch information
thorsten-stripe authored May 3, 2019
1 parent 8a53a10 commit dbc5841
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 94 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"node": "8.x"
},
"scripts": {
"start": "node server/node/server.js"
"start": "node server/node/server.js",
"setup-products": "node server/node/setup.js",
"postinstall": "npm run setup-products"
},
"dependencies": {
"body-parser": "^1.17.1",
Expand Down
5 changes: 5 additions & 0 deletions public/javascripts/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ class Store {
this.productsFetchPromise = new Promise(async resolve => {
const productsResponse = await fetch('/products');
const products = (await productsResponse.json()).data;
if (!products.length) {
throw new Error(
'No products on Stripe account! Make sure the setup script has run properly.'
);
}
// Check if we have SKUs on the product, otherwise load them separately.
for (const product of products) {
this.products[product.id] = product;
Expand Down
13 changes: 0 additions & 13 deletions server/node/inventory.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,6 @@ const retrieveProduct = async productId => {
return await stripe.products.retrieve(productId);
};

// Validate that products exist.
const productsExist = productList => {
const validProducts = ['increment', 'shirt', 'pins'];
return productList.data.reduce((accumulator, currentValue) => {
return (
accumulator &&
productList.data.length === 3 &&
validProducts.includes(currentValue.id)
);
}, !!productList.data.length);
};

// Get shipping cost from config based on selected shipping option.
const getShippingCost = shippingOption => {
return config.shippingOptions.filter(
Expand All @@ -47,6 +35,5 @@ const getShippingCost = shippingOption => {
exports.products = {
list: listProducts,
retrieve: retrieveProduct,
exist: productsExist,
getShippingCost,
};
11 changes: 1 addition & 10 deletions server/node/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
'use strict';

const config = require('./config');
const setup = require('./setup');
const {products} = require('./inventory');
const express = require('express');
const router = express.Router();
Expand Down Expand Up @@ -192,15 +191,7 @@ router.get('/config', (req, res) => {

// Retrieve all products.
router.get('/products', async (req, res) => {
const productList = await products.list();
// Check if products exist on Stripe Account.
if (products.exist(productList)) {
res.json(productList);
} else {
// We need to set up the products.
await setup.run();
res.json(await products.list());
}
res.json(await products.list());
});

// Retrieve a product by ID.
Expand Down
126 changes: 56 additions & 70 deletions server/node/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,76 +13,62 @@ const config = require('./config');
const stripe = require('stripe')(config.stripe.secretKey);
stripe.setApiVersion(config.stripe.apiVersion);

module.exports = {
running: false,
run: async () => {
if (this.running) {
console.log('⚠️ Setup already in progress.');
} else {
this.running = true;
this.promise = new Promise(async resolve => {
// Create a few products and SKUs assuming they don't already exist.
try {
// Increment Magazine.
const increment = await stripe.products.create({
id: 'increment',
type: 'good',
name: 'Increment Magazine',
attributes: ['issue'],
});
await stripe.skus.create({
id: 'increment-03',
product: 'increment',
attributes: {issue: 'Issue #3 “Development”'},
price: 399,
currency: config.currency,
inventory: {type: 'infinite'},
});
// Replace this list with information about your store's products.
const products = [
{
id: 'increment',
name: 'Increment Magazine',
price: 399,
attributes: {issue: 'Issue #3 “Development”'},
},
{
id: 'shirt',
name: 'Stripe Shirt',
price: 999,
attributes: {size: 'Small Standard', gender: 'Woman'},
},
{
id: 'pins',
name: 'Stripe Pins',
price: 799,
attributes: {set: 'Collector Set'},
},
];

// Stripe Shirt.
const shirt = await stripe.products.create({
id: 'shirt',
type: 'good',
name: 'Stripe Shirt',
attributes: ['size', 'gender'],
});
await stripe.skus.create({
id: 'shirt-small-woman',
product: 'shirt',
attributes: {size: 'Small Standard', gender: 'Woman'},
price: 999,
currency: config.currency,
inventory: {type: 'infinite'},
});
// Creates a collection of Stripe Products and SKUs to use in your storefront
const createStoreProducts = async () => {
try {
const stripeProducts = await Promise.all(
products.map(async product => {
const stripeProduct = await stripe.products.create({
id: product.id,
name: product.name,
type: 'good',
attributes: Object.keys(product.attributes),
metadata: product.metadata,
});

// Stripe Pins.
const pins = await stripe.products.create({
id: 'pins',
type: 'good',
name: 'Stripe Pins',
attributes: ['set'],
});
await stripe.skus.create({
id: 'pins-collector',
product: 'pins',
attributes: {set: 'Collector Set'},
price: 799,
currency: config.currency,
inventory: {type: 'finite', quantity: 500},
});
console.log('Setup complete.');
resolve();
this.running = false;
} catch (err) {
if (err.message === 'Product already exists.') {
console.log('⚠️ Products have already been registered.');
console.log('Delete them from your Dashboard to run this setup.');
} else {
console.log('⚠️ An error occurred.', err);
}
}
});
}
return this.promise;
},
const stripeSku = await stripe.skus.create({
product: stripeProduct.id,
price: product.price,
currency: config.currency,
attributes: product.attributes,
inventory: {type: 'infinite'},
});

return {stripeProduct, stripeSku};
})
);

console.log(
`🛍️ Successfully created ${
stripeProducts.length
} products on your Stripe account.`
);
} catch (error) {
console.log(`⚠️ Error: ${error.message}`);
return;
}
};

createStoreProducts();

0 comments on commit dbc5841

Please sign in to comment.