# IdempotentUuid Management

## Overview

idempotentUuid is a unique identifier you provide to represent one payment attempt. It prevents double charges when your POS has to resend the request (HTTP timeout, network issues, double click, app restart). It is accepted by the payment endpoints of the [Local](https://app.notion.com/p/3bc9a8f4fd9a8120bb0acd52a5f3dde6), [Cloud](https://app.notion.com/p/3bc9a8f4fd9a81518b1bda59179c4d1b) and [Android Intent](https://app.notion.com/p/3bc9a8f4fd9a8115b854d1eccf09ccc5) APIs. The terminal-side check described below applies to the Local and Android Intent APIs only.

## How the terminal uses it

When a payment request carries an idempotentUuid:

- If a transaction already exists on the terminal for this UUID (within the last 24 hours), the terminal returns that existing transaction instead of creating a new one

- If that transaction is still in progress, the request attaches to it: on the Local API, the response is sent when the ongoing payment completes; on the Android Intent API, the in-progress transaction is returned as is, without a status field

- Otherwise, the terminal starts a new payment and links this UUID to the transaction once the payment is completed

> ⚠️ Cloud API. On the Cloud API, the terminal does not look up the idempotentUuid: the behaviour described in this section is not performed by the terminal. Do not rely on the terminal to deduplicate Cloud payment requests.

> ⚠️ If the existing transaction for this UUID failed (status: "ko"), sending the same idempotentUuid returns the same failure. To actually retry the payment, generate a new idempotentUuid.

> ⚠️ If you do not provide an idempotentUuid, Yavin generates one for its own purposes. That internal UUID does not protect your POS from double submission.

## The POS-side rule

1 payment attempt = 1 idempotentUuid

- Technical retries of the same attempt (timeout, automatic retry, POS app restart): reuse the same idempotentUuid

- A new attempt (you decide to "try paying again", typically after a ko): generate a new idempotentUuid

## Implementation recommendations

- Generate a UUID (v4) on the POS when you create the attempt, and persist it with the order/cart until the attempt is finalized

- When replaying the payment request due to a technical issue, send the exact same idempotentUuid

- Never reuse an idempotentUuid for a different attempt, even for the same amount or the same cart

- After status: "ok": the attempt is finished, any new payment must use a new UUID

- After status: "ko": to retry, create a new attempt with a new UUID

## Example: retry after timeout

Same request, same idempotentUuid:

```json
POST http://<LOCAL_IP>:16125/localapi/v4/payment
{
  "amount": 1000,
  "cartId": "ORDER-2026-000123",
  "idempotentUuid": "2f1c2e2a-6c21-4a4b-9c2b-9f6f2c8e9b51",
  "vendor": { "softwareName": "MyPOS", "softwareVersion": "4.7.0" }
}
```

## Related pages

[In-store payment: Local API](https://app.notion.com/p/3bc9a8f4fd9a8120bb0acd52a5f3dde6)

[In-store payment: Cloud API](https://app.notion.com/p/3bc9a8f4fd9a81518b1bda59179c4d1b)

[In-store payment: Android Intent API](https://app.notion.com/p/3bc9a8f4fd9a8115b854d1eccf09ccc5)
