2849c647d6
no-issue This uses the webhook secret and stripe module to validate the signature and parse the body into an object
86 lines
2.8 KiB
JavaScript
86 lines
2.8 KiB
JavaScript
const api = require('./api');
|
|
|
|
module.exports = class StripePaymentProcessor {
|
|
constructor(config) {
|
|
this._ready = new Promise((resolve, reject) => {
|
|
this._resolveReady = resolve;
|
|
this._rejectReady = reject;
|
|
});
|
|
this._configure(config);
|
|
}
|
|
|
|
async ready() {
|
|
return this._ready;
|
|
}
|
|
|
|
async _configure(config) {
|
|
this._stripe = require('stripe')(config.secretKey);
|
|
this._stripe.__TEST_MODE__ = config.secretKey.startsWith('sk_test_');
|
|
this._public_token = config.publicKey;
|
|
this._checkoutSuccessUrl = config.checkoutSuccessUrl;
|
|
this._checkoutCancelUrl = config.checkoutCancelUrl;
|
|
this._webhookHandlerUrl = config.webhookHandlerUrl;
|
|
|
|
try {
|
|
this._product = await api.products.ensure(this._stripe, config.product);
|
|
|
|
this._plans = [];
|
|
for (const planSpec of config.plans) {
|
|
const plan = await api.plans.ensure(this._stripe, planSpec, this._product);
|
|
this._plans.push(plan);
|
|
}
|
|
|
|
try {
|
|
// @TODO Need to somehow not duplicate this every time we boot
|
|
const webhook = await create(this._stripe, 'webhookEndpoints', {
|
|
url: this._webhookHandlerUrl,
|
|
enabled_events: ['checkout.session.completed']
|
|
});
|
|
this._webhookSecret = webhook.secret;
|
|
} catch (err) {
|
|
console.log(err);
|
|
this._webhookSecret = process.env.WEBHOOK_SECRET;
|
|
}
|
|
} catch (err) {
|
|
return this._rejectReady(err);
|
|
}
|
|
|
|
return this._resolveReady({
|
|
product: this._product,
|
|
plans: this._plans
|
|
});
|
|
}
|
|
|
|
getPublicConfig() {
|
|
return {
|
|
publicKey: this._public_token,
|
|
plans: this._plans.map(({id, currency, amount, interval, nickname}) => ({
|
|
id, currency, amount, interval,
|
|
name: nickname
|
|
}))
|
|
};
|
|
}
|
|
|
|
async parseWebhook(body, signature) {
|
|
return this._stripe.webhooks.constructEvent(body, signature, this._webhookSecret);
|
|
}
|
|
|
|
async createCheckoutSession(member, planName) {
|
|
const customer = await api.customers.ensure(this._stripe, member, member.email);
|
|
const plan = this._plans.find(plan => plan.nickname === planName);
|
|
const session = await this._stripe.checkout.sessions.create({
|
|
payment_method_types: ['card'],
|
|
success_url: this._checkoutSuccessUrl,
|
|
cancel_url: this._checkoutCancelUrl,
|
|
customer: customer.id,
|
|
subscription_data: {
|
|
items: [{
|
|
plan: plan.id
|
|
}]
|
|
}
|
|
});
|
|
|
|
return session;
|
|
}
|
|
};
|