Skip to content

Token issuer restrictions ​

Some stablecoin issuers can freeze an address on-chain. Circle can blacklist an address on USDC and Tether can blacklist one on USDT, usually because of a court order, a sanctions listing or a request from law enforcement. Once that happens, the token contract itself refuses the affected transfers. No wallet, app or payment provider can get around it, Klappay included.

Klappay doesn't decide which addresses are restricted. It keeps no blocklist of its own and uses no third-party sanctions list. Every check on this page reads the token contract's own public status, so Klappay only refuses what the blockchain would refuse anyway, and does it early enough that money doesn't get stuck.

What each token restricts ​

TokenIssuer functionRestricted address can receive?Restricted address can send?
USDCisBlacklistedNoNo
USDT on EthereumisBlackListedYesNo
USDT on Polygon, Arbitrum, Avalanche (USDT0)isBlockedYesNo

Some tokens have no public function to ask: USDT on Base and Optimism, and both tokens on BNB Chain. Their issuer can still freeze addresses, but Klappay has no way to see it ahead of time, so these pairs are always reported as unknown.

What happens at each step ​

StepWhat Klappay doesWhat you see
Registering a recipientNothing is blocked.Call GET /v1/recipients/{id}/transferability to see the status per pair and warn the address's owner early. See recipients.
Creating a chargeChecks whether every address the charge pays (your payout address, each split recipient, Klappay's fee treasury) can receive on each accepted pair.422 recipient_transfer_restricted, listing only the affected TOKEN on network pairs. Drop them from acceptedPayments and retry. See charges.
PayingKlappay never checks the payer.If the payer's own address is restricted, their wallet's transfer fails on-chain and the charge simply stays unpaid.
Paying outBefore distributing, checks that the split can send and that every recipient can receive.If an address became restricted after the charge was created, the payout is held: the funds stay in the charge's split contract, the charge keeps its status (confirmed or underpaid) with settlementStatus: pending, and no webhook is sent. Klappay checks again every hour and pays out normally if the issuer lifts the restriction. See distributions.

A USDT recipient whose address is restricted is still paid, because USDT never checks who receives. The money then sits in that address until the issuer lifts the restriction. The transferability endpoint shows this as receive: allowed, send: restricted, which is worth telling the address's owner.

When Klappay can't tell ​

Each check reads the token contract live, with a 1 second limit. If the read fails, times out, or the token has no function to ask, the result is unknown, and unknown never blocks a charge or a payout. Klappay also never saves these results: a definite answer is cached in memory for up to 5 minutes and an unknown for 30 seconds, so a change made by the issuer can take that long to show.

What to do as an integrator ​

  • Check a recipient with GET /v1/recipients/{id}/transferability when it's registered, not only when a charge fails.
  • On 422 recipient_transfer_restricted, offer the payer the remaining pairs. For example, a USDC-restricted payout address can usually still be paid in USDT.
  • If a restricted address belongs to someone you work with, ask them for another address. Only the token issuer can lift a restriction; Klappay can't.
  • A paid charge that gets no charge.settled for hours may be a held payout. Contact Klappay support with the charge id.

Public docs for @klappay/types, mirrored from this package's own docs/ folder.