Error Handling
Use the following guidelines for handling errors in the system.
Idempotency and Request Handling
All payment-related API calls have idempotency built into them. To leverage idempotency, pass the x-idempotency-key
header with each API request.
There is no harm in making the same API call multiple times with the same key. Note however that any changes to the request after the initial request
will likely not be processed if the original request was successful.
Payment Errors
The system does not consider a payment decline an HTTP error. We do not use HTTP response codes to indicate failure of a successful call to the payment provider (card brands or banks).
Inspect the status
field returned to understand if the payment was successful or not. Common status values include:
succeeded
: Payment completed successfullyfailed
: Payment was declined or failedpending
: Payment is being processedcreated
: Initial state, ready for payment attempt
Non-200 HTTP errors are used to indicate either a logic error (e.g., validation, configuration) or a system error.
Retries and Preventing Duplicates
There are several things that happen during the processing of a payment, from validation to fraud detection to persisting across our distributed system. While we take extreme measures to ensure that when things go wrong they are handled, there are times when unexpected behavior occurs. If you experience a 500 code error, often times it is best to not attempt the transaction again. Keep reading for best practices.
Best Practices
Create one Payment Intent per Checkout Experience
Creating one Payment Intent (PI) and using that PI to both collect payment data and attach payments to for an entire session is the correct way to use the API. If a payment fails, perhaps due to a decline or system error, continue to use the PI for new payment methods and new attempts. Do not create a new PI if the first payment attempt fails, as doing so will bypass a number of guards the system has in place to prevent issues such as duplicates. A great technique is to use your unique checkout cart id as the reference id on the PI (ex. cart_123456), and either a unique id or postfix per payment attempt (ex. cart_123456-1, cart_123456-2, etc.)
Always Use Idempotency Keys
Leverage idempotency keys to prevent duplicate charges to a customer. Each unique operation should have its own idempotency key that remains consistent across retries.
Handling 500 Errors for Payments
In the rare event that you receive a system error when creating a payment, you should fetch the Payment Intent by ID and inspect the status:
- If the status is
created
, you can make additional payment attempts. Our team will be alerted to such errors and will investigate the primary issue, but feel free to reach out to support. - If the status is
pending
, this indicates an error late in the processing attempt. Best practice is to not process this payment again (assume the payment went through), and provide guidance to the end user to not attempt additional payments. This very specific error comes with special handling by our team and in almost all cases we can resolve the issue. You can make API calls to check on the status of the PI to see if it was processed by our team, or you can listen to webhooks for updates on when the payment gets processed.