Create Stripe Subscriptions on startup if requested

This commit is contained in:
Justin Reynolds 2018-02-03 13:17:04 -06:00
parent f51eda2d6c
commit 7e4cce29cb
10 changed files with 78 additions and 22 deletions

View file

@ -32,7 +32,8 @@ As well as the following private setting (can be stored in the setting's root or
}
},
"stripe": {
"secretKey": "sk_test_sfdhj34jdsfxhjs234sd0K"
"secretKey": "sk_test_sfdhj34jdsfxhjs234sd0K",
"createPlans": false
},
}
```

View file

@ -1,9 +1,4 @@
/*
The main Comments collection definition file.
*/
// The main Charges collection definition file.
import { createCollection } from 'meteor/vulcan:core';
import schema from './schema.js';
@ -23,7 +18,7 @@ const Charges = createCollection({
Charges.addDefaultView(terms => {
return {
options: {sort: {createdAt: -1}}
options: { sort: { createdAt: -1 } }
};
});

View file

@ -15,7 +15,7 @@ const schema = {
viewableBy: ['guests'],
onInsert: (document, currentUser) => {
return new Date();
}
},
},
userId: {
type: String,

View file

@ -6,6 +6,6 @@ Users.addField([
fieldSchema: {
type: String,
optional: true,
}
}
},
},
]);

View file

@ -2,5 +2,5 @@ import { addStrings } from 'meteor/vulcan:core';
addStrings('en', {
'payments.payment_succeeded': 'Thanks, your payment has succeeded.',
'payments.error': 'Sorry, something went wrong.'
});
'payments.error': 'Sorry, something went wrong.',
});

View file

@ -6,4 +6,4 @@ import './routes.js';
import './i18n.js';
import './custom_fields.js';
export * from './products.js'
export * from './products.js'

View file

@ -1,5 +1,5 @@
export const Products = {}
export const Products = {};
export const addProduct = (productKey, product) => {
Products[productKey] = product;
}
};

View file

@ -2,4 +2,4 @@ import { addRoute } from 'meteor/vulcan:core';
addRoute([
{name:'checkoutTest', path: '/checkout-test', componentName: 'Checkout'},
]);
]);

View file

@ -5,6 +5,7 @@ import Charges from '../../modules/charges/collection.js';
import Users from 'meteor/vulcan:users';
import { Products } from '../../modules/products.js';
import { webAppConnectHandlersUse } from 'meteor/vulcan:core';
import { Promise } from 'meteor/promise';
registerSetting('stripe', null, 'Stripe settings');
@ -19,7 +20,7 @@ const sampleProduct = {
name: 'My Cool Product',
description: 'This product is awesome.',
currency: 'USD',
}
};
/*
@ -251,7 +252,47 @@ export const subscribeUser = async ({user, customer, product, collection, docume
// eslint-disable-next-line no-console
console.log(error);
}
}
};
// create a stripe plan
// plan is used as the unique ID and is not needed for creating a plan
export const createPlan = async ({
// Extract all the known properties for the stripe api
// Evertying else goes in the metadata field
plan: id,
currency,
interval,
name,
amount,
interval_count,
statement_descriptor,
...metadata
}) => stripe.plans.create({
id,
currency,
interval,
name,
amount,
interval_count,
statement_descriptor,
...metadata
});
export const retrievePlan = async (planObject) => stripe.plans.retrieve(planObject.plan);
export const createOrRetrievePlan = async (planObject) => {
return retrievePlan(planObject)
.catch(error => {
// Plan does not exist, create it
if (error.statusCode === 404) {
// eslint-disable-next-line no-console
console.log(`Creating subscription plan ${planObject.plan} for ${(planObject.amount && (planObject.amount / 100).toLocaleString('en-US', { style: 'currency', currency })) || 'free'}`);
return createPlan(planObject);
}
// Something else went wrong
// eslint-disable-next-line no-console
console.error(error);
throw error;
});
};
/*
@ -262,7 +303,7 @@ Webhooks with Express
// see https://github.com/stripe/stripe-node/blob/master/examples/webhook-signing/express.js
const app = express()
const app = express();
// Add the raw text body of the request to the `request` object
function addRawBody(req, res, next) {
@ -466,5 +507,23 @@ Meteor.startup(() => {
runs: 'async',
});
})
})
});
// Create plans if they don't exist
if (stripeSettings.createPlans) {
// eslint-disable-next-line no-console
console.log('Creating stripe plans...');
Promise.awaitAll(Object.keys(Products)
// Return the object
.map(productKey => {
const definedProduct = Products[productKey];
const product = typeof definedProduct === 'function' ? definedProduct(document) : definedProduct || sampleProduct;
return product;
})
// Find only products that have a plan defined
.filter(productObject => productObject.plan)
.map(planObject => createOrRetrievePlan(planObject)));
// eslint-disable-next-line no-console
console.log('Finished creating stripe plans.');
}
});

View file

@ -10,6 +10,7 @@ Package.onUse(function (api) {
api.versionsFrom('1.6.1');
api.use([
'promise',
'vulcan:core@1.8.9',
'fourseven:scss@4.5.4',