Accept cards. Settle in USDC.
One POST creates a hosted checkout page. One redirect sends the customer. One callback confirms the payment. Your Polygon wallet receives USDC within seconds — no SDK, no setup fee, no KYC.
2
endpoints
~5 min
integration
~3 s
settlement
Quickstart
One POST, one redirect, one webhook handler. That's the entire integration — you can be live before lunch.
- 01
Create wallet + link
POST /api/v1/wallet returns checkout_url and ipn_token.
- 02
Redirect customer
Send the buyer to checkout_url — PayLio hosts the checkout.
- 03
Receive callback
PayLio GETs your URL with status=paid and the on-chain txid.
# 1 · Create the checkout link
curl -X POST https://paylio.org/api/v1/wallet \
-H "Authorization: Bearer plio_live_…" \
-H "Content-Type: application/json" \
-d '{
"address": "0xYourPolygonWallet",
"callback": "https://example.com/order/123/callback",
"amount": "49.99",
"currency": "USD"
}'
# 2 · Redirect the customer
# → checkout_url
# 3 · Receive the callback when they pay
# GET https://example.com/order/123/callback?status=paid&txid_out=…Authentication
Every request to POST /api/v1/wallet and GET /api/v1/payment-status requires an API key.
Where to manage keys
Dashboard › API Keys
Full create / list / revoke page.
Dashboard › Settings
Same controls, embedded under the Developer section.
Send the key
Either header works — use one, not both:
Authorization: Bearer plio_live_YOUR_KEY
# or
X-API-Key: plio_live_YOUR_KEYCreate Wallet & Checkout Link
Generates a hosted-checkout page and returns a ready-to-redirect checkout_url plus an ipn_token for tracking. Accepts JSON POST or query-string GET.
/api/v1/walletRequest parameters
addressstringrequired0x…). Funds are forwarded here after every successful payment.callbackurlrequiredamountstring | numberrequired"105.78") to avoid float rounding.currencystringUSD, EUR, GBP, CAD. Default USD.emailstringnotestringSample request
curl -X POST https://paylio.org/api/v1/wallet \
-H "Authorization: Bearer plio_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"address": "0xF977814e90dA44bFA03b6295A0616a897441aceC",
"callback": "https://example.com/orders/12345/paylio-callback",
"amount": "105.78",
"currency": "USD",
"email": "[email protected]"
}'Response — 200 OK
{
"address_in": "0xa1B2c3...derived",
"polygon_address_in": "0x32e854bD1270670C832634CA87858fFd9F3e2c78",
"ipn_token": "f7e9d3a1-4b8e-4a2f-9c6e-1234567890ab",
"callback_url": "https://example.com/orders/12345/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 fields
address_instringcheckout_url. Normally you don't need to render it yourself.polygon_address_instringipn_tokenstringcheckout_urlurlshort_urlurlpayment_idstring/payment-status.payment_typestring"card" for API-created payments at this stage.statusstring"unpaid" at creation. Updates after payment.Check Payment Status
Server-to-server status check. Use it to verify a callback (always do this!) or to poll while the customer is still on the checkout page.
/api/v1/payment-statusRequest parameters
ipn_tokenstring/wallet. Either this or payment_id is required.payment_idstringSample request
curl "https://paylio.org/api/v1/payment-status?ipn_token=f7e9d3a1-..." \
-H "Authorization: Bearer plio_live_YOUR_KEY"Response — 200 OK
{
"status": "paid",
"value_coin": "105.6",
"txid_in": "0xa22a82b4aefbc55f6382e1b5c0b4f0e3c034a654df3bcac431f7fed1942e22bc",
"txid_out": "0x94c2c3e84c2021e6bf377aebf8abf03b49570611bb0c336e357d7f4516f56244",
"coin": "polygon_usdc",
"address_in": "0x32e854bD1270670C832634CA87858fFd9F3e2c78",
"payment_id": "clx9k2m3a0001a8w0b3v4r5g6",
"amount": "105.78",
"currency": "USD",
"forward_status": "completed",
"forwarded_amount": "105.6",
"paid_at": "2026-04-28T13:01:42.000Z",
"created_at": "2026-04-28T12:59:11.000Z"
}Response fields
statusstringunpaid · paid · canceled.value_coinstringtxid_instringtxid_outstringcoinstringpolygon_usdc).forward_statusstringpending · processing · completed · failed. Treat completed as final.forwarded_amountstringCallback
On payment completion PayLio appends data to your callback URL and GETs it. Treat callbacks as untrusted hints — always verify with /payment-status.
Callback parameters
statusstringpaid on success.value_coinstringcoinstringtxid_instringtxid_outstringaddress_instringpolygon_address_in from /wallet.ipn_tokenstring/wallet.payment_idstringSample callback URL
https://example.com/orders/12345/paylio-callback
?value_coin=105.6
&coin=polygon_usdc
&txid_in=0xa22a82b4aefbc55f6382e1b5c0b4f0e3c034a654df3bcac431f7fed1942e22bc
&txid_out=0x94c2c3e84c2021e6bf377aebf8abf03b49570611bb0c336e357d7f4516f56244
&address_in=0x32e854bD1270670C832634CA87858fFd9F3e2c78
&ipn_token=f7e9d3a1-...
&payment_id=clx9k2m3a0001a8w0b3v4r5g6
&status=paidSample handler
// Express · Node.js
app.get("/orders/:id/paylio-callback", async (req, res) => {
const { ipn_token } = req.query;
// 1. ALWAYS re-verify — query strings can be spoofed if your URL leaks.
const verify = await fetch(
`https://paylio.org/api/v1/payment-status?ipn_token=${ipn_token}`,
{ headers: { Authorization: `Bearer ${process.env.PAYLIO_API_KEY}` } },
).then((r) => r.json());
if (verify.status !== "paid") {
return res.status(400).send("Not yet paid");
}
// 2. Mark the order paid — make this idempotent (e.g. WHERE status != 'paid').
await markOrderPaid(req.params.id, {
txid: verify.txid_out,
amountUsdc: verify.value_coin,
});
// 3. Respond 200 within 10s. Do heavy work in a background job.
res.status(200).send("ok");
});- Always re-verify with
/payment-statusbefore fulfilling. - Make your handler idempotent — we retry on non-2xx responses.
- Respond
200within 10 s; do heavy work async.
Error Codes
Errors return JSON of the form { "error": "...", "code": "..." } (the code field is included when actionable).
| HTTP | Cause | What to do |
|---|---|---|
| 400 | Validation failed (missing field, invalid wallet, amount below minimum, …). | Read error — safe to retry after fixing input. |
| 401 | Missing, invalid, or revoked API key. | Generate a new key in dashboard › API Keys. |
| 404 | Payment not found, or owned by a different user. | Verify the ipn_token / payment_id. |
| 429 | Too many requests in a short window. | Honour the Retry-After header and back off with jitter. |
| 500 | Server error (upstream down, RPC unreachable, …). | Retry with exponential backoff. Contact support if it persists. |
Sample error response
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "address must be a valid Polygon (USDC) wallet starting with 0x",
"code": "invalid_wallet"
}Integrate in an afternoon.
Generate your first API key, copy a sample request, and start receiving USDC today. No KYC, no setup fee, no SDK to install.