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})
|
@task({drop: true})
|
||||||
*saveProduct() {
|
*saveProduct() {
|
||||||
let pollTimeout = 0;
|
let pollTimeout = 0;
|
||||||
|
@ -169,13 +158,11 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
||||||
try {
|
try {
|
||||||
yield this.settings.save();
|
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;
|
this.product = products.firstObject;
|
||||||
if (this.product) {
|
if (this.product) {
|
||||||
const stripePrices = this.product.stripePrices || [];
|
|
||||||
const yearlyDiscount = this.calculateDiscount(5, 50);
|
const yearlyDiscount = this.calculateDiscount(5, 50);
|
||||||
stripePrices.push(
|
this.product.set('monthlyPrice', {
|
||||||
{
|
|
||||||
nickname: 'Monthly',
|
nickname: 'Monthly',
|
||||||
amount: 500,
|
amount: 500,
|
||||||
active: 1,
|
active: 1,
|
||||||
|
@ -183,8 +170,8 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
||||||
currency: 'usd',
|
currency: 'usd',
|
||||||
interval: 'month',
|
interval: 'month',
|
||||||
type: 'recurring'
|
type: 'recurring'
|
||||||
},
|
});
|
||||||
{
|
this.product.set('yearlyPrice', {
|
||||||
nickname: 'Yearly',
|
nickname: 'Yearly',
|
||||||
amount: 5000,
|
amount: 5000,
|
||||||
active: 1,
|
active: 1,
|
||||||
|
@ -192,15 +179,9 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
||||||
description: yearlyDiscount > 0 ? `${yearlyDiscount}% discount` : 'Full access',
|
description: yearlyDiscount > 0 ? `${yearlyDiscount}% discount` : 'Full access',
|
||||||
interval: 'year',
|
interval: 'year',
|
||||||
type: 'recurring'
|
type: 'recurring'
|
||||||
}
|
});
|
||||||
);
|
yield this.saveProduct.perform();
|
||||||
this.product.set('stripePrices', stripePrices);
|
this.settings.set('portalPlans', ['free', 'monthly', 'yearly']);
|
||||||
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.settings.save();
|
yield this.settings.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,91 +14,35 @@ export default class GhLaunchWizardFinaliseComponent extends Component {
|
||||||
this.settings.rollbackAttributes();
|
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() {
|
async saveProduct() {
|
||||||
const data = this.args.getData();
|
const data = this.args.getData();
|
||||||
this.product = data?.product;
|
this.product = data?.product;
|
||||||
if (this.product) {
|
if (this.product) {
|
||||||
const stripePrices = this.product.stripePrices || [];
|
|
||||||
const monthlyAmount = data.monthlyAmount * 100;
|
const monthlyAmount = data.monthlyAmount * 100;
|
||||||
const yearlyAmount = data.yearlyAmount * 100;
|
const yearlyAmount = data.yearlyAmount * 100;
|
||||||
const currency = data.currency;
|
const currency = data.currency;
|
||||||
const getActivePrice = (prices, type, amount) => {
|
const monthlyPrice = {
|
||||||
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(
|
|
||||||
{
|
|
||||||
nickname: 'Monthly',
|
nickname: 'Monthly',
|
||||||
amount: monthlyAmount,
|
amount: monthlyAmount,
|
||||||
active: 1,
|
active: 1,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
interval: 'month',
|
interval: 'month',
|
||||||
type: 'recurring'
|
type: 'recurring'
|
||||||
}
|
};
|
||||||
);
|
const yearlyPrice = {
|
||||||
}
|
|
||||||
if (!yearlyPrice) {
|
|
||||||
stripePrices.push(
|
|
||||||
{
|
|
||||||
nickname: 'Yearly',
|
nickname: 'Yearly',
|
||||||
amount: yearlyAmount,
|
amount: yearlyAmount,
|
||||||
active: 1,
|
active: 1,
|
||||||
currency: currency,
|
currency: currency,
|
||||||
interval: 'year',
|
interval: 'year',
|
||||||
type: 'recurring'
|
type: 'recurring'
|
||||||
}
|
};
|
||||||
);
|
this.product.set('monthlyPrice', monthlyPrice);
|
||||||
}
|
this.product.set('yearlyPrice', yearlyPrice);
|
||||||
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);
|
|
||||||
const savedProduct = await this.product.save();
|
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;
|
return savedProduct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
*finaliseTask() {
|
*finaliseTask() {
|
||||||
|
|
|
@ -46,38 +46,12 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
|
||||||
return envConfig.environment !== 'development' && !/^https:/.test(siteUrl);
|
return envConfig.environment !== 'development' && !/^https:/.test(siteUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
get disabled() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
get isPaidPriceDisabled() {
|
get isPaidPriceDisabled() {
|
||||||
return this.disabled || !this.membersUtils.isStripeEnabled;
|
return !this.membersUtils.isStripeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isFreeDisabled() {
|
get isFreeDisabled() {
|
||||||
return this.disabled || this.settings.get('membersSignupAccess') !== 'all';
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -182,7 +156,6 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
|
||||||
const storedData = this.args.getData();
|
const storedData = this.args.getData();
|
||||||
if (storedData?.product) {
|
if (storedData?.product) {
|
||||||
this.product = storedData.product;
|
this.product = storedData.product;
|
||||||
this.stripePrices = this.product.get('stripePrices') || [];
|
|
||||||
|
|
||||||
if (storedData.isMonthlyChecked !== undefined) {
|
if (storedData.isMonthlyChecked !== undefined) {
|
||||||
this.isMonthlyChecked = storedData.isMonthlyChecked;
|
this.isMonthlyChecked = storedData.isMonthlyChecked;
|
||||||
|
@ -199,27 +172,16 @@ export default class GhLaunchWizardSetPricingComponent extends Component {
|
||||||
this.stripeMonthlyAmount = storedData.monthlyAmount;
|
this.stripeMonthlyAmount = storedData.monthlyAmount;
|
||||||
this.stripeYearlyAmount = storedData.yearlyAmount;
|
this.stripeYearlyAmount = storedData.yearlyAmount;
|
||||||
} else {
|
} 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;
|
this.product = products.firstObject;
|
||||||
let portalPlans = this.settings.get('portalPlans') || [];
|
let portalPlans = this.settings.get('portalPlans') || [];
|
||||||
const currentMontlyPriceId = this.settings.get('membersMonthlyPriceId');
|
|
||||||
const currentYearlyPriceId = this.settings.get('membersYearlyPriceId');
|
this.isMonthlyChecked = portalPlans.includes('monthly');
|
||||||
this.isMonthlyChecked = false;
|
this.isYearlyChecked = portalPlans.includes('yearly');
|
||||||
this.isYearlyChecked = false;
|
this.isFreeChecked = portalPlans.includes('free');
|
||||||
this.isFreeChecked = false;
|
|
||||||
if (portalPlans.includes(currentMontlyPriceId)) {
|
const monthlyPrice = this.product.get('monthlyPrice');
|
||||||
this.isMonthlyChecked = true;
|
const yearlyPrice = this.product.get('yearlyPrice');
|
||||||
}
|
|
||||||
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');
|
|
||||||
if (monthlyPrice && monthlyPrice.amount) {
|
if (monthlyPrice && monthlyPrice.amount) {
|
||||||
this.stripeMonthlyAmount = (monthlyPrice.amount / 100);
|
this.stripeMonthlyAmount = (monthlyPrice.amount / 100);
|
||||||
this.currency = monthlyPrice.currency;
|
this.currency = monthlyPrice.currency;
|
||||||
|
|
Loading…
Add table
Reference in a new issue