REST API · v1

Two endpoints. USDC in your wallet.

POST creates a hosted checkout. We GET your callback when paid. That's it.

Quickstart

The whole integration in three lines: create the link, redirect, handle the callback. Copy below, replace the wallet + key, and you're live.

STEP 1

POST /v1/wallet

We return a checkout_url.

STEP 2

Redirect

Send the customer to checkout_url.

STEP 3

Receive callback

We GET your URL with status=paid.

Copy & run

Quickstart · curl
curl -X POST https://paylio.org/api/v1/wallet \
  -H "Authorization: Bearer plio_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "address":  "0xYourPolygonWallet",
    "callback": "https://example.com/orders/123/paylio-callback",
    "amount":   "49.99",
    "currency": "USD"
  }'

Authentication

Every request needs an API key. Generate one in dashboard › API Keys. Send it in either header — never both:

HTTP headers
Authorization: Bearer plio_live_YOUR_KEY
# or
X-API-Key: plio_live_YOUR_KEY

Treat keys like passwords. We only store a SHA-256 hash. If a key leaks, revoke it and create a new one.

Create checkout link

Generates a hosted-checkout page and returns a ready-to-redirect URL plus an ipn_token for tracking.

POST/api/v1/wallet

Card-funded payments that settle as USDC on Polygon. For direct-crypto flows use the dashboard or the WooCommerce / WHMCS modules.

addressreq
string
Your Polygon USDC payout wallet (0x…). Funds land here.
callbackreq
url
Where PayLio GETs once the payment completes. See Callback.
amountreq
string | number
Order total. Decimal string preferred (e.g. "49.99").
currency
string
ISO code — USD, EUR, GBP, CAD. Default USD.
email
string
Customer email. Pre-fills the checkout, included in the callback.
note
string
Free-form note shown in your dashboard. Hidden from the customer.

Request

Request · curl
curl -X POST https://paylio.org/api/v1/wallet \
  -H "Authorization: Bearer plio_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "address":  "0xYourPolygonWallet",
    "callback": "https://example.com/orders/123/paylio-callback",
    "amount":   "49.99",
    "currency": "USD"
  }'

Response · 200 OK

Response · JSON
{
  "address_in":         "0xa1B2c3...derived",
  "polygon_address_in": "0x32e854bD1270670C832634CA87858fFd9F3e2c78",
  "ipn_token":          "f7e9d3a1-4b8e-4a2f-9c6e-1234567890ab",
  "callback_url":       "https://example.com/orders/123/paylio-callback",
  "payment_id":         "clx9k2m3a0001a8w0b3v4r5g6",
  "short_code":         "a8wB3v4R",
  "short_url":          "https://paylio.org/p/a8wB3v4R",
  "checkout_url":       "https://paylio.org/pay/clx9k2m3a0001a8w0b3v4r5g6",
  "payment_type":       "card",
  "status":             "unpaid"
}
Response field reference
checkout_url
url
Redirect the customer here.
ipn_token
string
Save on your order row. Use it to verify the callback.
payment_id
string
PayLio internal ID. Alternative input for status checks.
short_url
url
Branded short link to the checkout (good for SMS / email).
address_in
string
Deposit address embedded in checkout_url.
polygon_address_in
string
Decrypted Polygon address — for internal reconciliation.
payment_type
string
Always "card" for API-created payments.
status
string
Always "unpaid" at creation.

Check payment status

Server-to-server verification. Always call this before fulfilling an order — query strings on your callback can be spoofed.

GET/api/v1/payment-status
ipn_token
string
The token from /wallet. Either this or payment_id is required.
payment_id
string
PayLio payment ID.

Request

Request · cURL
curl "https://paylio.org/api/v1/payment-status?ipn_token=f7e9d3a1-..." \
  -H "Authorization: Bearer plio_live_YOUR_KEY"

Response · 200 OK

Response · JSON
{
  "status":           "paid",
  "value_coin":       "49.4",
  "txid_in":          "0xa22a82b4...",
  "txid_out":         "0x94c2c3e8...",
  "coin":             "polygon_usdc",
  "address_in":       "0x32e854bD1270670C832634CA87858fFd9F3e2c78",
  "payment_id":       "clx9k2m3a0001a8w0b3v4r5g6",
  "amount":           "49.99",
  "currency":         "USD",
  "forward_status":   "completed",
  "forwarded_amount": "49.4",
  "paid_at":          "2026-04-28T13:01:42.000Z",
  "created_at":       "2026-04-28T12:59:11.000Z"
}
Response field reference
status
string
unpaid · paid · canceled.
forward_status
string
pending · processing · completed · failed. Treat completed as final.
value_coin
string
Amount received in the settlement coin.
forwarded_amount
string
Final amount delivered to your wallet (after fees).
txid_in
string
Hash of the customer's deposit tx.
txid_out
string
Hash of the payout to your wallet.
coin
string
Settlement coin ticker (e.g. polygon_usdc).

Webhook callback

On payment completion, PayLio appends data to your callback URL and GETs it. Treat callbacks as untrusted hints — always re-verify with /payment-status.

Express · Node.js
// Express · Node.js
app.get("/orders/:id/paylio-callback", async (req, res) => {
  // 1. Re-verify — query strings can be spoofed.
  const verify = await fetch(
    `https://paylio.org/api/v1/payment-status?ipn_token=${req.query.ipn_token}`,
    { headers: { Authorization: `Bearer ${process.env.PAYLIO_API_KEY}` } },
  ).then((r) => r.json());

  if (verify.status !== "paid") return res.status(400).send("not paid");

  // 2. Mark the order paid (idempotent).
  await markOrderPaid(req.params.id, { txid: verify.txid_out });

  // 3. Reply 200 within 10 s.
  res.status(200).send("ok");
});
Three rules:
  1. Re-verify with /payment-status before fulfilling.
  2. Make your handler idempotent — we retry on non-2xx responses.
  3. Reply 200 within 10 s; do heavy work async.

Errors

All errors return JSON: { "error": "...", "code": "..." } (the code field appears when actionable).

HTTPCauseWhat to do
400Validation failed (missing field, bad wallet, low amount).Read error, fix input, retry.
401Missing, invalid, or revoked API key.Generate a new key.
404Payment not found, or owned by a different user.Verify ipn_token / payment_id.
429Too many requests in a short window.Honour Retry-After; back off with jitter.
500Server error (upstream / RPC unreachable).Retry with exponential backoff.

Ship your first payment today.

Generate a key, copy a sample, watch USDC land in your wallet. No KYC, no SDK.