SpendPreflight
Practical guide · November 9, 2026

Keep payment receipts and delivery evidence separate.

After an authorized API purchase, keep the payment record, the response you actually received and your application checks together. Each answers a different question. A transfer receipt alone does not show that an API delivered the promised result.

1. Preserve the payment event and the original receipt

The ERC-20 Transfer event records sender, recipient and token amount. Identify an event with its chain, token contract, transaction hash and log index: a transaction can contain several transfers. Keep exact atomic amounts and the observed block information. A token symbol or transaction hash alone is not enough to select the intended transfer.

Retain a receipt's original bytes. If it is signed, verify the signature and issuer key using the receipt format's documented procedure before relying on that signature. Keep the verification outcome and observation time separately. A valid issuer signature does not establish merchant delivery, wallet ownership or the business purpose of the transfer.

2. Capture the response that your client saw

Coinbase's x402 flow separates the payment challenge, signed payment, verification, work, settlement and resource response. Your records should preserve the boundaries you actually observed. An unsigned 402 offer is not a completed purchase; a signed authorization is not proof that settlement completed.

For an already authorized call, retain the request method and resource, exact challenge and request-body bytes, HTTP status, response-body bytes, observation time and whether the body completed. Record a timeout, abort or network error explicitly. Do not fill an absent response with an empty successful result or silently turn a partial body into a complete one.

Store these files privately with access controls and a retention policy. Request or response content can contain personal or commercial information. Keep authentication headers, wallet keys and reusable payment authorizations out of shared evidence bundles. Preserve original bytes privately; label a redacted copy as a derivative because its hash will differ.

3. Define a small application contract

Write down what the caller expected before examining the result: for example, HTTP 200, a complete JSON object and a required answer field. Check the captured response against those rules. A field's presence does not establish that its value is correct, fresh or useful; deeper meaning needs your own domain checks.

Saved observationWhat you can recordWhat remains unresolved
Complete response meets the declared checksCaller observed a matching responseTruth, usefulness and independent delivery proof
Complete response fails a declared checkThe specific contract mismatchCause, remedy and any refund entitlement
Timeout, partial body or missing associationUnknown outcome with the missing evidenceWhether the merchant completed work or a payment settled

4. Add an offline attachment without changing the receipt

The published SpendPreflight SDK 0.3.4 includes createDeliveryEvidence and verifyDeliveryEvidence. The first hashes caller-supplied bytes into a separate unsigned attachment; the second checks consistency against supplied source bytes. Neither function contacts a merchant, queries a chain, verifies the receipt signature, signs evidence or pays.

Review the pinned offline example and helper source. The example uses synthetic bytes and an explicitly unverified fixture signature. Its successful consistency check demonstrates only that the attachment matches those supplied inputs. It is not a live purchase or merchant attestation.

Keep the original receipt and attachment as separate files. Associate the transaction hash and log index only when you have evidence for that association. Without it, retain payment_association_unknown. Hashes can detect later byte changes relative to saved references; a caller able to replace both the files and references can also replace the story.

5. Inspect an uncertain attempt before paying again

A missing response does not establish non-payment. Preserve the attempt identifier, observed transport outcome and any available settlement reference. Reconcile that same attempt through the service's documented process before deciding whether another authorized purchase is appropriate. This guide does not authorize a retry, new signature, payment or target probe.

Review USDC Receipt inputs and evidence limits →

For a longer wallet period, use the separate statement reconciliation guide. Neither workflow decides invoice status, tax treatment, customer identity or legal remedies.

Written by SpendPreflight. Sources and existing SDK 0.3.4 behavior reviewed November 9, 2026. This article uses no customer records and executes no purchase.