TryGhost/Ghost · error · Error

Unable to create stripe checkout session

Error message

Unable to create stripe checkout session

What it means

Thrown by editBilling() when the POST to members 'create-stripe-update-session' returns non-2xx. This endpoint builds a Stripe Checkout Session for updating the card on an existing subscription. Unlike other handlers, this throw discards the backend error body entirely — it always uses the generic message regardless of what the backend returned.

Source

Thrown at apps/portal/src/utils/api.js:758

                const checkoutCancelUrl = window.location.href.startsWith(siteUrlObj.href) ? new URL(window.location.href) : new URL(siteUrl);
                checkoutCancelUrl.searchParams.set('stripe', 'billing-update-cancel');
                cancelUrl = checkoutCancelUrl.href;
            }
            return makeRequest({
                url,
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    identity: identity,
                    subscription_id: subscriptionId,
                    successUrl,
                    cancelUrl
                })
            }).then(function (res) {
                if (!res.ok) {
                    throw new Error('Unable to create stripe checkout session');
                }
                return res.json();
            }).then(function (result) {
                const stripe = window.Stripe(result.publicKey);
                return stripe.redirectToCheckout({
                    sessionId: result.sessionId
                });
            }).then(function (result) {
                if (result.error) {
                    throw new Error(result.error.message);
                }
            }).catch(function (err) {
                throw err;
            });
        },

        async manageBilling({returnUrl, subscriptionId} = {}) {
            const identity = await api.member.identity();

View on GitHub (pinned to 47d8b0e2ad)

Solutions

  1. Check the Ghost server log for the create-stripe-update-session handler error — the backend reason is logged but not surfaced here.
  2. Confirm subscriptionId is a valid, active Stripe subscription belonging to the signed-in member.
  3. Re-authenticate the member (refresh identity) before retrying.
  4. Verify the Stripe subscription still exists in the Stripe dashboard (not deleted).
  5. Patch editBilling() to surface the backend's res.json() error body instead of the generic string (improves diagnosability).

Example fix

// before: backend error body discarded
if (!res.ok) {
    throw new Error('Unable to create stripe checkout session');
}

// after: surface the backend reason like checkoutPlan does
if (!res.ok) {
    const errData = await res.json().catch(() => null);
    const err = errData?.errors?.[0] || {};
    throw new Error(err.message || 'Unable to create stripe checkout session');
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the subscription context before calling
function canEditBilling(identity, subscriptionId) {
    return Boolean(identity && subscriptionId && typeof subscriptionId === 'string');
}

Try / catch

try {
    await api.member.editBilling({subscriptionId});
} catch (err) {
    // Generic message — check Ghost server logs for the real reason
    showToast(err.message);
}

Prevention

When it happens

Trigger: Member clicks 'Edit billing details' to update their card; the backend can't create the update session — subscriptionId is missing or not found, the subscription belongs to a different member, Stripe customer/subscription was deleted in the Stripe dashboard, or the member's identity token doesn't authorize that subscription.

Common situations: subscriptionId passed is empty/stale; the subscription was cancelled in Stripe but still listed in Ghost; identity token expired; Stripe Connect key rotated so session creation fails server-side; member trying to edit billing on a complimentary (non-Stripe) subscription.

Related errors


AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13). Data as JSON: /api/errors/5d16e5f43e5f67c4. Report an issue: GitHub.