mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
🐛 Fixed checkout sessions when using Offers
closes https://github.com/TryGhost/Team/issues/2195 The issue here is two-fold, and specific to using Offers so was not caught by any automated tests. First, we were incorrectly comparing the tier.id to the offer.tier.id - this is because the Tier objects id property is an instance of ObjectID rather than a string. Secondly we were passing through the cadence parameter from the request body, but when using Offers this is not including in the request, so we must pull the data off of the Offer object instead and pass that to the payments service.
This commit is contained in:
parent
3c71d07dfb
commit
1f300fb781
4 changed files with 91 additions and 2 deletions
|
@ -1,5 +1,21 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Create Stripe Checkout Session Can create a checkout session when using offers 1: [body] 1`] = `
|
||||||
|
Object {
|
||||||
|
"url": "https://site.com",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Create Stripe Checkout Session Can create a checkout session when using offers 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`] = `
|
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 {
|
Object {
|
||||||
"url": "https://site.com",
|
"url": "https://site.com",
|
||||||
|
|
|
@ -55,6 +55,78 @@ describe('Create Stripe Checkout Session', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Can create a checkout session when using offers', async function () {
|
||||||
|
const {body: {tiers}} = await adminAgent.get('/tiers/?include=monthly_price&yearly_price');
|
||||||
|
const paidTier = tiers.find(tier => tier.type === 'paid');
|
||||||
|
const {body: {offers: [offer]}} = await adminAgent.post('/offers/').body({
|
||||||
|
offers: [{
|
||||||
|
name: 'Test Offer',
|
||||||
|
code: 'test-offer',
|
||||||
|
cadence: 'month',
|
||||||
|
status: 'active',
|
||||||
|
currency: 'usd',
|
||||||
|
type: 'percent',
|
||||||
|
amount: 20,
|
||||||
|
duration: 'once',
|
||||||
|
duration_in_months: null,
|
||||||
|
display_title: 'Test Offer',
|
||||||
|
display_description: null,
|
||||||
|
tier: {
|
||||||
|
id: paidTier.id
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
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') {
|
||||||
|
return [200, {id: 'cs_123', url: 'https://site.com'}];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uri === '/v1/coupons') {
|
||||||
|
return [200, {id: 'coupon_123', url: 'https://site.com'}];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [500];
|
||||||
|
});
|
||||||
|
|
||||||
|
await membersAgent.post('/api/create-stripe-checkout-session/')
|
||||||
|
.body({
|
||||||
|
customerEmail: 'free@test.com',
|
||||||
|
offerId: offer.id
|
||||||
|
})
|
||||||
|
.expectStatus(200)
|
||||||
|
.matchBodySnapshot()
|
||||||
|
.matchHeaderSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
it('Does allow to create a checkout session if the customerEmail is not associated with a paid member', async function () {
|
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');
|
const {body: {tiers}} = await adminAgent.get('/tiers/?include=monthly_price&yearly_price');
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ module.exports = class RouterController {
|
||||||
async createCheckoutSession(req, res) {
|
async createCheckoutSession(req, res) {
|
||||||
let ghostPriceId = req.body.priceId;
|
let ghostPriceId = req.body.priceId;
|
||||||
const tierId = req.body.tierId;
|
const tierId = req.body.tierId;
|
||||||
const cadence = req.body.cadence;
|
let cadence = req.body.cadence;
|
||||||
const identity = req.body.identity;
|
const identity = req.body.identity;
|
||||||
const offerId = req.body.offerId;
|
const offerId = req.body.offerId;
|
||||||
const metadata = req.body.metadata ?? {};
|
const metadata = req.body.metadata ?? {};
|
||||||
|
@ -185,6 +185,7 @@ module.exports = class RouterController {
|
||||||
if (offerId) {
|
if (offerId) {
|
||||||
offer = await this._offersAPI.getOffer({id: offerId});
|
offer = await this._offersAPI.getOffer({id: offerId});
|
||||||
tier = await this._tiersService.api.read(offer.tier.id);
|
tier = await this._tiersService.api.read(offer.tier.id);
|
||||||
|
cadence = offer.cadence;
|
||||||
} else {
|
} else {
|
||||||
offer = null;
|
offer = null;
|
||||||
tier = await this._tiersService.api.read(tierId);
|
tier = await this._tiersService.api.read(tierId);
|
||||||
|
|
|
@ -67,7 +67,7 @@ class PaymentsService {
|
||||||
let coupon = null;
|
let coupon = null;
|
||||||
let trialDays = null;
|
let trialDays = null;
|
||||||
if (offer) {
|
if (offer) {
|
||||||
if (offer.tier.id !== tier.id) {
|
if (!tier.id.equals(offer.tier.id)) {
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
message: 'This Offer is not valid for the Tier'
|
message: 'This Offer is not valid for the Tier'
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue