Catch and respond to declines, invalid data, network problems, and more.
Stripe offers many kinds of errors. They can reflect external events, like declined payments and network interruptions, or code problems, like invalid API calls.
To handle errors, use some or all of the techniques in the table below. No matter what technique you use, you can follow up with our recommended responses for each error type.
Investigate past problems and support other techniques
Sometimes
Catch exceptions
If an immediate problem prevents an API call from continuing, the Stripe Node.js library can raise an exception. It’s a best practice to catch and handle exceptions. To enable exception raising and catch the exception, do the following: raising and catch the exception, you need to do several things:
If you make the API call in a function, precede the function definition with the async keyword.
Precede the API call itself with the await keyword.
Stripe notifies you about many kinds of problems using webhooks. This includes problems that don’t follow immediately after an API call. For example:
You lose a dispute.
A recurring payment fails after months of success.
Your front end confirms a payment, but goes offline before finding out the payment fails. (The back end still receives webhook notification, even though it wasn’t the one to make the API call.)
You don’t need to handle every webhook event type. In fact, some integrations don’t handle any.
In your webhook handler, start with the basic steps from the webhook builder: get an event object and use the event type to find out what happened. Then, if the event type indicates an error, follow these extra steps:
);const express =require('express');const app =express();
app.post('/webhook', express.json({type:'application/json'}),(request, response)=>{// Get an event objectconst event = request.body;// Use its type to find out what happenedif(event.type=='payment_intent.payment_failed'){// Get the object affectedconst paymentIntent = event.data.object;// Use stored information to get an error objectconst error = paymentIntent.error;// Use its type to choose a responseswitch(error.type){case'StripeCardError':
console.log(`A payment error occurred: ${error.message}`);break;case'StripeInvalidRequestError':
console.log('An invalid request occurred.');if(error.param){
console.log(`The parameter ${error.param} is invalid or missing.`);}break;default:
console.log('Another problem occurred, maybe unrelated to Stripe.');break;}}
response.send();});
app.listen(4242,()=> console.log('Running on port 4242'));
To test how your integration responds to webhook events, you can trigger webhook events locally. After completing the setup steps at that link, trigger a failed payment to see the resulting error message.
Command Line
stripe trigger payment_intent.payment_failed
Output
A payment error occurred: Your card was declined.
Get stored information about failures
Many objects store information about failures. That means that if something already went wrong, you can retrieve the object and examine it to learn more. In many cases, stored information is in the form of an error object, and you can use its type to choose a response.
For instance:
Retrieve a specific payment intent.
Check if it experienced a payment error by determining if last_payment_error is empty.
If it did, log the error, including its type and the affected object.
To test code that uses stored information about failures, you often need to simulate failed transactions. You can often do this using test cards or test bank numbers. For example:
This error can occur when your integration is working correctly. It reflects an action by the issuer, and that action may be legitimate. Use the decline code to determine what next steps are appropriate. See the documentation on decline codes for appropriate responses to each code.
This error can occur when your integration is working correctly. Use the error code to determine what next steps are appropriate. See the documentation on error codes for appropriate responses to each code.
Invalid request errors
Type
StripeInvalidRequestError
Problem
You made an API call with the wrong parameters, in the wrong state, or in an invalid way.
Solutions
In most cases, the problem is with the request itself. Either its parameters are invalid or it can’t be carried out in your integration’s current state.
For convenience, you can follow the link at e.doc_url for documentation about the error code.
If the error involves a specific parameter, use e.param to determine which one.
Connection errors
Type
StripeAPIConnectionError
Problem
There was a network problem between your server and Stripe.
Solutions
Treat the result of the API call as indeterminate. That is, don’t assume that it succeeded or that if failed.
To find out if it succeeded, you can:
Retrieve the relevant object from Stripe and check its status.
Listen for webhook notification that the operation succeeded or failed.
To make it easier to recover from connection errors, you can:
When creating or updating an object, use an idempotency key. Then, if a connection error occurs, you can safely repeat the request without risk of creating a second object or performing the update twice. Repeat the request with the same idempotency key until you receive a clear success or failure. For advanced advice on this strategy, see Low-level error handling.
Turn on automatic retries. Then, Stripe generates idempotency keys for you, and repeats requests for you when it is safe to do so.
This error can mask others. It’s possible that when the connection error resolves, some other error becomes apparent. Check for errors in all of these solutions just as you would in the original request.
API errors
Type
StripeAPIError
Problem
Something went wrong on Stripe’s end. (These are rare.)
Solutions
Treat the result of the API call as indeterminate. That is, don’t assume that it succeeded or that it failed.
Rely on webhooks for information about the outcome. Whenever possible, Stripe fires webhooks for any new objects we create as we solve a problem.
You used an idempotency key for something unexpected, like replaying a request but passing different parameters.
Solutions
After you use an idempotency key, only reuse it for identical API calls.
Use idempotency keys under the limit of 255 characters.
Permission errors
Type
StripePermissionError
Problem
The API key used for this request does not have the necessary permissions.
Solutions
Are you using a restricted API key for a service it doesn’t have access to?
Are you performing an action in the Dashboard while logged in as a user role that lacks permission?
Rate limit errors
Type
StripeRateLimitError
Problem
You made too many API calls in too short a time.
Solutions
If a single API call triggers this error, wait and try it again.
To handle rate-limiting automatically, retry the API call after a delay, and increase the delay exponentially if the error continues. See the documentation on rate limits for further advice.
If you anticipate a large increase in traffic and want to request an increased rate limit, contact support in advance.
This error can occur when your integration is working correctly. If you use webhook signature verification and a third party attempts to send you a fake or malicious webhook, then verification fails and this error is the result. Catch it and respond with a 400 Bad Request status code.
If you receive this error when you shouldn’t – for instance, with webhooks that you know originate with Stripe – then see the documentation on checking webhook signatures for further advice. In particular, make sure you’re using the correct endpoint secret. This is different from your API key.
Welcome to the Stripe Shell!
Stripe Shell is a browser-based shell with the Stripe CLI pre-installed. Log in to your
Stripe account and press Control + Backtick (`) on your keyboard to start managing your Stripe
resources in test mode.
- View supported Stripe commands:
- Find webhook events:
- Listen for webhook events:
- Call Stripe APIs: stripe [api resource] [operation] (e.g., )