Claim a transfer
Let a customer report a transfer by its hash after their checkout closed.
For a customer who paid after their checkout closed, or after canceling it. Public, like creating a checkout: the checkout's ID is all it takes. Called with your secret key, the response also has email, reporting and fee_rate_bps.
Works on an expired or canceled crypto checkout. The checkout and its payment become needs_review with a review_reason of claimed, the payment's timeline gains a claimed event with the hash, and you receive payment.needs_review.
Nothing checks the hash for you. Look it up on the network first, then accept the payment: accepting a claim counts the full quoted amount as received.
Path
idstring RequiredThe checkout's ID, such aschk_8zXVc2SbCBDho78Q.
Body
tx_hashstring RequiredThe transaction hash from the customer's wallet, on the checkout's network.emailstringThe customer's email, kept when the checkout has none yet, so you can reach them.
Errors
- 400
invalid_requestA field other thantx_hashoremailwas sent. - 400
invalid_tx_hashtx_hashisn't a transaction hash on the checkout's network. - 400
invalid_emailemailisn't a valid email address. - 404
not_foundNo checkout has that ID. - 409
wrong_railThe checkout is for a card, which finishes on the secure payment page. - 409
payment_paidThe payment has already succeeded. - 409
already_claimedThe checkout already needs review. - 409
checkout_not_claimableThe checkout isn't expired or canceled, so it's still watching for the transfer.
Any request can also fail on its key or its body. See errors.
Request
curl -X POST "https://api.402pay.co/api/v1/checkouts/chk_8zXVc2SbCBDho78Q/claim" \
-H "Content-Type: application/json" \
-d '{
"tx_hash": "0x5e2b8c0f4a91d37e6b0c2f8a14d9e7c3b6a05f1d28e4c9b7a3f6d0e1c8b2a4f7"
}'const response = await fetch("https://api.402pay.co/api/v1/checkouts/chk_8zXVc2SbCBDho78Q/claim", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
tx_hash: "0x5e2b8c0f4a91d37e6b0c2f8a14d9e7c3b6a05f1d28e4c9b7a3f6d0e1c8b2a4f7"
}),
});
const { data } = await response.json();import requests
response = requests.post(
"https://api.402pay.co/api/v1/checkouts/chk_8zXVc2SbCBDho78Q/claim",
json={
"tx_hash": "0x5e2b8c0f4a91d37e6b0c2f8a14d9e7c3b6a05f1d28e4c9b7a3f6d0e1c8b2a4f7"
},
)
data = response.json()["data"]Response200 OK
{
"data": {
"id": "chk_8zXVc2SbCBDho78Q",
"kind": "checkout",
"status": "needs_review",
"rail": "crypto",
"link_id": null,
"payment_id": "pmt_pxYW5vHfVt1xTIT2",
"amount": "49.00",
"currency": "USD",
"breakdown": {
"currency": "USD",
"price": "49.00",
"processing_fee": null,
"network_fee": "0.90",
"total": "49.90"
},
"crypto": {
"asset": "USDC",
"network": "ethereum",
"amount": "49.00",
"address": "0xB82AFd9E40ED990A37c7eeB43e8d04528732ef39",
"payment_uri": "ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48@1/transfer?address=0xB82AFd9E40ED990A37c7eeB43e8d04528732ef39&uint256=49000000",
"rate": {
"amount": "1.00",
"currency": "USD"
},
"received_amount": "0.00",
"remaining_amount": null,
"remaining_payment_uri": null,
"overpaid_amount": null,
"detected_network": null,
"tx_hash": null,
"explorer_url": null
},
"card": null,
"confirmations": {
"current": 0,
"required": 2
},
"remainder": false,
"canceled_by": null,
"replaced_by": null,
"failure_code": null,
"review_reason": "claimed",
"success_url": "https://example.com/thanks",
"expires_at": "2026-09-27T18:27:57.906Z",
"sent_at": null,
"created_at": "2026-09-27T18:12:57.906Z",
"updated_at": "2026-09-27T18:13:10.639Z"
}
}