# Fixing "agent sent the renewal receipt before the payment settled: customer disputed the pending charge"

## TL;DR

Send the receipt only after the payment settles, never on charge attempt. Gate receipt sending on the settled or succeeded webhook, and make receipts idempotent so a retry cannot send two. The early receipt is what makes a normal pending charge look suspicious.

```text
agent sent the renewal receipt before the payment settled: customer disputed the pending charge
```

## Steps

1. Move receipt sending out of the charge-attempt step and into the settlement webhook handler.
   Expected: Receipts only go out for payments the provider confirms as settled.
2. Add an idempotency key per invoice so a duplicate webhook cannot send a second receipt.
   Expected: Replayed webhooks produce exactly one receipt.
3. Make the receipt show the settlement date and the last digits of the charged method.
   Expected: The customer can match the receipt to their statement.
4. For charges that stay pending past your window, send a "payment processing" notice instead of a receipt.
   Expected: Customers are informed without being told a payment completed.

## Prevention

Charge attempt and settlement are two different events hours or days apart. Any flow that treats the attempt as the trigger for the receipt will eventually send one for a payment that later fails or stays pending. Wire receipts to settlement only.

## Detection

Compare receipt timestamps against settlement timestamps; any receipt sent before its payment settled is a hit. Watch disputes with the reason "unrecognized" where a receipt went out early. Alert when a receipt exists for a payment still in pending.

## Recovery

Contact the customer, explain the pending charge will either settle or drop off, and confirm you will send the real receipt on settlement. If they already disputed, provide the settlement evidence to the dispute process. Then fix the trigger.

## When this applies

- Receipts go out at charge time and customers dispute the pending charge
- The receipt claims payment succeeded before the provider confirms it
- Duplicate receipts follow retried webhooks

## When it doesn't

- The payment settled and the customer disputes anyway (that is a recognition or fraud dispute)
- No receipt was sent at all (different problem)
- The receipt was for a failed payment by design (reconsider that design)

## Compatibility

Stripe API (charge succeeded and payment intent succeeded webhooks), Adyen (authorisation and capture notifications), PayPal REST API v2 (payment capture webhooks). Any provider with distinct attempt and settlement events.

### receipt emailed before the charge settled

### customer disputed a pending charge after getting the receipt early

### renewal receipt sent on attempt instead of settlement

## Why it happens

The agent wants to close the loop fast, so it sends the receipt right after the charge call returns. The charge call returning is not settlement; it is an authorization or a pending capture. The customer sees a receipt for money that has not moved, then sees a pending charge they do not recognize, and disputes.

## Edge cases

- Slow-capture methods (bank debits, some wallets): pending can last days; the "processing" notice matters most here
- Webhook delays: if settlement webhooks lag, poll the payment status on a schedule as a backup trigger
- Partial captures: the receipt must reflect the captured amount, not the authorized amount

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_AQAM6NprFWCOAcDuBacyaw
