Redeem Code — Payment Codes
One-time use codes — issuer pre-authorizes, recipient redeems
The Payment Codes model is issuer-initiated. The issuer (payer) connects their EVM wallet, signs an EIP-3009 transferWithAuthorization, and RelAI registers it on SKALE L3 — returning a short 8-character code. The issuer passes the code to the recipient (merchant, cashier, agent). When the recipient enters the code at /redeem, USDC settles instantly — even if the issuer is offline.
Think of it as a digital cheque: the issuer writes it, hands it over, and the recipient cashes it at any time before expiry.
How It Works
/dashboard/payment-codesPaymentSettler.settle() on L2 (Base)Security: The EIP-3009 signature commits the exact amount and the settler contract as recipient. No one can redirect the funds or change the amount. The code alone is sufficient to trigger settlement — keep it private until redemption.
SKALE private settlement: When using the SKALE Base Sepolia network, the settlement transaction is BITE-encrypted — amounts and participants are private on-chain.
Using the Redeem UI
Recipients redeem codes at /redeem. No wallet or login required for the recipient — just the 8-character code.
- 1Enter the 8-character code received from the issuer
- 2Optionally enter your wallet address as payee (defaults to relayer if blank)
- 3Click Redeem — no signature required from the recipient
- 4L3 registration confirmed → L2 settlement executes
- 5Explorer links for both L3 (SKALE) and L2 (Base) transactions shown on success
Generating Codes (API)
Codes can be generated programmatically via the facilitator API. The issuer must provide a pre-signed EIP-3009 authorization.
/facilitator/payment-codesRegister a pre-signed EIP-3009 authorization and receive an 8-char code.
/facilitator/payment-codes/:code/redeemRedeem a code. Triggers L2 settlement. Returns tx hashes.
/facilitator/payment-codes/:codeCheck code status (active, redeemed, expired).
/facilitator/payment-codes/:codeCancel an active code before redemption.
curl -X POST https://api.relai.fi/facilitator/payment-codes \
-H "X-Service-Key: sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"from": "0xIssuerWallet",
"signature": "0xEIP3009Signature...",
"value": 5000000,
"validBefore": 1735000000,
"nonce": "0xRandomNonce32Bytes",
"settlementNetwork": "base-sepolia",
"ttl": 300
}'
# Response
{
"code": "D92T5TPW",
"validBefore": 1735000000,
"expiresIn": 300
}{
"success": true,
"code": "D92T5TPW",
"l3TxHash": "0xskale...",
"l2TxHash": "0xbase...",
"explorerUrl": "https://basescan.org/tx/0xbase...",
"settlementNetwork": "base-sepolia",
"private": false
}Settlement Networks
| Network | ID | L3 Registration | L2 Settlement | Privacy |
|---|---|---|---|---|
| Base Sepolia | base-sepolia | SKALE L3 (gasless) | Base Sepolia | Public |
| SKALE Base Sepolia | skale-base-sepolia | SKALE L3 (gasless) | SKALE Base Sepolia | 🔒 BITE encrypted |
Error Handling
not_found— Code not foundThe code does not exist — check for typos or confirm the issuer generated it successfully.
expired— Code expiredThe TTL elapsed. The issuer must generate a new code.
already_redeemed— Already redeemedThis code was already settled. Each code is single-use.
cancelled— Code cancelledThe issuer cancelled the code before it was redeemed.
settlement_failed— L3 OK · L2 failedThe SKALE L3 registration succeeded but L2 settlement failed. Contact support with the L3 tx hash.