Token Pay Platform
Let each project monetize its native SPL token via x402 self-settle — without building RPC, price oracle, or on-chain verification infra. The default merchant today is TCX (Concierge utility token).
Concierge Token Pay complements USDC settlement via PayAI / Dexter. Users pay in the project token on Solana (user pays SOL gas); the server verifies the transfer on-chain — no facilitator hot wallet.
Status: TCX is live — mint F2bnJW1z55UQ9ZqGX5RwYQfvNJrd23n66eyBV5QZpump. Set SOON_TOKEN_MINT on Vercel to enable checkout; pricing flows from DexScreener with SOON_USDC_RATE as fallback. Other projects register via TOKEN_PAY_MERCHANTS_JSON.
What is Token Pay?
Token Pay lets your project monetize its own native SPL token as an x402 payment option (alongside USDC). Users sign the token transfer in their wallet; Concierge verifies and settles via self-settle on-chain.
For developers: register your token once on Concierge. After your merchant is live, callers can pay
with your token on supported x402 routes — revenue lands in your payTo wallet.
No need to build RPC, price oracle, or settlement verification yourself.
What you provide
- Token mint (live on Solana) + decimals
- Receive wallet (
payTo) — where x402 token payments are credited - Pricing: DexScreener (recommended) or a static USD fallback
- Routes: which paid APIs should list your token (
resourceKinds)
What Concierge handles
- Token amount resolution from USDC list pricing
- Token accept inside the
402response - Simulate → broadcast → confirm → verify the token delta on-chain (no facilitator hot wallet)
Public APIs
GET /api/token-pay— platform meta + merchant registry + readinessGET /api/token-pay-analytics?merchant=ID— tx count, volume, daily chart dataGET /api/token-pay-build-accept— server-built accept for partner APIsPOST /api/token-pay-verify— verify + settle on partner domainsGET /api/x402-config— includestokenPayconfig for your accept builder
Integrate Token Pay in your project
Use this flow when your team wants users or agents to pay with your native token for x402-gated APIs — whether they call Concierge directly or your app wraps Concierge calls.
Step 1 — Configure your merchant
Self-service: Onboarding wizard — fill the form, validate via POST /api/token-pay-preview, copy the env line. Or edit JSON manually:
Add your row to TOKEN_PAY_MERCHANTS_JSON in environment variables, then redeploy:
- Local test — copy
.env.example, setTOKEN_PAY_MERCHANTS_JSON, runnpm run dev - Production — append your row in Vercel env on the Concierge deploy and redeploy
{
"id": "acme",
"symbol": "ACME",
"name": "ACME Protocol",
"mint": "YourMintBase58…",
"decimals": 6,
"payTo": "YourSolanaReceiveWallet…",
"priceSource": "dexscreener",
"fallbackUsd": 0.001,
"resourceKinds": ["external", "concierge"],
"allowedOrigins": ["https://api.acme.xyz", "https://acme.xyz"],
"x402Enabled": true
}
Required: unique id, live mint, your payTo wallet, and decimals.
Create an ATA on payTo by sending a tiny amount of your token once.
Stuck after fixing readiness.blockers? Contact the Concierge team on
Telegram.
Step 2 — Confirm readiness (before launch)
curl -s "https://conc-exe.xyz/api/token-pay?merchant=acme" | jq '.merchant.readiness'
Target: status: "ready" and acceptReady: true. Or open
Token Pay Dashboard (/agent/token-pay?merchant=acme).
Step 3 — Wire your x402 client
On any supported route (e.g. POST /api/concierge):
- Call without payment → receive 402 +
PAYMENT-REQUIRED - Decode
accepts[]— pick entry withextra.settlement === "self"andextra.merchantId === "acme" - Sign SPL
transferCheckedtopayToforamountatomic units ofasset(mint) - Retry with
PAYMENT-SIGNATURE→ server verifies on-chain → 200 + JSON body
Browser reference: frontend/lib/x402-browser-client.ts + x402-solana-self-scheme.ts.
Load merchant config from GET /api/x402-config → tokenPay.merchants.
Agents can use pay curl or any x402 HTTP client the same way as USDC — select the token accept instead of USDC.
Step 4 — Ship in your product
- Agent / backend — call Concierge paid routes; pass
PAYMENT-SIGNATUREwith your token accept (users or treasury wallet signs) - Web app — embed pay flow like Executive Lounge: fetch config, show your token in the pay modal, self-settle in Phantom/OKX
- Community — publish
GET /api/token-pay?merchant=YOUR_IDfor liveconciergeAtomicamounts and pricing labels
Revenue: every successful settlement credits your payTo wallet. Track volume on
/agent/token-pay or GET /api/token-pay-analytics.
Step 5 — End-to-end test
- Run one paid call with your token (Playground, Lounge, or
curl+ x402 client) - Confirm HTTP 200 +
PAYMENT-RESPONSEheader contains Solanatransaction - Open the signature on Solscan — your
payTotoken balance increased - Dashboard tx count increments (requires KV in production for persistent analytics)
Token Pay on your own API (partner verify)
Gate your endpoints (e.g. api.acme.xyz) with x402 + your native token.
Concierge builds the accept, verifies the on-chain payment, and credits your payTo wallet —
no extra Vercel functions (uses the existing Edge router).
Merchant setup
Include "external" in resourceKinds. Optional allowedOrigins restricts browser calls to build/verify APIs.
curl -s "https://conc-exe.xyz/api/token-pay?merchant=acme&resource=external" | jq '.merchant.readiness'
1. Build accept (your backend)
curl -s -X POST https://conc-exe.xyz/api/token-pay-build-accept \
-H "Content-Type: application/json" \
-d '{"merchantId":"acme","usdAmount":0.1,"resourceUrl":"https://api.acme.xyz/v1/intel"}'
Returns accept — use it in your 402 + PAYMENT-REQUIRED response.
2. User pays (wallet signs SPL transfer)
Same self-settle flow as Concierge routes — client signs transferChecked to your payTo.
3. Verify via Concierge
curl -s -X POST https://conc-exe.xyz/api/token-pay-verify \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <base64 payment payload>" \
-d '{"merchantId":"acme","usdAmount":0.1,"resourceUrl":"https://api.acme.xyz/v1/intel"}'
On success: HTTP 200, JSON with transaction, header PAYMENT-RESPONSE. Then return your API response to the user.
SDK — @conc-exe/token-x402
TypeScript helper in packages/token-x402 (monorepo). Wraps build + verify:
import { createConciergeTokenPayClient } from "@conc-exe/token-x402";
const tp = createConciergeTokenPayClient({ origin: "https://conc-exe.xyz" });
const { accept } = await tp.buildAccept({ merchantId: "acme", usdAmount: 0.1, resourceUrl });
const verified = await tp.verifyPayment({ merchantId: "acme", usdAmount: 0.1, resourceUrl, paymentSignature });
Optional dedicated host: point pay.conc-exe.xyz to the same Vercel project (add domain in Vercel) and use it as origin.
Verify connection & monitor usage
Token Pay includes a per-merchant dashboard. Use the Concierge checks below to verify and monitor your merchant.
1. Readiness API (before any user pays)
After your merchant row is deployed, poll:
curl -s "https://conc-exe.xyz/api/token-pay?merchant=YOUR_ID" | jq '.merchant.readiness'
Target: status: "ready" and acceptReady: true. If not, read blockers[] (missing ATA, price, mint, etc.).
| status | Meaning |
|---|---|
ready | Will appear in 402 accepts for the probed resource |
ata_missing | Send a tiny token transfer to payTo once |
price_unavailable | Set fallbackUsd or list on DexScreener |
coming_soon | Mint not configured on server (partner pre-launch) |
Browser UI: Agent Discover · Token Pay Dashboard shows live readiness + settlement analytics.
2. 402 accept probe (integration wired)
curl -s -X POST https://conc-exe.xyz/api/concierge \
-H "Content-Type: application/json" \
-d '{"mode":"chat","message":"probe"}' -D - -o /dev/null 2>&1 | grep -i payment-required
Decode the base64 PAYMENT-REQUIRED header → accepts[] must include your token with extra.merchantId: "YOUR_ID" and extra.settlement: "self".
3. Successful payment (end-to-end)
- HTTP 200 on the paid route + JSON body (e.g.
replyfor Concierge) - Response header
PAYMENT-RESPONSE(base64) containstransaction= Solana signature - On-chain: open the signature in Solscan — merchant
payTotoken balance increased
Concierge monitoring tools
| Tool | What you see |
|---|---|
GET /api/token-pay | Per-merchant readiness, pricing, acceptReady |
| /agent/token-pay | Dashboard — readiness, tx count, volume chart, recent settlements + Solscan |
| /agent/discover | Live registry + readiness counts |
GET /api/token-pay-analytics | JSON totals, daily rollups, recent tx list |
| Solana explorer | On-chain proof — token credited to your payTo wallet |
Use readiness API + Token Pay Dashboard + one test payment + Solscan for definitive proof.
Security model (per merchant)
- Funds isolation — each partner must set their own
payTowallet; token payments never fall back to Concierge’sX402_SOL_PAY_TO. - Registry gate — settlement re-checks
merchantId, mint, payTo, andresourceKindsagainst the server registry before broadcast. - 402 matching — payment must match an accept the server issued (scheme, network, amount, asset, payTo).
- On-chain verify — simulate → broadcast → confirm → verify token delta to the merchant wallet.
- Price guards — optional
usdMin/usdMaxper merchant; DexScreener cache per merchant id. - No hot wallet — Concierge never holds partner private keys; users sign transfers in their own wallet.
Reserved slug soon cannot be registered via JSON. Merchant ids must be lowercase a-z0-9_- (max 16 partners per deploy).
vs USDC facilitators
| PayAI / Dexter | Token Pay | |
|---|---|---|
| Model | Facilitator (gasless USDC) | Self-settle (user pays SOL gas) |
| Asset | USDC | Project native token |
| Price | Fixed USDC list price | DexScreener + env fallback |
| Phase 1 route | All paid APIs | POST /api/concierge (more routes later) |
Public APIs
GET /api/token-pay— platform meta + merchant registryGET /api/token-pay?merchant=soon— single merchant configGET /api/x402-config— includestokenPay(and legacysoonX402)
curl -s https://conc-exe.xyz/api/token-pay | jq '{live: .liveMerchantCount, merchants: [.merchants[] | {id, symbol, live, conciergeAtomic}]}'
curl -s "https://conc-exe.xyz/api/token-pay?merchant=acme" | jq '.merchant'
Pay with a partner token (agents & apps)
After your merchant is live, callers can pay Concierge with your SPL token instead of USDC:
POST /api/concierge(or another route in yourresourceKinds) → receive 402 +PAYMENT-REQUIRED- Decode
accepts— pick the entry whereextra.settlement === "self"andextra.merchantId === "your-id" - Sign an SPL
transferCheckedtopayToforamountatomic units ofasset(mint) - Retry with
PAYMENT-SIGNATURE— server simulates, broadcasts, confirms on-chain delta
USDC routes still use PayAI/Dexter facilitators. Token Pay accepts are separate Solana entries in the same accepts array. Browser reference: frontend/lib/x402-browser-client.ts + x402-solana-self-scheme.ts.
# Inspect accepts (decode PAYMENT-REQUIRED header from 402)
curl -s -X POST https://conc-exe.xyz/api/concierge \
-H "Content-Type: application/json" \
-d '{"mode":"chat","message":"test"}' -D - -o /dev/null 2>&1 | grep -i payment-required
Merchant JSON fields
| Field | Required | Description |
|---|---|---|
id | yes | Stable slug (a-z0-9_-, 2–32 chars). Reserved: soon |
symbol | yes | Ticker shown in UI |
mint | yes | SPL mint (base58) |
payTo | yes | Your Solana receive wallet — where token payments are credited |
decimals | yes | Token decimals (usually 6) |
priceSource | no | dexscreener (default) or env |
fallbackUsd | recommended | USD per 1 token when oracle fails |
usdMin / usdMax | no | Price sanity bounds |
resourceKinds | no | concierge, external (your own API), etc. |
allowedOrigins | no | Browser origins allowed for build/verify APIs |
x402Enabled | no | Set false to disable without removing row |
Resource kinds
Your token appears in 402 accepts only for routes listed in resourceKinds:
| resourceKind | API route | USDC price |
|---|---|---|
concierge | POST /api/concierge | $0.10 |
news | POST /api/news-open | $0.10 |
signal-open | POST /api/lounge-signal-open | $0.10 |
signal-publish | POST /api/lounge-signal-publish | $1.00 |
intel-* | POST /api/concierge-intel-* | $0.10 |
Default for new merchants is ["concierge"]. Request additional routes when you expand your integration.
Merchant registration checklist
Add your token via TOKEN_PAY_MERCHANTS_JSON in environment variables and redeploy.
When your merchant is live (mint + payTo + resolvable price), every 402 response
for matching resource kinds includes a self-settle accept for your token — alongside USDC.
Checklist
- Add your row to
TOKEN_PAY_MERCHANTS_JSON(local.envor Vercel env) and redeploy - Ensure
payTowallet has an ATA for your mint (send a tiny amount once) - Set
fallbackUsdor list on DexScreener for live price - Confirm
GET /api/token-pay?merchant=YOUR_ID→readiness.acceptReady: true - Confirm
GET /api/x402-configshows your merchantlive: trueandconciergeAtomic - Run a test paid call — inspect
PAYMENT-REQUIREDfor yourmerchantIdaccept - Verify Solscan + dashboard after first settlement
Example registry row
TOKEN_PAY_MERCHANTS_JSON=[
{
"id": "acme",
"symbol": "ACME",
"name": "ACME Protocol",
"mint": "YourMintBase58…",
"decimals": 6,
"payTo": "YourSolanaReceiveWallet…",
"priceSource": "dexscreener",
"fallbackUsd": 0.001,
"resourceKinds": ["external", "concierge"],
"allowedOrigins": ["https://api.acme.xyz"],
"x402Enabled": true
}
]
resourceKinds controls which paid APIs list your token:
concierge, news, signal-open, signal-publish, and intel routes as configured.
Multiple live merchants appear as separate options in the Lounge pay modal.
Need help after self-service setup? Telegram — Theconcierge33
x402 accept (self-settle)
When live, Concierge 402 responses include one or more Solana token accepts alongside USDC (one per live merchant):
{
"scheme": "exact",
"network": "solana:…",
"amount": "<atomic TCX>",
"asset": "<TCX mint>",
"payTo": "<merchant receive wallet>",
"extra": {
"settlement": "self",
"merchantId": "soon",
"name": "TCX",
"decimals": 6
}
}
Executive Lounge signs transferChecked in the browser; the Edge API simulates, broadcasts, and confirms the merchant token delta.
Environment (TCX merchant)
TOKEN_PAY_DEFAULT_MERCHANT=soon
SOON_TOKEN_MINT=F2bnJW1z55UQ9ZqGX5RwYQfvNJrd23n66eyBV5QZpump
SOON_TOKEN_DECIMALS=6
SOON_PRICE_SOURCE=dexscreener
SOON_PRICE_MAX_AGE_SEC=60
SOON_USDC_RATE=0.00008 # fallback
X402_SOL_PAY_TO= # merchant receive (USDC + TCX)
Add partner merchants via TOKEN_PAY_MERCHANTS_JSON (see registration checklist). TCX uses X402_SOL_PAY_TO for receive. See Architecture and docs/token-pay-platform.md in the repository.
For your community (end users)
Once live, your token appears in the Executive Lounge pay modal alongside USDC. Users need:
- Phantom or OKX with Solana connected
- Enough of your token for the quoted atomic amount
- A small amount of SOL for transaction fees (self-settle)
Promote: GET /api/token-pay?merchant=YOUR_ID for live pricing labels and conciergeAtomic amounts.
Related
- TCX tokenomics — operating policy · holder tiers
- TCX transparency — weekly buyback & burn ledger
- Executive Lounge — pay modal lists USDC + all live Token Pay merchants
- For Builders — integration paths for agents
- x402 Protocol — USDC flow via PayAI/Dexter
Concierge · Executive Lounge