← Home

AI Builder Setup

Paste this page's URL into Lovable, Replit, Bolt, Cursor or any AI coder. It will read the spec and wire up the entire crypto-payment flow on your site — no language lock-in.

Fastest way to integrate
  1. Open your AI builder (Lovable / Replit / Bolt / Cursor / v0).
  2. Paste the prompt below — it already contains this URL.
  3. When asked, add your 3 secrets in the project's secret manager.
  4. Paste the generated webhook URL into https://pay.itemodeverify.com/api → Webhooks.

1. Copy this prompt into your AI builder

One copy. The AI will read this entire page automatically and implement every step.

prompt
You are integrating the Crypto Invoice API into my website/app.

Read the full machine-readable spec at:
  https://pay.itemodeverify.com/websetup
  https://pay.itemodeverify.com/llms.txt
  https://pay.itemodeverify.com/api/openapi.json

Implement the FULL flow end-to-end. Do NOT skip steps.

REQUIREMENTS
1. Store 3 secrets in the project's secret manager (NOT in code):
   - CRYPTO_API_KEY
   - CRYPTO_API_SECRET
   - CRYPTO_WEBHOOK_SECRET
   Add a setup screen / .env example showing the names only.

2. Build a backend endpoint POST /api/checkout that:
   - Reads { amount, currency?, customer_email?, description? } from the request.
   - Optionally calls GET https://pay.itemodeverify.com/api/public/v1/wallets to pick an active wallet.
   - Calls POST https://pay.itemodeverify.com/api/public/v1/invoices with:
       Authorization: Bearer <CRYPTO_API_KEY>:<CRYPTO_API_SECRET>
       body: { amount, currency: currency || "USDT",
               description, customer_email,
               expires_in_minutes: 30,
               success_redirect_url: "<MY_SITE>/payment/success?inv={id}" }
   - Returns { pay_url, invoice_id } to the frontend.
   - Frontend then redirects the user to pay_url (hosted pay page with QR + address).

3. Build a webhook endpoint POST /api/crypto-webhook that:
   - Reads the RAW request body (do not re-serialize JSON).
   - Verifies header X-Webhook-Signature = HMAC_SHA256(CRYPTO_WEBHOOK_SECRET, raw_body) in constant time.
   - On event "invoice.paid": mark the order paid, credit the user's balance, send confirmation. Handler MUST be idempotent (same invoice id may arrive more than once).
   - On "invoice.expired" / "invoice.cancelled": update the order status.
   - Always reply HTTP 200 within 5s. Process heavy work async.

4. Add a 30-second polling fallback for any invoice still "pending":
   - Server-side cron OR client-side setInterval on the success page.
   - GET https://pay.itemodeverify.com/api/public/v1/invoices/<id> every 30s until status != "pending" or 30 minutes elapsed.
   - This guarantees balance updates even if the webhook is temporarily down.

5. Success page at /payment/success?inv=<id>:
   - Fetch the invoice, show status, amount, tx hash.
   - If still pending, show "Confirming…" and poll every 30s.
   - When paid, show success + redirect to dashboard.

6. Admin test panel at /admin/crypto-test with ONE button "Run integration test":
   - Verifies auth (lists wallets).
   - Creates a $1 test invoice.
   - Cancels it.
   - Shows pass/fail for each step. Use this to debug without real payments.

CONSTRAINTS
- Default invoice expiry: 30 minutes.
- Default polling interval: 30 seconds.
- Never expose API_SECRET or WEBHOOK_SECRET to the browser.
- Never trust webhook payloads without HMAC verification.
- Use the framework already in this project (do not introduce a new one).

When done, print: the 3 secret names to set, the webhook URL to paste into the Crypto Invoice dashboard at https://pay.itemodeverify.com/api → Webhooks, and a checklist of what to test manually.

2. The 3 secrets you need

Generate the API key/secret at https://pay.itemodeverify.com/api. The webhook secret is shown once when you add a webhook URL — copy it immediately.

env
# .env.example  — names only, fill values in your secret manager
CRYPTO_API_KEY=
CRYPTO_API_SECRET=
CRYPTO_WEBHOOK_SECRET=
CRYPTO_API_BASE=https://pay.itemodeverify.com

Store these in your platform's secret manager — Lovable Cloud secrets, Replit Secrets, Bolt env, Vercel/Netlify env vars. Never commit values.

3. REST API contract (language-agnostic)

spec
BASE URL
  https://pay.itemodeverify.com

AUTH (server-side only)
  Authorization: Bearer <API_KEY>:<API_SECRET>

ENDPOINTS
  GET    /api/public/v1/wallets                  -> list active wallets
  POST   /api/public/v1/invoices                 -> create invoice
  GET    /api/public/v1/invoices/{id}            -> read invoice (use for polling)
  POST   /api/public/v1/invoices/{id}/cancel     -> cancel a pending invoice

CREATE INVOICE BODY
  {
    "amount": 10,
    "currency": "USDT",
    "description": "Wallet top-up",
    "customer_email": "user@example.com",
    "expires_in_minutes": 30,
    "success_redirect_url": "https://yoursite.com/payment/success?inv={id}"
  }

CREATE INVOICE RESPONSE
  {
    "id": "inv_...",
    "status": "pending",
    "pay_url": "https://pay.itemodeverify.com/pay/inv_...",
    "wallet_id": "...",
    "amount": 10,
    "currency": "USDT",
    "expires_at": "2026-..."
  }

INVOICE STATUSES
  pending | paid | expired | cancelled

Full machine-readable schema: /api/openapi.json

4. The flow your AI must build

  1. User picks amount → frontend calls your /api/checkout.
  2. Server creates invoice (30-min expiry default) → returns pay_url.
  3. Frontend redirects user to the hosted pay page (QR + address).
  4. User pays from any wallet / Binance Pay.
  5. We notify your webhook + your success page polls every 30s.
  6. Order/balance is credited exactly once (idempotent).
  7. User is redirected to success_redirect_url.

5. Webhook spec (auto-retry, signed)

spec
WEBHOOK DELIVERY
  Method:  POST  (your URL)
  Header:  Content-Type: application/json
  Header:  X-Webhook-Signature: <hex>
  Body:    { "type": "invoice.paid" | "invoice.expired" | "invoice.cancelled" | "ping",
             "data": { ...invoice... } }

VERIFY (pseudo-code, any language)
  raw      = read raw request body bytes
  expected = HMAC_SHA256(WEBHOOK_SECRET, raw).hex()
  if not constant_time_equals(expected, header["X-Webhook-Signature"]):
      return 401

RETRIES
  We auto-retry failed deliveries with exponential backoff:
    1m, 5m, 30m, 2h, 6h, 24h  (6 attempts total)
  Your handler MUST be idempotent.

REGISTER YOUR URL
  https://pay.itemodeverify.com/api  →  Webhooks  →  Add URL
  The WEBHOOK_SECRET is shown ONCE on creation — store it immediately.

6. 30s polling fallback (instant + safe)

spec
POLLING FALLBACK (use alongside webhooks)
  Interval:   30 seconds (default)
  Stop when:  status != "pending"  OR  30 minutes elapsed
  Endpoint:   GET https://pay.itemodeverify.com/api/public/v1/invoices/{id}

WHERE TO POLL
  - /payment/success page (browser side) — instant UX update
  - Server cron job for invoices still "pending" past 1 minute — safety net

WHY BOTH WEBHOOK + POLLING
  Webhooks are instant but can fail (network, downtime, firewall).
  Polling guarantees the balance eventually updates even if every webhook fails.

7. Redirect URL

Pass success_redirect_url when creating the invoice. Use {id} — we substitute the invoice id automatically.

url
https://yoursite.com/payment/success?inv={id}

8. Admin test panel (no real payment needed)

The AI builder should add a single page at /admin/crypto-test with one "Run integration test" button that hits: list wallets → create $1 invoice → cancel it. Each step shows pass/fail.

checklist
MANUAL TEST CHECKLIST
  [ ] GET /wallets returns 200 with at least one active wallet
  [ ] POST /invoices returns pay_url, status="pending"
  [ ] Opening pay_url shows QR + crypto address
  [ ] Cancelling moves status to "cancelled"
  [ ] Webhook URL receives a "ping" test from the dashboard
  [ ] Signature verification rejects a tampered body (returns 401)
  [ ] After a real payment: webhook fires "invoice.paid" AND polling sees "paid"
  [ ] Balance/order is credited exactly ONCE (idempotency works)
  [ ] success_redirect_url sends the user back with {id} substituted

9. Error codes & fixes (read this when stuck)

Most integration failures are 401 Unauthorized — auth header missing, malformed, or called from the browser. Full list with causes and fixes below. Have your AI builder read this section before debugging.

errors
HTTP ERROR CODES — CAUSES & FIXES

================================================================
401  Unauthorized  ← MOST COMMON
================================================================
Meaning: API rejected your auth header.

Causes & fixes:
  1. Missing Authorization header
     → Add: Authorization: Bearer <API_KEY>:<API_SECRET>
  2. Wrong format (using only the key, or "Bearer KEY" without secret)
     → Must be EXACTLY:  Bearer <API_KEY>:<API_SECRET>   (colon-separated)
  3. API_KEY or API_SECRET is empty / undefined
     → Check your secret manager. Names: CRYPTO_API_KEY, CRYPTO_API_SECRET
     → Do NOT hardcode. Do NOT expose to the browser.
  4. Calling from the browser (frontend)
     → Auth must run on YOUR server. Frontend → your /api/checkout → our API.
  5. Old / revoked API key
     → Regenerate at https://pay.itemodeverify.com/api  →  API Keys
  6. Extra whitespace, quotes, or newline pasted into the env var
     → Re-paste the value cleanly. Trim it.
  7. Using the WEBHOOK_SECRET as API key
     → They are 3 DIFFERENT secrets. Don't mix.

Quick test (run from your server, never the browser):
  curl -H "Authorization: Bearer $CRYPTO_API_KEY:$CRYPTO_API_SECRET" \
       https://pay.itemodeverify.com/api/public/v1/wallets
  Expected: 200 + JSON list. If 401 → key/secret is wrong.

================================================================
400  Bad Request
================================================================
Cause:  Invalid body — missing "amount", bad currency, malformed JSON.
Fix:    Send Content-Type: application/json. Required: { amount: number }.
        amount must be > 0. currency defaults to "USDT" if omitted.

================================================================
403  Forbidden
================================================================
Cause:  Your API key is valid but doesn't own the wallet you referenced,
        OR the account is suspended / unverified.
Fix:    Use a wallet_id from GET /api/public/v1/wallets (same account).
        Check account status at https://pay.itemodeverify.com/api.

================================================================
404  Not Found
================================================================
Cause:  Wrong invoice id, or wrong URL path.
Fix:    Check the id you stored. Endpoint is /api/public/v1/invoices/{id}
        — note the "v1" and the "public" segments.

================================================================
409  Conflict
================================================================
Cause:  Trying to cancel an invoice that's already paid / expired / cancelled.
Fix:    Only "pending" invoices can be cancelled. Check status first.

================================================================
422  Unprocessable Entity
================================================================
Cause:  Amount below wallet minimum, or currency not supported by the wallet.
Fix:    Call GET /wallets/{id}/quote first — it returns min/max and rate.

================================================================
429  Too Many Requests
================================================================
Cause:  Rate limit hit (default 60 req/min per API key).
Fix:    Back off. Respect Retry-After header. For polling: 30s interval is fine.
        Don't poll faster than every 10s.

================================================================
500 / 502 / 503  Server Error
================================================================
Cause:  Temporary issue on our side.
Fix:    Retry with exponential backoff (1s, 2s, 4s, 8s, max 5 tries).
        If it persists > 5 min, check status page.

================================================================
WEBHOOK-SPECIFIC ERRORS (your endpoint receives, or we log)
================================================================

401 on webhook  →  Signature mismatch
  • You're hashing the parsed JSON instead of the RAW body. Use raw bytes.
  • Wrong WEBHOOK_SECRET. It was shown ONCE — regenerate the webhook URL
    in dashboard if you lost it.
  • Encoding mismatch — compare hex lowercase, constant-time.

"Failed to fetch" / CORS error in browser
  • You're calling our API directly from the frontend. Don't. Route through
    your own backend: browser → /api/checkout (your server) → our API.
  • Our API does NOT send CORS headers for /api/public/v1/* — by design.

Webhook never arrives
  • URL not publicly reachable (localhost won't work — use a tunnel, or deploy).
  • Your handler returns non-2xx → we retry 6× then give up.
  • URL not registered. Add it at https://pay.itemodeverify.com/api → Webhooks.

Balance not updated after payment
  • Webhook handler crashed before crediting → check your logs.
  • Not idempotent → duplicate event was ignored AND the first one failed.
  • Polling not enabled → enable the 30s fallback on /payment/success.

================================================================
DEBUG CHECKLIST  (run in this order when something breaks)
================================================================
  1. curl /wallets with your key → must return 200
  2. curl POST /invoices → must return pay_url
  3. Open pay_url in browser → must show QR
  4. Send "ping" from dashboard webhook page → your endpoint must return 200
  5. Verify signature on the ping → must pass
  6. Make a $1 test payment → webhook fires + GET /invoices/{id} shows "paid"

11. Security rules (non-negotiable)

  • Never expose API_SECRET or WEBHOOK_SECRET to the browser.
  • Always verify the HMAC signature on every webhook — use constant-time compare.
  • Hash the raw request body; never re-serialize parsed JSON.
  • Make the webhook handler idempotent — same invoice.id may arrive twice.
  • Trust only your server's GET /invoices/{id} result before crediting balance.