Skip to Content
CheckoutAPI ReferencePaymentsReopen an expired payment

Reopen an expired payment

POST/payments/{id}/reopen

Re-arm an expired one-shot payment under a new deadline, with or without a recorded deposit, or re-arm a direct payment whose deploy deadline passed after it was funded. Send one signature per entry of the payment object's payment_options, all under the same deadline (signReopen() from @exodus/checkout-signer builds the body from the payment object). Signatures verify against the business's current factory (factory_address); a payment whose addresses no longer derive from it, after a signer rotation, is refused with factory_rotated. Direct payments sign a fresh deploy and need a deadline at least 30 minutes ahead; two-step payments sign a Reopen message. Every address is registered again, and the deposits already recorded are judged before the response: one that covers an address funds the payment under the new deadline. The response is the payment object. The status in the response reflects the deposits already recorded. Deposits not yet recorded surface after the reopen through the deposit poll: recent ones (the last 6,000 blocks of each chain, about 25 minutes on Arbitrum One and longer on every other chain) typically within about a minute, one cron tick, and older ones typically within about 50 minutes for each day since the payment was created, for a payment option enabled on every supported mainnet (a little under 6 hours for a payment created a week earlier), twice that for a fiat-settled payment with a USDC and a USDT option, and sooner for a payment on fewer chains. These figures assume approximate published block cadences, 12,000 blocks (24 pages of 500) of catch-up per minute left after the poll's own deposit scan, which for the reopened payment starts at its floor, and one reopened payment in the backlog at a time. A refusal is a 409 payment_not_reopenable whose data.cause is one of not_expired (the payment is not expired, a deploy is in flight, or it changed while reopening; the message names which), flagged, checkout_closed, unsupported_method (defensive, no current payment method reaches it), solana_not_supported, factory_rotated (the business rotated its signer, so the addresses no longer derive from its current factory, or the signer configuration changed while reopening; the message names the second case), signer_missing (the business has no merchant signer configured), config_invalid (the business's payment configuration lists no supported chains) or fiat_settlement_not_reopenable (the business settles in fiat, so the quoted token amount is tied to a price lock that a reopen cannot honour; the payment stays expired). A 503 service_unavailable with code: chain_unavailable means the chain could not be reached before anything was written; retry later.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your secret API keyyes

Path Parameters

NameTypeRequiredDescription
idstringyes

Request Body

FieldTypeRequiredDescription
deadlineintegeryes
signaturesobject[]yes

signatures

FieldTypeRequiredDescription
on_chain_idstringyes
signaturestringyes

Example Request

Request

const response = await fetch('https://checkout-api.exodus.com/payments/<id>/reopen', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "deadline": 1798761600,
    "signatures": [
      {
        "on_chain_id": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
        "signature": "0x8106eb4a89add4e134b91dfd43edc51e9499df687b4f8fd8f5b51e070326abad033e4ad556d1f34cf65da3e547d388f8672dfb0233f1b2c18e774e121c10030e1c"
      }
    ]
  }),
});

Responses

StatusDescription
200The reopened payment.
400Validation error
401A reopen signature does not verify
403API key lacks the required scope
404Resource not found
409The payment cannot be reopened
503The chain could not be reached; nothing was written

Response body

FieldTypeRequiredDescription
idstringyes
objectenum: paymentyes
statusenum: client_deposit_pending | client_deposit_detected | client_deposit_confirmed | client_deposit_expired | escrow_confirmed | settlement_pending | settled | failed | refunded | cancelledyes
payment_methodenum: direct | two_stepyes
detected_assetstring | nullyes
detected_token_symbolstring | nullyes
detected_chainstring | nullyes
token_amountstring | nullyes
token_amount_decimalstring | nullyes
deposit_addressstring | nullyes
payer_addressesstring[]yes
on_chain_idstring | nullyes
factory_addressstring | nullyes
payment_optionsobject[]yes
created_atstring · date-timeyes
flaggedbooleanyes

payment_options

FieldTypeRequiredDescription
on_chain_idstringyes
deposit_addressstringyes
chain_familystringyes
tokenstring | nullyes

Example Response

{
  "id": "tz4a98xxat96iws9zmbrgj3a",
  "object": "payment",
  "status": "settled",
  "payment_method": "two_step",
  "detected_asset": "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "detected_token_symbol": "USDC",
  "detected_chain": "eip155:1",
  "token_amount": "50000000",
  "token_amount_decimal": "50",
  "deposit_address": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
  "payer_addresses": [
    "0x742d35Cc6634C0532925a3b844Bc9e7595f8fE21"
  ],
  "on_chain_id": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
  "factory_address": "0x2f1c4e7b9a3d5c8e6f0a1b2c3d4e5f6a7b8c9d0e",
  "payment_options": [
    {
      "on_chain_id": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b",
      "deposit_address": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
      "chain_family": "evm",
      "token": "USDC"
    }
  ],
  "created_at": "2024-01-15T12:30:00Z",
  "flagged": false
}

Error Response

Error (e.g. 400)

{
  "error": {
    "type": "validation_error",
    "message": "amount must be a positive number",
    "param": "amount"
  }
}

Start building

XO

Request Demo

Schedule a call with our team

Select a product
Arrow right

Start building
Grateful

Contact Us

We're here to help