Stirling-Tools/Stirling-PDF · error · StripeFunctionError
accept-payg-bundle-quote failed
Error message
accept-payg-bundle-quote failed
What it means
Fallback thrown by acceptBundleStripeQuote when accept-payg-bundle-quote returns success === false OR omits invoice_id. Accepting a quote must raise a Stripe invoice, so a missing invoice_id is a hard failure regardless of the success flag.
Source
Thrown at frontend/editor/src/portal/billing/stripe.ts:390
error?: string;
}
/**
* Accept the Stripe quote for a persisted quote row, via {@code accept-payg-bundle-quote}. Acceptance
* generates the net-terms invoice as a DRAFT (auto_advance off) and returns the hosted URL; the
* payment step ({@link finalizeBundleInvoice}) stamps the recipient + PO and finalizes it. Payable by
* card on the hosted page, or by bank transfer / PO. Capacity is credited only on invoice.paid.
*/
export async function acceptBundleStripeQuote(req: {
teamId: number;
quoteId: number;
}): Promise<BundleInvoice> {
const res = await invoke<BundleInvoiceResponse>("accept-payg-bundle-quote", {
team_id: req.teamId,
quote_id: req.quoteId,
});
if (!res.success || !res.invoice_id) {
throw new StripeFunctionError(
res.error ?? "accept-payg-bundle-quote failed",
);
}
return {
invoiceId: res.invoice_id,
hostedInvoiceUrl: res.hosted_invoice_url ?? null,
invoicePdf: res.invoice_pdf ?? null,
status: res.status ?? null,
};
}
/**
* Finalize the accepted bundle invoice (stamping an optional PO), via {@code finalize-payg-bundle-invoice}.
* Returns the hosted checkout URL + PDF. Called by both Download-invoice and Pay-online; idempotent
* server-side (an already-finalized invoice comes back as-is, PO locked).
*/
export async function finalizeBundleInvoice(req: {
teamId: number;View on GitHub (pinned to 9ef20dcab8)
Solutions
- Refresh the quote state (getLatestBundleQuote) and only show Accept when status is open/valid.
- Make accept idempotent on the client: disable the button while the request is in flight and after success.
- Inspect res.error / function logs for the real cause (e.g. quote_already_accepted).
- Ensure the edge function sets invoice_id on every success path and a meaningful error otherwise.
Example fix
// edge function — before
if (alreadyAccepted) return json({ success: true });
// after
if (alreadyAccepted) {
return json({ success: false, error: 'quote_already_accepted' });
}
return json({ success: true, invoice_id: invoice.id }); Defensive patterns
Strategy: try-catch
Validate before calling
function canAcceptQuote(quote: LatestBundleQuote | null): boolean {
return quote != null && quote.status === "open";
}
if (!canAcceptQuote(latestQuote)) {
notifications.show({ message: "Quote cannot be accepted in its current state.", color: "orange" });
return;
} Type guard
function isBundleInvoiceResponse(res: BundleInvoiceResponse | null): res is BundleInvoiceResponse & { success: true; invoice_id: string } {
return res != null && res.success === true && typeof res.invoice_id === "string";
} Try / catch
try {
await acceptBundleStripeQuote({ teamId, quoteId });
} catch (e) {
if (e instanceof StripeFunctionError && /already.*accept/i.test(e.message)) {
notifications.show({ message: "This quote was already accepted.", color: "orange" });
refreshQuote();
} else throw e;
} Prevention
- Only show Accept when the quote status is open/valid (gate via getLatestBundleQuote).
- Make accept idempotent in the UI: disable while in-flight and after success.
- Ensure the edge function returns a stable error code for double-accept.
When it happens
Trigger: accept-payg-bundle-quote responds success:false (with res.error, or this fallback if error omitted), or success:true without invoice_id. Common when the quote was already accepted/cancelled/expired, or Stripe invoice creation failed inside the function.
Common situations: Double-accept of the same quote (concurrent clicks / page reload); quote in a non-open status; Stripe error creating the invoice; function bug returning success without the invoice handle.
Related errors
- create-payg-bundle-quote failed
- finalize-payg-bundle-invoice failed
- cancel-payg-bundle-quote failed
- Edge function ${name} returned no data
- payg_upsert_bundle_quote returned no row
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/69959c487026404b.
Report an issue: GitHub.