One open protocol, two ways to integrate: connect your wallet or platform to let your users pay any GoBTC Pay merchant, or accept Bitcoin payments on your own website. Instant confirmation, on-chain settlement, and a built-in 50/50 revenue share for integrating partners.
Connect to the protocol via the Wallet / Institution API and earn a revenue share on every attributed payment.
Read the guide →Drop in the Web SDK — a button or widget plus webhooks — and start accepting BTC at checkout.
Read the guide →This is the initial published reference for the June 19 release. Endpoints, key formats and the OpenAPI file are being finalized — confirm exact values with your integration manager before going to production.
GoBTC Pay is a Bitcoin payment protocol with instant confirmation and on-chain settlement, built on the Bitcoin Instant Protocol. There are two integration surfaces:
https://api.gobtcpay.com/v1https://sandbox.api.gobtcpay.com/v1Every request is authenticated with API keys. You get two types of key per environment:
pk_…) — safe to expose in the browser; used by the Web SDK to start a payment.sk_…) — server-side only; sent as a Bearer token. Never expose it client-side.Sandbox keys are available immediately and require no approval — build and test the full flow against test data. Production keys are issued after KYB approval (merchant) or institution review (wallet partner).
Authorization: Bearer sk_live_... For wallets and platforms connecting their users to the protocol. Onboarding is reviewed by our BD team; once approved you receive an institution ID, sandbox + production keys, and a webhook signing secret. Every payment you create carries an attribution_id so the revenue share is credited to you.
/paymentsCreate a payment. Returns a QR string and a mobile deep link to render in your own UX.
| Field | Type | Description |
|---|---|---|
amount | number | Amount in the fiat currency below. |
currency | string | ISO 4217 code, e.g. USD. |
merchant_id | string | The merchant receiving the payment. |
attribution_id | string | Your institution ID — drives the 50/50 revenue share. |
reference | string | Your own order/reference identifier. Optional. |
metadata | object | Arbitrary key/value pairs echoed back on events. Optional. |
Performance target: ≤ 500 ms (P95). Send an Idempotency-Key header for safe retries.
curl https://api.gobtcpay.com/v1/payments \
-H "Authorization: Bearer sk_live_..." \
-H "Idempotency-Key: 5f3c1b2a-7d9e-4a10-9c2f-..." \
-H "Content-Type: application/json" \
-d '{
"amount": 49.99,
"currency": "USD",
"merchant_id": "mrc_8Kd2...",
"attribution_id": "inst_3Ad9...",
"reference": "order-1024",
"metadata": { "cart_id": "c_88f" }
}'{
"id": "pay_1Hk9x...",
"status": "pending",
"amount": 49.99,
"currency": "USD",
"amount_btc": "0.00052431",
"merchant_id": "mrc_8Kd2...",
"attribution_id": "inst_3Ad9...",
"reference": "order-1024",
"qr": "bitcoin:bc1q...?amount=0.00052431",
"deep_link": "gobtcpay://pay/pay_1Hk9x...",
"expires_at": "2026-06-19T03:15:00Z",
"created_at": "2026-06-19T03:00:00Z"
}/payments/{id}Retrieve a payment's status. Statuses: pending, confirmed, failed, expired.
Performance target: ≤ 200 ms (P95).
{
"id": "pay_1Hk9x...",
"status": "confirmed",
"amount": 49.99,
"currency": "USD",
"amount_btc": "0.00052431",
"txid": "9b1c...e4",
"confirmed_at": "2026-06-19T03:01:12Z"
}/institutions/{id}/revenue-shareAccrued revenue share in BTC and the payout schedule. The merchant fee is split 50% to GoMining network miners and 50% to the partner whose client made the transaction. Accrued balance above the minimum threshold settles on a weekly payout.
{
"institution_id": "inst_3Ad9...",
"currency": "BTC",
"accrued": "0.01837402",
"paid_to_date": "0.42910778",
"split": { "miners": 0.5, "partner": 0.5 },
"next_payout_at": "2026-06-23T00:00:00Z",
"minimum_payout": "0.00100000"
}Accept BTC payments on a merchant website. Install via npm or a script tag:
npm install @gobtcpay/sdk<script src="https://js.gobtcpay.com/v1/gobtc.js"></script>Create a client with your publishable key:
import { GoBTCPay } from "@gobtcpay/sdk";
const gobtc = GoBTCPay({
publishableKey: "pk_live_...",
environment: "production", // or "sandbox"
}); Call createPayment with the amount and your reference. The SDK opens a modal (or redirect) showing a QR on desktop and a deep link on mobile, then emits success, failure or expiry events.
const payment = await gobtc.createPayment({
amount: 49.99,
currency: "USD",
reference: "order-1024",
metadata: { cart_id: "c_88f" },
});
payment.on("success", (p) => console.log("Paid:", p.id));
payment.on("failure", (err) => console.error(err));
payment.on("expiry", () => console.warn("Payment expired"));The publishable key starts the payment client-side; always confirm the final state server-side via webhooks before fulfilling an order.
We deliver events to your endpoint for every payment (Web SDK) or every attributed payment (institution-level). Events are signed with HMAC SHA-256, de-duplicated by event ID, and delivered within 5 s (P95).
POST https://your-server.com/webhooks/gobtc
X-GoBTC-Signature: t=1718766000,v1=4f2c8e...
Content-Type: application/json
{
"id": "evt_9aZ...",
"type": "payment.confirmed",
"created_at": "2026-06-19T03:01:12Z",
"data": {
"id": "pay_1Hk9x...",
"status": "confirmed",
"attribution_id": "inst_3Ad9...",
"amount_btc": "0.00052431"
}
}Always verify the X-GoBTC-Signature header against the raw request body:
import crypto from "node:crypto";
// Verify the X-GoBTC-Signature header against the raw request body.
export function verifySignature(rawBody, header, secret) {
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("=")),
);
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(parts.v1),
Buffer.from(expected),
);
}Idempotency-Key header on POST requests; retries with the same key return the original result instead of creating a duplicate payment.429 response includes a Retry-After header. Back off and retry.code and a human-readable message.id.POST /payments with the merchant_id and your attribution_id; render the returned QR / deep link in your own UX.GET /payments/{id} for status and subscribe to institution-level webhooks for every attributed payment.createPayment at checkout and handle the success / failure / expiry events in the UI.payment.confirmed.