mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-29 15:12:58 +03:00
Handled product save failure on Stripe connect
refs https://github.com/TryGhost/Team/issues/704 We try and create new default prices soon after Stripe Connect is completed, but it might take couple of seconds for backend to have Stripe config ready and in the meanwhile saving a product with new prices will fail with 409 Conflict error as it will be unable to create prices on Stripe. This change allows re-attempting saving a product with new prices soon after connect in case of a STRIPE_NOT_CONFIGURED error so that the default prices can be created properly.
This commit is contained in:
parent
8862960974
commit
740a304bf0
@ -5,6 +5,9 @@ import {task} from 'ember-concurrency-decorators';
|
||||
import {timeout} from 'ember-concurrency';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
const RETRY_PRODUCT_SAVE_POLL_LENGTH = 1000;
|
||||
const RETRY_PRODUCT_SAVE_MAX_POLL = 15 * RETRY_PRODUCT_SAVE_POLL_LENGTH;
|
||||
|
||||
export default class GhLaunchWizardConnectStripeComponent extends Component {
|
||||
@service ajax;
|
||||
@service config;
|
||||
@ -88,6 +91,28 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
||||
this.settings.set('portalPlans', portalPlans);
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*saveProduct() {
|
||||
let pollTimeout = 0;
|
||||
while (pollTimeout < RETRY_PRODUCT_SAVE_MAX_POLL) {
|
||||
yield timeout(RETRY_PRODUCT_SAVE_POLL_LENGTH);
|
||||
|
||||
try {
|
||||
const updatedProduct = yield this.product.save();
|
||||
return updatedProduct;
|
||||
} catch (error) {
|
||||
if (error.payload?.errors && error.payload.errors[0].code === 'STRIPE_NOT_CONFIGURED') {
|
||||
pollTimeout += RETRY_PRODUCT_SAVE_POLL_LENGTH;
|
||||
// no-op: will try saving again as stripe is not ready
|
||||
continue;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.product;
|
||||
}
|
||||
|
||||
@task({drop: true})
|
||||
*openDisconnectStripeConnectModalTask() {
|
||||
this.hasActiveStripeSubscriptions = false;
|
||||
@ -170,8 +195,7 @@ export default class GhLaunchWizardConnectStripeComponent extends Component {
|
||||
}
|
||||
);
|
||||
this.product.set('stripePrices', stripePrices);
|
||||
yield timeout(1000);
|
||||
const updatedProduct = yield this.product.save();
|
||||
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);
|
||||
|
@ -5,6 +5,9 @@ import {reads} from '@ember/object/computed';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task, timeout} from 'ember-concurrency';
|
||||
|
||||
const RETRY_PRODUCT_SAVE_POLL_LENGTH = 1000;
|
||||
const RETRY_PRODUCT_SAVE_MAX_POLL = 15 * RETRY_PRODUCT_SAVE_POLL_LENGTH;
|
||||
|
||||
export default Component.extend({
|
||||
config: service(),
|
||||
ghostPaths: service(),
|
||||
@ -258,6 +261,27 @@ export default Component.extend({
|
||||
this.settings.set('portalPlans', portalPlans);
|
||||
},
|
||||
|
||||
saveProduct: task(function* () {
|
||||
let pollTimeout = 0;
|
||||
while (pollTimeout < RETRY_PRODUCT_SAVE_MAX_POLL) {
|
||||
yield timeout(RETRY_PRODUCT_SAVE_POLL_LENGTH);
|
||||
|
||||
try {
|
||||
const updatedProduct = yield this.product.save();
|
||||
return updatedProduct;
|
||||
} catch (error) {
|
||||
if (error.payload?.errors && error.payload.errors[0].code === 'STRIPE_NOT_CONFIGURED') {
|
||||
pollTimeout += RETRY_PRODUCT_SAVE_POLL_LENGTH;
|
||||
// no-op: will try saving again as stripe is not ready
|
||||
continue;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.product;
|
||||
}),
|
||||
|
||||
saveStripeSettings: task(function* () {
|
||||
this.set('stripeConnectError', null);
|
||||
this.set('stripeConnectSuccess', null);
|
||||
@ -292,8 +316,7 @@ export default Component.extend({
|
||||
}
|
||||
);
|
||||
this.product.set('stripePrices', stripePrices);
|
||||
yield timeout(3000);
|
||||
const updatedProduct = yield this.product.save();
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user