Payment

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 SOON (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: SOON appears in the Lounge payment modal as Coming soon until the token launches. After launch, set SOON_TOKEN_MINT on Vercel — pricing flows from DexScreener with SOON_USDC_RATE as fallback.

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 402 response
  • Simulate → broadcast → confirm → verify the token delta on-chain (no facilitator hot wallet)

Public APIs

  • GET /api/token-pay — platform meta + merchant registry + readiness
  • GET /api/token-pay-analytics?merchant=ID — tx count, volume, daily chart data
  • GET /api/token-pay-build-accept — server-built accept for partner APIs
  • POST /api/token-pay-verify — verify + settle on partner domains
  • GET /api/x402-config — includes tokenPay config 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, set TOKEN_PAY_MERCHANTS_JSON, run npm 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):

  1. Call without payment → receive 402 + PAYMENT-REQUIRED
  2. Decode accepts[] — pick entry with extra.settlement === "self" and extra.merchantId === "acme"
  3. Sign SPL transferChecked to payTo for amount atomic units of asset (mint)
  4. 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-configtokenPay.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-SIGNATURE with 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_ID for live conciergeAtomic amounts 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

  1. Run one paid call with your token (Playground, Lounge, or curl + x402 client)
  2. Confirm HTTP 200 + PAYMENT-RESPONSE header contains Solana transaction
  3. Open the signature on Solscan — your payTo token balance increased
  4. 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.).

statusMeaning
readyWill appear in 402 accepts for the probed resource
ata_missingSend a tiny token transfer to payTo once
price_unavailableSet fallbackUsd or list on DexScreener
coming_soonMint not live yet (e.g. SOON 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. reply for Concierge)
  • Response header PAYMENT-RESPONSE (base64) contains transaction = Solana signature
  • On-chain: open the signature in Solscan — merchant payTo token balance increased

Concierge monitoring tools

ToolWhat you see
GET /api/token-payPer-merchant readiness, pricing, acceptReady
/agent/token-payDashboard — readiness, tx count, volume chart, recent settlements + Solscan
/agent/discoverLive registry + readiness counts
GET /api/token-pay-analyticsJSON totals, daily rollups, recent tx list
Solana explorerOn-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 payTo wallet; token payments never fall back to Concierge’s X402_SOL_PAY_TO.
  • Registry gate — settlement re-checks merchantId, mint, payTo, and resourceKinds against 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 / usdMax per 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 / DexterToken Pay
ModelFacilitator (gasless USDC)Self-settle (user pays SOL gas)
AssetUSDCProject native token
PriceFixed USDC list priceDexScreener + env fallback
Phase 1 routeAll paid APIsPOST /api/concierge (more routes later)

Public APIs

  • GET /api/token-pay — platform meta + merchant registry
  • GET /api/token-pay?merchant=soon — single merchant config
  • GET /api/x402-config — includes tokenPay (and legacy soonX402)
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:

  1. POST /api/concierge (or another route in your resourceKinds) → receive 402 + PAYMENT-REQUIRED
  2. Decode accepts — pick the entry where extra.settlement === "self" and extra.merchantId === "your-id"
  3. Sign an SPL transferChecked to payTo for amount atomic units of asset (mint)
  4. 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

FieldRequiredDescription
idyesStable slug (a-z0-9_-, 2–32 chars). Reserved: soon
symbolyesTicker shown in UI
mintyesSPL mint (base58)
payToyesYour Solana receive wallet — where token payments are credited
decimalsyesToken decimals (usually 6)
priceSourcenodexscreener (default) or env
fallbackUsdrecommendedUSD per 1 token when oracle fails
usdMin / usdMaxnoPrice sanity bounds
resourceKindsnoconcierge, external (your own API), etc.
allowedOriginsnoBrowser origins allowed for build/verify APIs
x402EnablednoSet false to disable without removing row

Resource kinds

Your token appears in 402 accepts only for routes listed in resourceKinds:

resourceKindAPI routeUSDC price
conciergePOST /api/concierge$0.10
newsPOST /api/news-open$0.10
signal-openPOST /api/lounge-signal-open$0.10
signal-publishPOST /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

  1. Add your row to TOKEN_PAY_MERCHANTS_JSON (local .env or Vercel env) and redeploy
  2. Ensure payTo wallet has an ATA for your mint (send a tiny amount once)
  3. Set fallbackUsd or list on DexScreener for live price
  4. Confirm GET /api/token-pay?merchant=YOUR_IDreadiness.acceptReady: true
  5. Confirm GET /api/x402-config shows your merchant live: true and conciergeAtomic
  6. Run a test paid call — inspect PAYMENT-REQUIRED for your merchantId accept
  7. 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 SOON>",
  "asset": "<SOON mint>",
  "payTo": "<merchant receive wallet>",
  "extra": {
    "settlement": "self",
    "merchantId": "soon",
    "name": "SOON",
    "decimals": 6
  }
}

Executive Lounge signs transferChecked in the browser; the Edge API simulates, broadcasts, and confirms the merchant token delta.

Environment (SOON merchant)

TOKEN_PAY_DEFAULT_MERCHANT=soon
SOON_TOKEN_MINT=           # set after pump.fun launch
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 + SOON)

Add partner merchants via TOKEN_PAY_MERCHANTS_JSON (see registration checklist). SOON 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

Concierge · Executive Lounge · Not financial advice