diff --git a/ghost/core/test/e2e-api/members/__snapshots__/create-stripe-checkout-session.test.js.snap b/ghost/core/test/e2e-api/members/__snapshots__/create-stripe-checkout-session.test.js.snap index 2f0d202b9f..2a2744c812 100644 --- a/ghost/core/test/e2e-api/members/__snapshots__/create-stripe-checkout-session.test.js.snap +++ b/ghost/core/test/e2e-api/members/__snapshots__/create-stripe-checkout-session.test.js.snap @@ -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", diff --git a/ghost/core/test/e2e-api/members/create-stripe-checkout-session.test.js b/ghost/core/test/e2e-api/members/create-stripe-checkout-session.test.js index 9ffc9eb6ba..0ffd5aaf4f 100644 --- a/ghost/core/test/e2e-api/members/create-stripe-checkout-session.test.js +++ b/ghost/core/test/e2e-api/members/create-stripe-checkout-session.test.js @@ -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'); diff --git a/ghost/payments/lib/payments.js b/ghost/payments/lib/payments.js index 1096dc61b2..d3a7218894 100644 --- a/ghost/payments/lib/payments.js +++ b/ghost/payments/lib/payments.js @@ -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({