Repeat payment notifications

A signature over the raw bytes and handling the duplicate in the database.

skill-tg cover

A payment gateway may repeat a notification if it did not get a response in time. There is still only one purchase. The handler has to recognise that it has already delivered it.

In TelegramShop I read the raw request body, compute the signature and compare with hmac.compare_digest. JSON is parsed after this check. If it is rebuilt earlier, field order or whitespace can change, and you get a different body to sign.

A missing signature and an unconfigured key must both end in refusal. Otherwise a conditional check easily turns into a skip: there is no header, nothing to compare, and the code moves on.

For repeats in the minimal shop I use the unique telegram_payment_charge_id. The database accepts a new record once. The reference for external gateways has a conditional UPDATE: move the invoice to paid if it is not paid yet, and credit the balance in the same transaction. The database operation makes the decision, so two parallel requests must not both get the right to credit.

An already processed duplicate gets a successful HTTP response. A failure to send a message to the buyer does not repeat the credit. External delivery needs its own state and retries, and a payment record alone does not complete it.

I collected these techniques in skill-tg.

← All projects

Contacts