Errors
Every error from the API has the same shape:
{ "error": { "type": "invalid_request", "message": "Payment intent not found.", "details": {} }}message is written to be read. It’s safe to log, and usually safe to show. details is
there only for some errors. @usestack/node throws these as a StackError with type,
status, message, details and requestId.
type |
HTTP | Means | What to do |
|---|---|---|---|
invalid_request |
400, 404, 409 | Something in the request is wrong, or the thing doesn’t exist or isn’t yours. | Fix the request. message says what. |
authentication_failed |
401 | Missing, wrong or rolled key. | Check the key, and that it’s the secret key on your server. |
invalid_request |
403 | A live key while live mode isn’t open to you: not verified yet, or paused by Stack. | See Going live. Your test keys keep working. |
insufficient_balance |
409 | Your Stack balance can’t cover a refund. | Try again once your balance covers it. |
limit_exceeded |
403 | A live payment over a limit Stack set on your account (per payment or per month). | Contact us, or take a smaller payment. |
rate_limited |
429 | Too many requests. | Back off and retry. @usestack/node does this for you. |
internal |
500 | Something broke at Stack. | Retry with the same idempotency key. If it keeps happening, contact us with the x-request-id. |
network_error |
— | @usestack/node only: Stack couldn’t be reached. |
Retry. The SDK already retried twice. |
In the payment sheet
Section titled “In the payment sheet”Errors during a payment are handled in the sheet: a declined card, a wrong code or PIN, an expired payment. The customer sees what happened and can try again, or choose another way to pay. You only see a result when the sheet closes:
presentPaymentSheetresolves with{ status: 'failed', error: { type, message } }when a payment can’t go ahead, for example because it expired (intent_expired).- The customer’s own limits (
limit_exceeded) and card declines (card_declined) are shown in the sheet and don’t close it.