Skip to main content

Idempotency

Every payment and session you create carries a merchantInternalTransactionCode — your own unique reference for that operation. AccruPay uses it as the idempotency key: it guarantees that a given code maps to at most one transaction, so a retried or duplicated request cannot create a second charge.

The rule

merchantInternalTransactionCode must be unique per merchant + provider. Before any payment or session is created, AccruPay runs a pre-flight check and rejects the request if that code is already in use — against:

  • an existing transaction on the provider,
  • a local transaction, or
  • a local client transaction session.

If the code is already used, the mutation fails with a uniqueness error (extensions.code is a @…/… AppError key) and nothing is created.

This check runs on every create/start path: merchantApiServerPaymentMethodTransactionCreate, merchantApiServerAchPaymentTransactionCreate, and all client session starts (payment, authorization, add-payment-method).

Status does not matter

A code is rejected regardless of the prior transaction's status. A code attached to a FAILED or DECLINED attempt is permanently consumed — it cannot be reused. To retry after a known failure, generate a new merchantInternalTransactionCode.

Choosing a code

  • Make it unique and stable for the intent of one payment — e.g. order-5571-charge, invoice-2026-0042.
  • Do not reuse a code across logically different operations.
  • Generate it on your side before the call so a network retry of the same request is naturally de-duplicated.

Retry semantics

SituationWhat you knowWhat to do
Mutation returned DECLINED / FAILEDThe attempt is final and its code is burnedRetry the payment with a new code (after customer action, if needed).
Network timeout / no responseOutcome unknown — the charge may or may not have gone throughQuery first by merchantInternalTransactionCode (merchantApiTransaction) to learn the outcome. If a transaction exists, use its status; if none exists, retry with a new code.
You resend the exact same request (same code)AccruPay rejects the duplicate rather than charging twice.

The key safety property: a retry can never silently double-charge, because the second attempt with the same code is rejected, and a deliberate retry uses a fresh code only after you have confirmed the first did not succeed.