Idempotency

The Mangopay API supports idempotency for all POST calls, which allows you to safely retry an operation while only performing the operation once. This helps avoid unwanted duplicated calls that can have detrimental consequences, for example in case of a network error.

Using an idempotency key

To make a POST call idempotent, include the Idempotency-Key header in your API request and generate a unique value for it.

The unique value allows the system to identify any subsequent retries of the same operation within 24 hours.

The idempotency key must contain between 16 and 36 alphanumeric characters or dashes (-).

Best practice – Use a UUID for idempotency keys

We strongly recommend generating a universally unique identifier (UUID) to use as the value for the Idempotency-Key header of your API request.

While using an idempotency key is optional, it is strongly recommended and necessary for some operations.

This is notably the case for:

  • Multiple card pay-in captures against the same Preauthorization within 24 hours

Looking up an idempotency key

To retrieve an API response, call the GET View an API Response endpoint using your Idempotency-Key header value as the path parameter.

If Mangopay finds that the key was used in the last 24 hours, then the API response shows the outcome of the original request:

  • StatusCode – The HTTP response code of the original request.
  • Resource – The response body of the original request.

Note – Idempotency lookup limited to within 24 hours

An idempotency key is only valid for 24 hours:

  • A request only returns a 409 response if its Idempotency-Key header value was used in the last 24 hours
  • The GET View an API Response returns a 400 error if the value wasn’t used in the last 24 hours

Blocking duplicated calls

If you use the same idempotency key within 24 hours, Mangopay will block all requests except the first. This means you are able to retry the same request safely knowing that it will only be processed once.

If the idempotency key has already been used in the last 24 hours, the API returns a 409 HTTP response code error:

409 Conflict
{
"Message": "A resource has already been created with this Idempotency Key",
"Type": "idempotent_creation_conflict",
"Id": "002576ad-64d8-494b-95cd-4374c9400476#1789130930",
"Date": 1789130931,
"errors": null
}

Idempotent requests are blocked regardless of the HTTP response code of the first API call. This means you can’t reuse an idempotency key that was used on a failed call.

Handling timeouts

A timeout means that you didn’t receive a response from the API within the timeout configured in your HTTP client.

If your initial call used an Idempotency-Key header, then you can safely retry automatically using the same key:

1

Retry the request once with the same idempotency key

If the retry is successful, then it means that the original attempt did not reach Mangopay, so the retry is the one that gets processed.

If the API responds with a 409 response, then the original request did reach Mangopay and can be looked up using the dedicated endpoint below.

2

If the retry returns a 409 response, look up the idempotency key

Use the idempotency key value with the GET View an API Response endpoint as described above.

If StatusCode reflects success, then you know that the original request was processed (for example, the payment was initiated), and Resource gives the response body.

If StatusCode is not successful, then the Resource gives the error message. If StatusCode is 500, then you can attempt to check for the operation as described below.

If the original request that timed out didn’t include an idempotency key, or occurred more than 24 hours ago, then you should attempt to check for the operation before attempting a single retry. Integrating idempotency is recommended in all cases.

Handling server errors (500 response)

A 500 response code means Mangopay encountered an unexpected issue while processing the request, with the result of the operation being unknown.

In such cases, looking up the idempotency key with GET View an API Response will typically return the 500 error of the first call – the StatusCode in the response will be 500 along with the error message in Resource.

Therefore, to understand what happened you can attempt to check for the operation.

Checking for an operation

Before proceeding to a retry, and if the idempotency key can’t tell you the outcome of an operation, then you can try to check whether the resource exists using other parts of the system by:

  • Webhooks – Receiving a webhook notification for the relevant creation event (for example, PAYIN_NORMAL_CREATED), provided it was previously set up
  • Listing endpoints – Calling a list endpoint based on a resource related to the operation you attempted

Common areas where listing endpoints are available include:

Using unique values in the common Tag property can facilitate this lookup operation. To store multiple values in the Tag, you can serialize them into a single string, for example a JSON object: "{\"id_1\":AB123,\"id_2\":DE456}".

If you find the resource and the operation was successful, then no retry is necessary.

Retrying an operation

In cases where you are unable to find a resource via its idempotency key, a webhook notification, or after checking all the available list endpoints, then it may be safe to retry with a new idempotency key. For any operation where an unintended duplicate would be costly, wait if possible and check again before attempting the retry.

Best practice – Retry once, with backoff

We recommend a single retry for temporary errors like 500 or 429, rather than retrying indefinitely.

  • For a 500, wait using an exponential backoff with jitter before retrying.
  • For a 429, use the x-ratelimit-reset response header to know when to retry.

Retrying immediately or in a tight loop adds load to the service and can mean you quickly hit rate limits, which may affect your operations.