Ghost/ghost/members-api/lib/services/stripe-plans/index.js
Fabien 'egg' O'Carroll e3ef01932f Refactor members-api (#231)
no-issue

This refactors the members-api module so that it is easier to test going forward,
as well as easier to understand & navigate. The Stripe API no longer contains
storage code, this is all handled via the member repository. And we have dedicated
services for webhooks, and stripe plans initialisation.
2021-01-18 13:55:40 +00:00

96 lines
2.7 KiB
JavaScript

/**
* @typedef {'usd'|'aud'|'cad'|'gbp'|'eur'|'inr'} Currency
*/
module.exports = class StripeService {
/**
* @param {object} deps
* @param {import('../stripe-api')} deps.stripeAPIService
*/
constructor({
stripeAPIService
}) {
this._stripeAPIService = stripeAPIService;
this._configured = false;
/** @type {import('stripe').products.IProduct} */
this._product = null;
/** @type {import('stripe').plans.IPlan[]} */
this._plans = null;
}
/**
* @returns {import('stripe').products.IProduct}
*/
getProduct() {
if (!this._configured) {
throw new Error('StripeService has not been configured');
}
return this._product;
}
/**
* @returns {import('stripe').plans.IPlan[]}
*/
getPlans() {
if (!this._configured) {
throw new Error('StripeService has not been configured');
}
return this._plans;
}
/**
* @param {string} nickname
* @returns {import('stripe').plans.IPlan}
*/
getPlan(nickname) {
if (!this._configured) {
throw new Error('StripeService has not been configured');
}
return this.getPlans().find((plan) => {
return plan.nickname.toLowerCase() === nickname.toLowerCase();
});
}
/**
* @param {Currency} currency
* @returns {import('stripe').plans.IPlan}
*/
getComplimentaryPlan(currency) {
if (!this._configured) {
throw new Error('StripeService has not been configured');
}
return this.getPlans().find((plan) => {
return plan.nickname.toLowerCase() === 'complimentary' && plan.currency === currency;
});
}
/**
* @param {object} config
* @param {object} config.product - The name for the product
* @param {string} config.product.name - The name for the product
*
* @param {object[]} config.plans
* @param {string} config.plans[].name
* @param {Currency} config.plans[].currency
* @param {'year'|'month'} config.plans[].interval
* @param {string} config.plans[].amount
*
* @returns {Promise<void>}
*/
async configure(config) {
try {
const product = await this._stripeAPIService.ensureProduct(config.product.name);
this._product = product;
this._plans = [];
for (const planSpec of config.plans) {
const plan = await this._stripeAPIService.ensurePlan(planSpec, product);
this._plans.push(plan);
}
this._configured = true;
} catch (err) {
console.log(err);
}
}
};