Checkout Sessions API, Manually Adding Wallets & More
Developer API: Checkout Sessions & Orders
The Checkout Sessions API and Orders API are now available to merchants in closed-beta.
Checkout Sessions let you create a hosted payment page with a single API call. Pass your order details, get back a URL, and redirect your customer. Decal handles the checkout UI, payment collection, and order tracking.
curl -X POST https://api.usedecal.com/v0/checkout/sessions \
-H "Authorization: Bearer sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"items": [{ "name": "Cold Brew", "quantity": 1, "unitPrice": 550 }],
"successUrl": "https://yoursite.com/confirmed?session={SESSION_ID}"
}'The response includes a url to redirect your customer to and the full order object so you have the
order ID handy for confirmation.
Orders can also be managed independently — create, retrieve, update, or cancel orders directly without going through a checkout session. Useful for POS integrations or anywhere you're managing order state server-side.
Both APIs:
- Support taxes and discounts (fixed and percentage)
- Accept a
customerobject that will find-or-create a customer record, withexternalIdsupport for mapping to your own customer IDs - Use test/live mode automatically based on your API key (
sk_test_vssk_live_)
Webhooks
Checkout sessions now fire a checkout.session.completed webhook to your callbackUrl after a
successful payment — before the customer is redirected to your successUrl. This means your server
knows about the payment before the customer lands on your confirmation page, eliminating the need to
poll for payment status.
Both successUrl and callbackUrl support a {SESSION_ID} placeholder template that gets replaced
with the actual session ID at creation time, so you don't need to store the mapping yourself:
{
"callbackUrl": "https://yoursite.com/webhooks/decal?session={SESSION_ID}"
}Manual Settlement Wallets
You can now add a settlement wallet by pasting a Solana address directly, without connecting a browser extension. This enables wallet types that can't go through the standard signature flow:
- Multisig wallets (Squads) — add a program-owned address directly
- Cold storage (Ledger, Keystone, etc) — no need to plug in
- Any externally managed address
Manually added wallets are tagged with a Manual badge in your wallet list, and adding one requires a confirmation checkbox since funds sent to a wrong address can't be recovered.

Payment Destination Override
When creating an order or checkout session via the API, you can now specify exactly which settlement wallet receives the funds — overriding the default wallet resolution for that transaction:
{
"items": [{ "name": "Catering Package", "quantity": 1, "unitPrice": 25000 }],
"paymentDestination": "sw_live_abc1234567890"
}Accepts either a typed wallet ID (sw_live_...) or a raw Solana address from your verified wallets.
Stored Value Improvements
A few quality of life improvements for Stored Value programs:
- No settlement wallet required to activate — the activation checklist is now two steps (balance name + launch). The settlement wallet step was a leftover requirement that didn't actually affect how stored value payments route, so it's gone.
- Default bonus values — new programs now come pre-filled with bonus configurations ($5 bonus on $25+ first load, $5 bonus on $50+ recurring loads) so you're not starting from a blank slate.
- Better bonus display — when a top-up added to a checkout qualifies for a bonus, the bonus details appear inline before the customer pays. The balance page now shows the correct bonus type automatically (signup vs topup) without being anchored to a preset amount.
- Smarter low-balance messaging — first-time customers no longer see a misleading "Low balance" warning. Instead they see a first-topup incentive. Returning customers with a low balance continue to see the existing reload nudge.
Embedded Authentication
Customer authentication now uses inline embedded flows instead of pop-up windows. New users enter their OTP code directly in the app, and returning users authenticate via an embedded iframe. Popups are only used as a fallback for passkey (WebAuthn) auth, with automatic popup blocker detection and Safari-specific recovery instructions.
Minor
- Stablecoin payment setup streamlined — enabling a stablecoin payment method is now a single click. The prior flow opened a wallet selection dialog linked to the payment method; that's gone. Payment routing now resolves via orchestration wallets at payment time.
- Better card payment errors — user-actionable Coinflow errors (invalid zip, declined card) are now shown directly to customers instead of a generic failure message.