🐛 Fixed upgrading to a paid plan
closes https://github.com/TryGhost/Team/issues/2196 We were incorrectly assuming that all requests would have the `customerEmail` passed in the body. Instead we were incorrectly passing `undefined` or `''` as the `customerEmail` property to stripe, which resulted in a validation error. We've updated the code to pass `null` in the case of a falsy value, which the Stripe API handles without error.
This commit is contained in:
parent
1f300fb781
commit
ba41f308c7
@ -16,6 +16,22 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Create Stripe Checkout Session Can create a checkout session without passing a customerEmail 1: [body] 1`] = `
|
||||
Object {
|
||||
"url": "https://site.com",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Create Stripe Checkout Session Can create a checkout session without passing a customerEmail 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-type": "application/json",
|
||||
"vary": "Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Create Stripe Checkout Session Does allow to create a checkout session if the customerEmail is not associated with a paid member 1: [body] 1`] = `
|
||||
Object {
|
||||
"url": "https://site.com",
|
||||
|
@ -1,3 +1,4 @@
|
||||
const querystring = require('querystring');
|
||||
const {agentProvider, mockManager, fixtureManager, matchers} = require('../../utils/e2e-framework');
|
||||
const nock = require('nock');
|
||||
const should = require('should');
|
||||
@ -127,6 +128,61 @@ describe('Create Stripe Checkout Session', function () {
|
||||
.matchHeaderSnapshot();
|
||||
});
|
||||
|
||||
it('Can create a checkout session without passing a customerEmail', async function () {
|
||||
const {body: {tiers}} = await adminAgent.get('/tiers/?include=monthly_price&yearly_price');
|
||||
|
||||
const paidTier = tiers.find(tier => tier.type === 'paid');
|
||||
|
||||
nock('https://api.stripe.com')
|
||||
.persist()
|
||||
.get(/v1\/.*/)
|
||||
.reply((uri, body) => {
|
||||
const [match, resource, id] = uri.match(/\/v1\/(\w+)\/(.+)\/?/) || [null];
|
||||
if (match) {
|
||||
if (resource === 'products') {
|
||||
return [200, {
|
||||
id: id,
|
||||
active: true
|
||||
}];
|
||||
}
|
||||
if (resource === 'prices') {
|
||||
return [200, {
|
||||
id: id,
|
||||
active: true,
|
||||
currency: 'usd',
|
||||
unit_amount: 500
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
return [500];
|
||||
});
|
||||
|
||||
nock('https://api.stripe.com')
|
||||
.persist()
|
||||
.post(/v1\/.*/)
|
||||
.reply((uri, body) => {
|
||||
if (uri === '/v1/checkout/sessions') {
|
||||
const bodyJSON = querystring.parse(body);
|
||||
// TODO: Actually work out what Stripe checks and when/how it errors
|
||||
if (bodyJSON.customerEmail) {
|
||||
return [400, {error: 'Invalid Email'}];
|
||||
}
|
||||
return [200, {id: 'cs_123', url: 'https://site.com'}];
|
||||
}
|
||||
|
||||
return [500];
|
||||
});
|
||||
|
||||
await membersAgent.post('/api/create-stripe-checkout-session/')
|
||||
.body({
|
||||
tierId: paidTier.id,
|
||||
cadence: 'month'
|
||||
})
|
||||
.expectStatus(200)
|
||||
.matchBodySnapshot()
|
||||
.matchHeaderSnapshot();
|
||||
});
|
||||
it('Does allow to create a checkout session if the customerEmail is not associated with a paid member', async function () {
|
||||
const {body: {tiers}} = await adminAgent.get('/tiers/?include=monthly_price&yearly_price');
|
||||
|
||||
|
@ -86,11 +86,13 @@ class PaymentsService {
|
||||
|
||||
const price = await this.getPriceForTierCadence(tier, cadence);
|
||||
|
||||
const email = options.email || null;
|
||||
|
||||
const session = await this.stripeAPIService.createCheckoutSession(price.id, customer, {
|
||||
metadata,
|
||||
successUrl: options.successUrl,
|
||||
cancelUrl: options.cancelUrl,
|
||||
customerEmail: options.email,
|
||||
customerEmail: customer ? email : null,
|
||||
trialDays: trialDays ?? tier.trialDays,
|
||||
coupon: coupon?.id
|
||||
});
|
||||
@ -119,8 +121,8 @@ class PaymentsService {
|
||||
|
||||
async createCustomerForMember(member) {
|
||||
const customer = await this.stripeAPIService.createCustomer({
|
||||
email: member.email,
|
||||
name: member.name
|
||||
email: member.get('email'),
|
||||
name: member.get('name')
|
||||
});
|
||||
|
||||
await this.StripeCustomerModel.add({
|
||||
|
Loading…
Reference in New Issue
Block a user