Quickstart
Ship Splintr in 10 minutes
Copy every block in order. When you finish, you're accepting any token on any chain and settling in one.
Splintr launches on Robinhood Chain. The platform remains chain-agnostic, and the same integration supports every available payment and settlement network.
STEP 0· 30 sec
Prerequisites
- Node 18+ (or Bun / Deno / Cloudflare Workers)
- A Splintr account — sign in
- A settlement wallet address (EVM or Solana) you control
STEP 1· 2 min
Get your keys
- Open Dashboard → API Keys
- Copy
pk_test_…(publishable) andsk_test_…(secret) - Create a webhook endpoint and copy its signing secret
STEP 2· 1 min
Set environment variables
snippet.tsx
# .env (server)
SPLINTR_SECRET_KEY=sk_test_xxx
SPLINTR_WEBHOOK_SECRET=whsec_xxx
SPLINTR_API_URL=https://splintr.cash # optional
# .env (client)
VITE_SPLINTR_PUBLIC_KEY=pk_test_xxx| Name | Scope | Purpose |
|---|---|---|
| SPLINTR_SECRET_KEY | server | Auth for REST calls |
| SPLINTR_WEBHOOK_SECRET | server | Verify inbound webhooks |
| VITE_SPLINTR_PUBLIC_KEY | client | Mount <SplintrCheckout> |
Never expose SPLINTR_SECRET_KEY to the browser.
STEP 3· 30 sec
Install the SDKs
snippet.tsx
npm install @splintr-dev/server @splintr-dev/react
# or: bun add / pnpm add / yarn addSTEP 4· 2 min
Create a payment intent (server)
snippet.tsx
import { Splintr } from "@splintr-dev/server";
const splintr = new Splintr({ apiKey: process.env.SPLINTR_SECRET_KEY! });
export async function createCheckout(orderId: string, amountUsd: number) {
return splintr.paymentIntents.create(
{
amount: amountUsd,
currency: "USD",
settlement: {
chain: "robinhood", // launch example; use any supported settlement chain
token: "ETH",
address: process.env.MERCHANT_WALLET!,
},
// Vending-machine by default — any supported token on any supported
// chain is accepted and auto-swapped to your settlement token.
metadata: { orderId },
},
{ idempotencyKey: `order:${orderId}` } // safe to retry
);
}STEP 5· 2 min
Mount the checkout widget (client)
snippet.tsx
import {
SplintrProvider,
SplintrCheckout,
} from "@splintr-dev/react";
export default function CheckoutPage({ intentId }: { intentId: string }) {
return (
<SplintrProvider publicKey={import.meta.env.VITE_SPLINTR_PUBLIC_KEY}>
<SplintrCheckout
intentId={intentId}
onSettled={(i) => {
window.location.href = `/thanks/${i.metadata.orderId}`;
}}
onError={(err) => console.error(err)}
/>
</SplintrProvider>
);
}Handles Reown/WalletConnect, multi-token contributions, quotes, retries, and confirmations automatically.
STEP 6· 2 min
Verify webhooks (server)
snippet.tsx
import { verifyWebhook } from "@splintr-dev/server";
export async function POST(req: Request) {
const body = await req.text(); // RAW body, not JSON.stringify
const sig = req.headers.get("splintr-signature")!;
const event = await verifyWebhook({
payload: body,
signature: sig,
secret: process.env.SPLINTR_WEBHOOK_SECRET!,
});
switch (event.type) {
case "payment_intent.settled":
await fulfillOrder(event.data.metadata.orderId);
break;
case "payment_intent.expired":
case "payment_intent.failed":
await releaseInventory(event.data.metadata.orderId);
break;
}
return new Response("ok");
}Test with Developers → Webhooks → Send test event.
STEP 7· 30 sec
Go live
- Swap
pk_test_/sk_test_→pk_live_/sk_live_ - Update
SPLINTR_WEBHOOK_SECRETto the live endpoint's secret - Toggle Live mode in the dashboard header
Troubleshooting
| Symptom | Fix |
|---|---|
401 Unauthorized | Wrong key, or test-vs-live mismatch |
| Widget stuck loading | publicKey missing or mismatched env |
| Bad signature | Use raw body, verify secret matches endpoint |
429 | SDK auto-retries with Retry-After |