Design A Retry Strategy
When errors occur, some can be retried while others require a change before they can succeed. In the case of payments, a successful retry strategy is vital to ensure that a payment is created before an authorization expires (generally 7 days). It is also vital to ensure that a payment does not inadvertently get created twice. This article will focus on retry strategies geared specifically at payments, but the strategies themselves can be generalized to all your WePay API requests.
As mentioned in API Basics, 5xx HTTP errors indicate that the request can be programmatically retried until successful, while 4xx HTTP errors typically require a new request.
The exception to 4xx HTTP errors requiring a new request is the
INVALID_PARAMS.CONCURRENT_UNIQUE_KEY_REQUEST_IS_PROCESSING error code and reason. This error is returned when a request is made with a Unique-Key that was used on a previous request which is still being processed by WePay. As such, this error can be retried with the same method you implement for 5xx HTTP errors.
To retry a request and ensure idempotency, everything about the request must remain the same. In the case of a payment API request, “everything” includes the Unique-Key header and the request body (such as the payment method, amount, etc).
When we discuss retrying a request in this article, we refer to automatically sending the request again with no user engagement. It is important to note that 4xx errors on a payment API request may require the user to submit new payment information. That said, the submission of a new payment method will result in a new API request, so does not qualify as a retry in the context of this article.
In summary, all 5xx HTTP errors are retryable, in addition to the
INVALID_PARAMS.CONCURRENT_UNIQUE_KEY_REQUEST_IS_PROCESSING 400 error.
First, familiarize yourself with general retry strategy recommendations below:
- Set a maximum number of retries
- Unique-Key headers are valid for 24 hours, so any retry thresholds you set must not retry after 24 hours from the initial request
- Wait at least 1 second after receiving and error before the first retry
- Implement exponential backoff for subsequent retries
- Escalate to WePay with the
X-Correlation-Idin the response header if you do not receive a 200 HTTP response before you hit your retry threshold
WePay also recommends progressively extending the time between retries, as this is best practice for handling web application errors.
There are a variety of ways to implement exponential back off, so use any method that suits your use case so long as the above considerations are included in your design.
A buyer purchases a cart of items to be shipped from one of your eCommerce merchants.
The buyer enters their card details and then submits the payment. On your back end, you send a POST /payments request with Unique-Key, an order number, and the payment method. The request receives the
UNEXPECTED_ERROR WePay API Error Code, which is a 500 HTTP error. This payment is sent through your retry flow as soon as the 500 HTTP error is received. As a result, show the buyer a payment confirmation page and indicate that a confirmation email will be sent out shortly.
Your retry flow is coded to wait 1.5 seconds before sending the same request, with the same Unique-Key. On the first retry, the same API error returns, and your code will retry again
5*n seconds later where
n is the number of retries thus far (with a maximum 5-minute delay).
|Successful Retry Flow||Unsuccessful Retry Flow|
|After 5 retries, you receive a 200 HTTP response. Stop retrying the payment and email the buyer that their order is complete. Notify the merchant of the purchase so that they can begin preparing for shipment.||If the payment has not succeeded at 24 hours, stop retrying the payment. Email the buyer and prompt them to try using a different payment method. At the same time, fetch the
Questions? Need help? Visit our support page!