Idempotency
Every endpoint in this API is a read. Repeating a call creates, changes and deletes nothing — retrying is always safe as far as your data is concerned.
On our side
Gateways resend the same event — that is normal at-least-once delivery. PassKey deduplicates on ingest, so a payment resent three times is still a single sale in your read.
An identified resend shows up with status DUPLICATE and is not counted twice in revenue.
On your side
Use the sale id as the unique key in your database. It is stable: the same sale returns the same id forever, which makes your upsert idempotent without comparing field by field.
A sale can change state after you read it — a payment becomes a refund, a pending dispatch completes. Re-reading the window and upserting by id is the right pattern.