Skip to content

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

  • id string Required
    The checkout's ID, such as chk_8zXVc2SbCBDho78Q.

Body

  • tx_hash string Required
    The transaction hash from the customer's wallet, on the checkout's network.
  • email string
    The customer's email, kept when the checkout has none yet, so you can reach them.

Errors

  • 400 invalid_request
    A field other than tx_hash or email was sent.
  • 400 invalid_tx_hash
    tx_hash isn't a transaction hash on the checkout's network.
  • 400 invalid_email
    email isn't a valid email address.
  • 404 not_found
    No checkout has that ID.
  • 409 wrong_rail
    The checkout is for a card, which finishes on the secure payment page.
  • 409 payment_paid
    The payment has already succeeded.
  • 409 already_claimed
    The checkout already needs review.
  • 409 checkout_not_claimable
    The 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"
  }'
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"
  }
}