Accept Solana payments
on any website.
Drop one script tag and call Settlix.open(). No SDK, no wallet libraries, no framework required.
Quick Start
Two steps to a working checkout button.
Load the checkout script once — anywhere in your HTML
<script src="https://settlix.xyz/checkout.js"></script>Trigger the checkout from any button
<button onclick="Settlix.open({ linkId: 'YOUR_LINK_ID' })">
Pay with Settlix
</button>Replace YOUR_LINK_ID with the ID from your Settlix dashboard.
Live Demo
Enter your payment link ID and fire the checkout right here.
Sign in and create a payment link to get your Payment Link ID. Go to Dashboard
Full API Reference
All options accepted by Settlix.open().
Settlix.open({
linkId: 'YOUR_LINK_ID',
// Optional — pass any JSON you want echoed back
metadata: {
orderId: 'order_789',
userId: 'user_456',
},
// Fires when payment is confirmed on-chain
onSuccess: function(txSignature, metadata) {
console.log('paid:', txSignature)
console.log('order:', metadata.orderId)
},
// Fires on close, cancel, or failure
onClose: function(metadata) {
console.log('abandoned order:', metadata?.orderId)
},
})
// Close programmatically (e.g. from your own UI)
Settlix.close()| Option | Type | Description |
|---|---|---|
| linkId | string | Required. Your payment link ID from the dashboard. |
| metadata | object | Optional. Any JSON — echoed back in onSuccess and onClose. |
| onSuccess | (txSig, metadata) => void | Called when payment is confirmed on-chain. |
| onClose | (metadata) => void | Called on close, cancel, or failure. |
Order Tracking
How to map a payment back to a specific order and user.
txSignature and userWallet.// Without metadata — you know SOMEONE paid, not WHO or WHAT ORDER
Settlix.open({ linkId: 'abc' })
// With metadata — you get back exactly what you put in
Settlix.open({
linkId: 'abc',
metadata: { orderId: 'order_789', userId: 'user_456', plan: 'pro' },
onSuccess: function(txSignature, metadata) {
// metadata.orderId → 'order_789' ✓
// metadata.userId → 'user_456' ✓
fulfillOrder(metadata.orderId, txSignature)
},
})metadata is stored alongside the transaction in Settlix and included in every webhook delivery — so your backend can correlate without relying solely on the client-side callback.
Webhook Payload
Settlix sends a signed POST to your endpoint on every confirmed payment.
// Payment link payment
{
"linkId": "clxyz1234abcd",
"txSignature": "5Yf3...k9mZ",
"userWallet": "9xKp...wQ2r",
"inputToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"inputAmount": "25000000",
"outputAmount": "25000000",
"timestamp": "2025-04-26T10:30:00.000Z",
"metadata": { "orderId": "order_789" }
}
// Invoice payment
{
"invoiceId": "clxyz5678efgh",
"txSignature": "5Yf3...k9mZ",
"userWallet": "9xKp...wQ2r",
"inputToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"inputAmount": "500000000",
"outputAmount": "500000000",
"timestamp": "2025-04-26T10:30:00.000Z"
}
// Subscription payment (first payment or renewal)
{
"subscriberId": "clxyz9012ijkl",
"planId": "clxyz3456mnop",
"txSignature": "5Yf3...k9mZ",
"userWallet": "9xKp...wQ2r",
"inputToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"inputAmount": "10000000",
"outputAmount": "10000000",
"timestamp": "2025-04-26T10:30:00.000Z"
}
// All events include the signature header:
// X-Settlix-Signature: sha256=<hmac-hex>Verifying the signature
Compute HMAC-SHA256(body, webhookSecret) and compare it to the hex value in X-Settlix-Signature. Reject the request if they don't match.
Content Security Policy
Add these directives if your site sets a CSP header.
Content-Security-Policy:
script-src https://settlix.xyz;
frame-src https://settlix.xyz;
connect-src https://settlix.xyz;frame-src allows the checkout iframe. connect-src allows API calls made from inside the iframe.
TypeScript
Full type declaration — paste this into any global.d.ts if you skipped the Quick Start.
/// <reference types="https://settlix.xyz/checkout.d.ts" />
// or paste this into a global.d.ts file:
interface SettlixCheckout {
open(opts: {
linkId: string
metadata?: Record<string, unknown>
onSuccess?: (txSignature: string, metadata: Record<string, unknown> | null) => void
onClose?: (metadata: Record<string, unknown> | null) => void
}): void
close(): void
}
declare global {
interface Window { Settlix: SettlixCheckout }
}Async Script Loading
Queue calls made before the script finishes loading.
<!-- Optional: queue calls made before the script loads -->
<script>
window.Settlix = { _q: [], open: function(o){ this._q.push(o) } }
</script>
<script src="https://settlix.xyz/checkout.js" async></script>If you load the script with async, calls to Settlix.open() before the script executes will be queued and replayed automatically.
Settlix API
for your backend.
Create links, configure webhooks, and manage your account — all from your own server using a simple REST API and a Bearer token.
Authentication
All protected endpoints accept a Bearer token in the Authorization header.
Authorization: Bearer sk_live_<your-key>API keys are scoped to your merchant wallet — they can do everything your dashboard session can.
Quick Start
Create a payment link and get a URL in one request.
# Create a link from your server
curl -X POST https://settlix.xyz/api/links \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": "25", "title": "Order #1234" }'
# Then open it client-side
Settlix.open({ linkId: "clxyz1234abcd", metadata: { orderId: "1234" } })API Keys
Create and revoke API keys programmatically. Up to 10 keys per wallet.
/api/keys# List your API keys
curl https://settlix.xyz/api/keys \
-H "Authorization: Bearer sk_live_..."/api/keys# Create a new API key (name it for your app)
curl -X POST https://settlix.xyz/api/keys \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "name": "My Shopify store" }'
# Response — save this key, it is shown ONCE
{
"id": "clxyz...",
"name": "My Shopify store",
"key": "sk_live_a1b2c3...",
"createdAt": "2025-04-26T10:00:00.000Z"
}The raw key is returned once and never stored. Save it immediately.
/api/keys/:id# Revoke a key by ID — returns 204 No Content
curl -X DELETE https://settlix.xyz/api/keys/clxyz... \
-H "Authorization: Bearer sk_live_..."Create a Payment Link
Returns the link ID and its public pay URL.
/api/links# Create a payment link
curl -X POST https://settlix.xyz/api/links \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"amount": "25.00",
"title": "Order #1234",
"description": "2x Widget Pro"
}'
# Response — 201 Created
{
"id": "clxyz1234abcd",
"payPath": "/pay/clxyz1234abcd"
}| Field | Type | Description |
|---|---|---|
| token | string | Required. Settlement token mint address (USDC). |
| amount | string | Required. Human-decimal amount, e.g. "25.00". |
| title | string? | Optional. Shown to the buyer at checkout. |
| description | string? | Optional. Up to 300 characters. |
| expiresAt | ISO 8601? | Optional. Link stops accepting payments after this time. |
| maxUses | number? | Optional. Maximum number of successful payments. |
| recipients | array? | Optional. Revenue split — basis points must sum to 10000. |
List Payment Links
Returns all links with stats and recent executions.
/api/links# List all your payment links with stats
curl https://settlix.xyz/api/links \
-H "Authorization: Bearer sk_live_..."Each link object includes stats.paidCount, stats.totalVolume, and up to 5 recentExecutions.
Manage a Link
Get details or toggle a link active/inactive.
/api/links/:id# Get a single payment link (public — no auth needed)
curl https://settlix.xyz/api/links/clxyz1234abcdPublic endpoint — no auth required. Used by buyers before paying.
/api/links/:id# Deactivate a link
curl -X PATCH https://settlix.xyz/api/links/clxyz1234abcd \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "active": false }'Invoices
Create and send invoices — clients pay via a dedicated invoice page.
# List all invoices
curl https://settlix.xyz/api/invoices \
-H "Authorization: Bearer sk_live_..."
# Create an invoice
curl -X POST https://settlix.xyz/api/invoices \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"clientName": "Acme Corp",
"clientEmail": "billing@acme.com",
"token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"dueDate": "2025-06-01T00:00:00.000Z",
"memo": "Q2 retainer",
"lineItems": [
{ "description": "Design work", "quantity": "1", "unitPrice": "500.00" },
{ "description": "Dev hours", "quantity": "8", "unitPrice": "150.00" }
]
}'
# Response — 201 Created
{
"id": "clxyz...",
"linkId": "clxyz...",
"payPath": "/invoice/clxyz..."
}| Field | Type | Description |
|---|---|---|
| clientName | string? | Optional. Shown in the invoice and email. |
| clientEmail | string? | Optional. If set, invoice email is sent on creation and a receipt on payment. |
| token | string | Required. Settlement token mint address (USDC). |
| dueDate | ISO 8601? | Optional. After this date the invoice is marked overdue. |
| memo | string? | Optional. Internal note shown on the invoice. |
| lineItems | array | Required. At least one item with description, quantity, and unitPrice. |
/api/invoices/:id# Get a single invoice (public — no auth needed)
curl https://settlix.xyz/api/invoices/clxyz...Public endpoint — no auth required. Used by the client to view and pay the invoice.
/api/invoices/:id# Archive an invoice — returns 204 No Content
curl -X DELETE https://settlix.xyz/api/invoices/clxyz... \
-H "Authorization: Bearer sk_live_..."/api/invoices/:id/send# Send (or resend) the invoice email to the client
# Returns 409 INVOICE_ALREADY_PAID if the invoice has been paid
curl -X POST https://settlix.xyz/api/invoices/clxyz.../send \
-H "Authorization: Bearer sk_live_..."409 INVOICE_ALREADY_PAID.Subscriptions
Create recurring payment plans and manage subscribers.
Subscribers authorize an SPL token delegation from the /subscribe/:planId page. The relayer then charges them automatically at each renewal. Merchants get a webhook on every successful charge.
/api/subscription-plans# List your subscription plans
curl https://settlix.xyz/api/subscription-plans \
-H "Authorization: Bearer sk_live_..."/api/subscription-plans# Create a subscription plan
curl -X POST https://settlix.xyz/api/subscription-plans \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"amount": "10.00",
"interval": "weekly",
"title": "Pro Plan",
"description": "Weekly access to all features"
}'
# Response — 201 Created
{ "id": "clxyz1234abcd" }
# Share this URL with subscribers:
# https://settlix.xyz/subscribe/clxyz1234abcd| Field | Type | Description |
|---|---|---|
| token | string | Required. Settlement token mint address (USDC). |
| amount | string | Required. Amount charged per interval, e.g. "10.00". |
| interval | "daily" | "weekly" | Required. Billing frequency. |
| title | string? | Optional. Shown to subscribers at sign-up. |
| description | string? | Optional. Up to 300 characters. |
/api/subscription-plans/:id# Pause a plan (stops new subscriptions, existing ones continue)
curl -X PATCH https://settlix.xyz/api/subscription-plans/clxyz1234abcd \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "active": false }'
# Reactivate
curl -X PATCH https://settlix.xyz/api/subscription-plans/clxyz1234abcd \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{ "active": true }'Pausing a plan prevents new sign-ups but does not cancel existing subscribers.
/api/subscription-plans/:id# Archive a plan — returns 204 No Content
curl -X DELETE https://settlix.xyz/api/subscription-plans/clxyz1234abcd \
-H "Authorization: Bearer sk_live_..."/api/subscriptions# List all subscribers across your plans
curl https://settlix.xyz/api/subscriptions \
-H "Authorization: Bearer sk_live_..."/api/subscriptions/:id/cancel# Cancel a subscriber (merchant-initiated)
curl -X POST https://settlix.xyz/api/subscriptions/clxyz9012ijkl/cancel \
-H "Authorization: Bearer sk_live_..."Subscribers can also self-cancel from their /manage/:subscriberId page by connecting the wallet they subscribed with.
Renewal schedule
Renewals run at midnight UTC. The relayer attempts each charge up to 3 times (10 PM, 11 PM, 12 AM). If all attempts fail the subscriber is cancelled and notified by email.
Webhooks
Configure a webhook — Settlix POSTs to your URL on every confirmed payment.
/api/webhook# Configure your webhook endpoint
curl -X PATCH https://settlix.xyz/api/webhook \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://yoursite.com/api/settlix-webhook",
"webhookSecret": "your-32-char-secret"
}'Verifying the signature
// Node.js — verify incoming webhook
const crypto = require('crypto')
function verifySettlixWebhook(rawBody, signature, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected),
)
}Always verify the signature
Compare the header value to sha256=HMAC(rawBody, webhookSecret) using a timing-safe comparison. Reject requests that don't match.
Errors
All errors follow a consistent JSON shape with a machine-readable code.
// Every error response follows this shape
{
"error": "Human-readable message",
"code": "MACHINE_READABLE_CODE",
"issues": [...] // only on validation errors (400)
}
// HTTP status codes used by this API
// 201 — resource created (POST)
// 204 — deleted (DELETE)
// 400 — bad request / validation failed
// 401 — missing or invalid API key
// 403 — forbidden (you don't own this resource)
// 404 — resource not found
// 409 — conflict (e.g. invoice already paid)
// 410 — gone (link expired or sold out)
// 502 — upstream failure (e.g. email delivery)
// 500 — server error