Developer docs
Accept crypto payments without ever touching customer funds. 0.5% flat. No KYC, no contracts, no monthly fees. From signup to first payment in about five minutes.
The API base URL is https://sovrn.ventures. Three chains live: Optimism, Bitcoin, Solana.
Overview
Sovrn is a non-custodial payment gateway. Every payment is split atomically on-chain: 99.5% goes to the merchant, 0.5% to Sovrn. Sovrn never holds merchant funds in a bank account, a smart contract Sovrn could drain, or anywhere else. There is no "withdrawal" step — funds settle directly to the merchant's wallet on the blockchain itself.
| Capability | Detail |
|---|---|
| Chains | Optimism, Bitcoin, Solana (Base/Polygon/Arbitrum on request) |
| Tokens | ETH, BTC, SOL, USDC, USDT |
| Fee | 0.5% flat, paid by the customer's wallet |
| Settlement | Atomic on EVM · ~30s sweep on BTC/SOL |
| Custody | Zero on EVM · ~30s on BTC/SOL (architectural minimum) |
| KYC | None for merchants. Customer's wallet handles everything. |
| Monthly fees | None. |
Quickstart
This is the full path from "never used Sovrn" to "your customers can pay you in crypto":
1 · Get an API key
Sign up at sovrn.ventures/dashboard.html. You get an API key (sk_live_…) the moment you create the account. Save it somewhere safe — it's the only thing that authorizes payment creation on your account.
2 · Set your payout wallet(s)
In the dashboard, paste the wallet address(es) where you want to receive funds. One address per chain:
- EVM (Optimism) — paste any Ethereum address you control, then click Deploy splitter. Sovrn pays the ~$0.005 deployment gas. From then on, customer payments arrive directly at your wallet, minus the 0.5% fee, all atomically on-chain.
- Bitcoin — paste a bech32 address (
bc1q…). Sovrn allocates a fresh receive address per payment and sweeps to yours. - Solana — paste any Solana address. Sovrn generates an ephemeral keypair per payment and sweeps to yours.
3 · Create a payment from your backend
curl -X POST https://sovrn.ventures/api/v1/payments \
-H "X-API-Key: sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 184.20,
"currency": "USD",
"chain": "bitcoin",
"token": "BTC",
"order_id": "1847"
}'
The response gives you a checkout_url. Redirect your customer there.
{
"payment_id": "pay_7c5955ca09ac85bdde754601",
"checkout_url": "https://sovrn.ventures/checkout.html?id=pay_7c5955ca…",
"status": "pending",
"chain": "bitcoin",
"token": "BTC",
"crypto_amount": 0.00194,
"wallet_address": "bc1q…",
"expires_at": 1780050838
}
4 · Receive a webhook when it settles
Set your webhook URL in the dashboard. When the payment settles on-chain, Sovrn POSTs a signed event to your URL:
{
"event": "payment.paid",
"payment_id": "pay_7c5955ca…",
"order_id": "1847",
"amount_fiat": 184.20,
"tx_hash": "0x4f1d…"
}
Verify the signature in the X-Sovrn-Signature header, mark the order paid, ship the product. Webhook details below.
That's the entire integration. There's no SDK to install, no library to compile, no "merchant agreement" to sign. You're a developer, you understand HTTP — it's just one POST.
Authentication
Every request to /api/v1/* must include your API key in the X-API-Key header:
X-API-Key: sk_live_24dc58f5ce24d7f99b36e5919c1aceb5215f389dae150052
You can also use the standard Authorization: Bearer … header. API keys never expire and never rotate automatically — if you suspect yours is compromised, regenerate it in the dashboard.
Your API key is a bearer credential. Anyone who has it can create payments on your behalf (which go directly to your wallet, so the financial blast radius is limited — but spam payments could fill your order pipeline). Keep it server-side. Never embed it in client-side JS or mobile apps.
Hosted checkout
The simplest integration. Your backend creates a payment, you redirect the customer to the returned checkout_url. Sovrn hosts a full checkout page with QR code, live polling, network telemetry, and a confirmation screen.
The hosted page handles:
- QR code generation (client-side, scannable by any wallet)
- Address copy with one tap
- Live block-height + mempool monitoring
- Countdown timer + auto-expiry
- Mobile-responsive layout
- Chain-specific instructions (BTC ~10 min, SOL sub-second, etc.)
If you want to embed instead of redirect, see the JS drop-in below.
JS drop-in
For a Stripe-Checkout-style modal overlay on your existing checkout page, include sovrn.js and call Sovrn.checkout():
<script src="https://sovrn.ventures/sovrn.js"></script>
<button onclick="payNow()">Pay with crypto</button>
<script>
async function payNow() {
// 1. Ask your backend to create the payment.
const r = await fetch('/api/create-sovrn-payment', { method: 'POST' });
const { checkout_url } = await r.json();
// 2. Open it as a modal.
Sovrn.checkout({
checkoutUrl: checkout_url,
onSuccess: function (payment) {
window.location.href = '/order/success?id=' + payment.payment_id;
},
onClose: function () {
console.log('Customer dismissed checkout');
},
});
}
</script>
For the simplest possible integration, you can also use data attributes — no JavaScript required beyond the <script> tag:
<button
data-sovrn
data-checkout-url="https://sovrn.ventures/checkout.html?id=pay_xxx"
data-success-url="/order/success">
Pay with crypto
</button>
The modal handles esc-to-close, click-outside-to-close, polls the payment status every 4s, and fires onSuccess when settled. On phones it falls back to a full-page redirect.
Webhooks
Set your webhook URL in the dashboard. Sovrn fires HTTPS POSTs to it for these events:
| Event | When |
|---|---|
payment.paid | Customer payment detected and (for BTC/SOL) successfully swept to merchant |
payment.expired | Invoice expiry passed before payment arrived |
payment.cancelled | Merchant explicitly cancelled the payment via API |
Signature verification (HMAC-SHA256)
Every webhook includes X-Sovrn-Signature. Verify it with your webhook secret (also in the dashboard) before trusting the body:
import hmac, hashlib
def verify_sovrn_webhook(raw_body: bytes, sig_header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig_header)
If the signature doesn't match, drop the request silently. Don't reply with an error code — that gives an attacker information.
Retries
Sovrn retries failed webhook deliveries with exponential backoff up to 24 hours. Reply with any 2xx to acknowledge. A 4xx or 5xx triggers a retry. If you need to retry processing on your end without re-triggering, store the payment_id and skip duplicates.
Create payment
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
amount | number | yes | Amount in fiat units (e.g. 184.20) |
currency | string | no | Fiat code. Defaults to USD. Supported: USD, EUR, GBP, AUD, CAD |
chain | string | yes | optimism, bitcoin, or solana |
token | string | no | Defaults to the chain's native token. Override to accept stablecoins. |
order_id | string | no | Your internal order identifier. Returned in the webhook. |
description | string | no | Shown on the checkout page. |
customer_email | string | no | Optional. If provided, the customer gets a receipt. |
metadata | object | no | Arbitrary JSON. Returned in webhooks and the get-payment response. |
Response · 201
{
"payment_id": "pay_7c5955ca09ac85bdde754601",
"status": "pending",
"amount_fiat": 184.20,
"fiat_currency": "USD",
"chain": "bitcoin",
"token": "BTC",
"crypto_amount": 0.00194,
"exchange_rate": 94948.27,
"wallet_address": "bc1q…",
"checkout_url": "https://sovrn.ventures/checkout.html?id=pay_7c5955ca…",
"expires_at": 1780050838,
"created_at": 1780049038
}
Get payment
Returns the current state of a payment. Useful for polling if you can't run a webhook endpoint.
List payments
Returns payments filtered by status, paginated. Maximum limit is 200.
Supported chains
| Chain | Tokens | Settle time | Customer's typical fee |
|---|---|---|---|
| Optimism | ETH, USDC, USDT | ~2 seconds | ~$0.01 in gas |
| Bitcoin | BTC | ~10 minutes | ~$1 in network fee |
| Solana | SOL, USDC, USDT | ~400 ms | ~$0.0005 in tx fees |
Base, Polygon, and Arbitrum are ready in the codebase and can be enabled per-merchant on request. Email hello@sovrn.ventures.
How the split works
EVM chains
On Optimism (and Base/Polygon/Arbitrum), every merchant gets their own splitter contract — a deterministic clone of our factory at 0xcFdaaC…4FBF. Customer sends ETH directly to your splitter. Your splitter's receive() function fires automatically, forwarding 99.5% to your wallet and 0.5% to Sovrn's fee wallet, in the same transaction. No intermediate custody. No upgrade path. No admin keys. The contract is immutable once deployed.
Bitcoin
Bitcoin has no smart contracts, so Sovrn allocates a unique receive address per payment from a BIP-84 master key. Customer pays that address. The moment our watcher detects the payment in the mempool, it broadcasts a single sweep transaction with two outputs — 99.5% to you, 0.5% to Sovrn — within ~30 seconds. The intermediate custody window is the inherent BTC trade-off.
Solana
Sovrn generates a fresh ephemeral keypair per payment. Customer pays the keypair's public key. On detection, Sovrn signs a forwarding transaction (paying tx fees from Sovrn's fee wallet) with two transfers — your share and ours — in a single signed instruction set. Finality in ~400 ms.
Security model
Sovrn's job is to not hold your funds. The whole architecture is designed so that even a complete compromise of Sovrn's servers cannot drain merchant balances:
- EVM: Funds go from customer → your splitter contract → your wallet, in one transaction. Sovrn's servers never touch this. The splitter contract is open-source, immutable, and audited.
- BTC/SOL: Sovrn holds a master key that controls the ~30-second receive window. If our server is compromised, an attacker could redirect payments in flight — but not your existing balance and not future payments after you set a new payout address. Mitigation: we rotate master keys quarterly.
- No merchant balances: Sovrn maintains no merchant balance ledger. There is no admin button anywhere to "withdraw merchant funds" because no such funds exist in our system.
The full splitter contract is <200 lines of Solidity. If you're integrating Sovrn for high-value flows, read it first — it's the only thing standing between you and your customers' money. View source on Etherscan →