mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Updated setup wizard pricing to use new product API
refs https://github.com/TryGhost/Team/issues/721 The setup wizard in Admin handles creating default prices as well as handling new price changes on default Product. This change updates the handling to use updated Products API with support for `monthly/yearly_price` values that offloads price handling to backend and makes the logic simpler. Also updates the stripe connect flow to use new API for creating default prices.
This commit is contained in:
parent
2b13bfea98
commit
d4cb7f9d1d
3 changed files with 50 additions and 163 deletions
|
@ -80,17 +80,6 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
updatePortalPlans(monthlyPriceId, yearlyPriceId) {
|
||||
let portalPlans = ['free'];
|
||||
if (monthlyPriceId) {
|
||||
portalPlans.push(monthlyPriceId);
|
||||
}
|
||||
if (yearlyPriceId) {
|
||||
portalPlans.push(yearlyPriceId);
|
||||
}
|
||||
this.settings.set('portalPlans', portalPlans);
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*saveProduct() {
|
||||
let pollTimeout = 0;
|
||||
|
@ -169,13 +158,11 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
|||
try {
|
||||
yield this.settings.save();
|
||||
|
||||
const products = yield this.store.query('product', {include: 'stripe_prices'});
|
||||
const products = yield this.store.query('product', {include: 'monthly_price,yearly_price'});
|
||||
this.product = products.firstObject;
|
||||
if (this.product) {
|
||||
const stripePrices = this.product.stripePrices || [];
|
||||
const yearlyDiscount = this.calculateDiscount(5, 50);
|
||||
stripePrices.push(
|
||||
{
|
||||
this.product.set('monthlyPrice', {
|
||||
nickname: 'Monthly',
|
||||
amount: 500,
|
||||
active: 1,
|
||||
|
@ -183,8 +170,8 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
|||
currency: 'usd',
|
||||
interval: 'month',
|
||||
type: 'recurring'
|
||||
},
|
||||
{
|
||||
});
|
||||
this.product.set('yearlyPrice', {
|
||||
nickname: 'Yearly',
|
||||
amount: 5000,
|
||||
active: 1,
|
||||
|
@ -192,15 +179,9 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
|||
description: yearlyDiscount > 0 ? `${yearlyDiscount}% discount` : 'Full access',
|
||||
interval: 'year',
|
||||
type: 'recurring'
|
||||
}
|
||||
);
|
||||
this.product.set('stripePrices', stripePrices);
|
||||
const updatedProduct = yield this.saveProduct.perform();
|
||||
const monthlyPrice = this.getActivePrice(updatedProduct.stripePrices, 'month', 500, 'usd');
|
||||
const yearlyPrice = this.getActivePrice(updatedProduct.stripePrices, 'year', 5000, 'usd');
|
||||
this.updatePortalPlans(monthlyPrice.id, yearlyPrice.id);
|
||||
this.settings.set('membersMonthlyPriceId', monthlyPrice.id);
|
||||
this.settings.set('membersYearlyPriceId', yearlyPrice.id);
|
||||
});
|
||||
yield this.saveProduct.perform();
|
||||
this.settings.set('portalPlans', ['free', 'monthly', 'yearly']);
|
||||
yield this.settings.save();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,91 +14,35 @@ export default class GhLaunchWizardFinaliseComponent extends Component {
|
|||
this.settings.rollbackAttributes();
|
||||
}
|
||||
|
||||
updatePortalPlans(monthlyPriceId, yearlyPriceId, data) {
|
||||
let portalPlans = this.settings.get('portalPlans') || [];
|
||||
const currentMontlyPriceId = this.settings.get('membersMonthlyPriceId');
|
||||
const currentYearlyPriceId = this.settings.get('membersYearlyPriceId');
|
||||
if (portalPlans.includes(currentMontlyPriceId)) {
|
||||
portalPlans = portalPlans.filter(priceId => priceId !== currentMontlyPriceId);
|
||||
}
|
||||
if (data.isMonthlyChecked) {
|
||||
portalPlans.pushObject(monthlyPriceId);
|
||||
}
|
||||
|
||||
if (portalPlans.includes(currentYearlyPriceId)) {
|
||||
portalPlans = portalPlans.filter(priceId => priceId !== currentYearlyPriceId);
|
||||
}
|
||||
if (data.isYearlyChecked) {
|
||||
portalPlans.pushObject(yearlyPriceId);
|
||||
}
|
||||
portalPlans = portalPlans.filter(priceId => priceId !== 'free');
|
||||
if (data.isFreeChecked) {
|
||||
portalPlans.pushObject('free');
|
||||
}
|
||||
this.settings.set('portalPlans', portalPlans);
|
||||
}
|
||||
|
||||
async saveProduct() {
|
||||
const data = this.args.getData();
|
||||
this.product = data?.product;
|
||||
if (this.product) {
|
||||
const stripePrices = this.product.stripePrices || [];
|
||||
const monthlyAmount = data.monthlyAmount * 100;
|
||||
const yearlyAmount = data.yearlyAmount * 100;
|
||||
const currency = data.currency;
|
||||
const getActivePrice = (prices, type, amount) => {
|
||||
return prices.find((price) => {
|
||||
return (
|
||||
price.active && price.amount === amount && price.type === 'recurring' &&
|
||||
price.interval === type && price.currency.toLowerCase() === currency.toLowerCase()
|
||||
);
|
||||
});
|
||||
};
|
||||
const monthlyPrice = getActivePrice(stripePrices, 'month', monthlyAmount);
|
||||
const yearlyPrice = getActivePrice(stripePrices, 'year', yearlyAmount);
|
||||
|
||||
if (!monthlyPrice) {
|
||||
stripePrices.push(
|
||||
{
|
||||
const monthlyPrice = {
|
||||
nickname: 'Monthly',
|
||||
amount: monthlyAmount,
|
||||
active: 1,
|
||||
currency: currency,
|
||||
interval: 'month',
|
||||
type: 'recurring'
|
||||
}
|
||||
);
|
||||
}
|
||||
if (!yearlyPrice) {
|
||||
stripePrices.push(
|
||||
{
|
||||
};
|
||||
const yearlyPrice = {
|
||||
nickname: 'Yearly',
|
||||
amount: yearlyAmount,
|
||||
active: 1,
|
||||
currency: currency,
|
||||
interval: 'year',
|
||||
type: 'recurring'
|
||||
}
|
||||
);
|
||||
}
|
||||
if (monthlyPrice && yearlyPrice) {
|
||||
this.updatePortalPlans(monthlyPrice.id, yearlyPrice.id, data);
|
||||
this.settings.set('membersMonthlyPriceId', monthlyPrice.id);
|
||||
this.settings.set('membersYearlyPriceId', yearlyPrice.id);
|
||||
return this.product;
|
||||
} else {
|
||||
this.product.set('stripePrices', stripePrices);
|
||||
};
|
||||
this.product.set('monthlyPrice', monthlyPrice);
|
||||
this.product.set('yearlyPrice', yearlyPrice);
|
||||
const savedProduct = await this.product.save();
|
||||
const updatedStripePrices = savedProduct.stripePrices || [];
|
||||
const updatedMonthlyPrice = getActivePrice(updatedStripePrices, 'month', monthlyAmount);
|
||||
const updatedYearlyPrice = getActivePrice(updatedStripePrices, 'year', yearlyAmount);
|
||||
this.updatePortalPlans(updatedMonthlyPrice.id, updatedYearlyPrice.id, data);
|
||||
this.settings.set('membersMonthlyPriceId', updatedMonthlyPrice.id);
|
||||
this.settings.set('membersYearlyPriceId', updatedYearlyPrice.id);
|
||||
return savedProduct;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@task
|
||||
*finaliseTask() {
|
||||
|
|
|
@ -46,38 +46,12 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
|
|||
return envConfig.environment !== 'development' && !/^https:/.test(siteUrl);
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get isPaidPriceDisabled() {
|
||||
return this.disabled || !this.membersUtils.isStripeEnabled;
|
||||
return !this.membersUtils.isStripeEnabled;
|
||||
}
|
||||
|
||||
get isFreeDisabled() {
|
||||
return this.disabled || this.settings.get('membersSignupAccess') !== 'all';
|
||||
}
|
||||
|
||||
getPrice(prices, type) {
|
||||
const monthlyPriceId = this.settings.get('membersMonthlyPriceId');
|
||||
const yearlyPriceId = this.settings.get('membersYearlyPriceId');
|
||||
|
||||
if (type === 'monthly') {
|
||||
return (
|
||||
prices.find(price => price.id === monthlyPriceId) ||
|
||||
prices.find(price => price.nickname === 'Monthly') ||
|
||||
prices.find(price => price.interval === 'month')
|
||||
);
|
||||
}
|
||||
|
||||
if (type === 'yearly') {
|
||||
return (
|
||||
prices.find(price => price.id === yearlyPriceId) ||
|
||||
prices.find(price => price.nickname === 'Yearly') ||
|
||||
prices.find(price => price.interval === 'year')
|
||||
);
|
||||
}
|
||||
return null;
|
||||
return this.settings.get('membersSignupAccess') !== 'all';
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -182,7 +156,6 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
|
|||
const storedData = this.args.getData();
|
||||
if (storedData?.product) {
|
||||
this.product = storedData.product;
|
||||
this.stripePrices = this.product.get('stripePrices') || [];
|
||||
|
||||
if (storedData.isMonthlyChecked !== undefined) {
|
||||
this.isMonthlyChecked = storedData.isMonthlyChecked;
|
||||
|
@ -199,27 +172,16 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
|
|||
this.stripeMonthlyAmount = storedData.monthlyAmount;
|
||||
this.stripeYearlyAmount = storedData.yearlyAmount;
|
||||
} else {
|
||||
const products = yield this.store.query('product', {include: 'stripe_prices'});
|
||||
const products = yield this.store.query('product', {include: 'monthly_price,yearly_price'});
|
||||
this.product = products.firstObject;
|
||||
let portalPlans = this.settings.get('portalPlans') || [];
|
||||
const currentMontlyPriceId = this.settings.get('membersMonthlyPriceId');
|
||||
const currentYearlyPriceId = this.settings.get('membersYearlyPriceId');
|
||||
this.isMonthlyChecked = false;
|
||||
this.isYearlyChecked = false;
|
||||
this.isFreeChecked = false;
|
||||
if (portalPlans.includes(currentMontlyPriceId)) {
|
||||
this.isMonthlyChecked = true;
|
||||
}
|
||||
if (portalPlans.includes(currentYearlyPriceId)) {
|
||||
this.isYearlyChecked = true;
|
||||
}
|
||||
if (portalPlans.includes('free')) {
|
||||
this.isFreeChecked = true;
|
||||
}
|
||||
this.stripePrices = this.product.get('stripePrices') || [];
|
||||
const activePrices = this.stripePrices.filter(price => !!price.active);
|
||||
const monthlyPrice = this.getPrice(activePrices, 'monthly');
|
||||
const yearlyPrice = this.getPrice(activePrices, 'yearly');
|
||||
|
||||
this.isMonthlyChecked = portalPlans.includes('monthly');
|
||||
this.isYearlyChecked = portalPlans.includes('yearly');
|
||||
this.isFreeChecked = portalPlans.includes('free');
|
||||
|
||||
const monthlyPrice = this.product.get('monthlyPrice');
|
||||
const yearlyPrice = this.product.get('yearlyPrice');
|
||||
if (monthlyPrice && monthlyPrice.amount) {
|
||||
this.stripeMonthlyAmount = (monthlyPrice.amount / 100);
|
||||
this.currency = monthlyPrice.currency;
|
||||
|
|
Loading…
Add table
Reference in a new issue