Hosted checkout
POST /v1/checkout/sessions returns a url on binkly’s checkout. Sessions expire after a time you set, from 5 minutes to 7 days.
Create a hosted checkout from your server, send the customer to it, and confirm the order from a signed webhook. binkly routes each payment to the provider accounts you connect.
Developer preview: the v1 API may still change. Test mode is open to anyone who signs up; live payments need an approved business account.
# Create a hosted checkout, then send the customer to its "url"
curl https://api.binkly.tech/v1/checkout/sessions \
-H "Authorization: Bearer sk_test_…" \
-H "Idempotency-Key: order-1042" \
-H "Content-Type: application/json" \
-d '{
"amount": 2400,
"currency": "USD",
"description": "Everyday Bottle",
"client_reference_id": "order-1042",
"success_url": "https://shop.example/thanks?cs={CHECKOUT_SESSION_ID}",
"cancel_url": "https://shop.example/cart"
}'
# Charge a payment method directly (test token shown)
curl https://api.binkly.tech/v1/payments \
-H "Authorization: Bearer sk_test_…" \
-H "Idempotency-Key: 7f3c2a90-pay" \
-H "Content-Type: application/json" \
-d '{
"amount": 2400,
"currency": "USD",
"payment_method": "tok_success",
"description": "Everyday Bottle",
"customer_email": "sara@example.com"
}'
# Refund part of a payment. Leave out "amount" to refund what is left.
curl https://api.binkly.tech/v1/payments/pay_…/refunds \
-H "Authorization: Bearer sk_test_…" \
-H "Idempotency-Key: 7f3c2a90-refund-1" \
-H "Content-Type: application/json" \
-d '{ "amount": 32000 }'
Amounts are integers in the currency’s smallest unit: 2400 is USD 24.00.
One account, one set of keys and one dashboard for all of it.
POST /v1/checkout/sessions returns a url on binkly’s checkout. Sessions expire after a time you set, from 5 minutes to 7 days.
Create, list and retrieve payments with /v1/payments, and refund in full or in part.
A “Pay with binkly” button for any page. It opens the checkout in a small window and tells your page when it is done.
Signed events for payments, refunds and completed checkouts, plus GET /v1/events to catch up.
Send your secret key as a bearer token. Keys that start with sk_test_ work in test mode and sk_live_ keys in live mode; test and live data are kept apart.
Send an Idempotency-Key header when you create a payment, refund or checkout session. If a request is retried with the same key, you get the first result instead of a second charge.
Authorization: Bearer sk_test_…Idempotency-Key: <your order id>{
"id": "pay_…",
"object": "payment",
"mode": "test",
"amount": 2400,
"currency": "USD",
"status": "succeeded",
"amount_refunded": 0,
"fee": 0,
"failure_code": null,
"metadata": {},
"created_at": "…"
}
Status is one of processing, succeeded, failed, partially_refunded or refunded. Shortened.
Add an endpoint in the dashboard and choose the events you want. Each delivery carries a Binkly-Signature header: t=<unix time>,v1=<HMAC-SHA256> of "<t>.<raw body>", signed with your endpoint secret (whsec_…).
If your server does not answer with a 2xx, binkly retries with growing gaps for about 20 hours.
payment.succeeded, payment.failedrefund.succeeded, refund.failedcheckout.session.completedsubscription.created, .renewed, .payment_failed, .updated, .canceled{
"id": "evt_…",
"type": "checkout.session.completed",
"mode": "test",
"created_at": "…",
"data": {
"checkout_session": {
"id": "cs_test_…",
"client_reference_id": "order-1042",
"amount": 2400,
"currency": "USD"
},
"payment": { "id": "pay_…", "status": "succeeded" }
}
}
import crypto from "node:crypto";
// raw: the request body exactly as received
function verify(raw, header, secret) {
const p = Object.fromEntries(header.split(",").map((s) => s.split("=")));
const expected = crypto.createHmac("sha256", secret)
.update(`${p.t}.${raw}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(p.t)) < 300;
return fresh && p.v1?.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(p.v1), Buffer.from(expected));
}
Shortened. Reject events with an old timestamp to stop replays.
Your server creates a checkout session; the page shows the binkly button for it. Customers pay with what they saved in their wallet (cards, mobile wallets, bank transfers or pay later through supported providers) in a small window, and your page is told when it is done.
checkout.session.completed webhook<!-- 1. Where the button goes -->
<div id="binkly-button"></div>
<!-- 2. The script, then the checkout id from your server -->
<script src="https://wallet.binkly.tech/v1/binkly.js"></script>
<script>
Binkly.button("#binkly-button", {
checkout: "cs_test_…",
onComplete: (e) => { location.href = "/thank-you?checkout=" + e.checkout; },
});
</script>
A message in the browser is a hint, not proof: confirm the payment on your server.
A binkly wallet customer can connect an AI assistant and give it a key that only asks to buy. They set the limits: one currency, the most one purchase may cost, a budget for each day, week or month, the stores it may buy from, and an end date. Each purchase waits for their approval in the wallet, or is paid at once below an amount they choose. An agent can keep only a few requests waiting, so it cannot flood the customer.
Your store does nothing new. The assistant pays the same checkout your customers pay, and you get the same checkout.session.completed webhook. The payment's metadata says it was an agent (agent_purchase), and the dashboard shows it.
GET /v1/payments/:id/agent-mandate, checkable at /.well-known/jwks.json)agent_mandate.issued webhook; before buying, an assistant can see whether binkly verified your businessAuthorization: Bearer agk_test_…, revoked by the customer at any timehttps://api.binkly.tech/mcp: the customer signs in to their wallet and sets the limits (OAuth 2.1, no key to copy). A local MCP server and BinklyAgent in @binkly/node too{
"mcpServers": {
"binkly": {
"command": "npx",
"args": ["-y", "@binkly/agent-mcp"],
"env": { "BINKLY_AGENT_KEY": "agk_test_…" }
}
}
}
# Ask the customer to approve paying a checkout
curl https://api.binkly.tech/v1/agent/purchases \
-H "Authorization: Bearer agk_test_…" \
-H "Content-Type: application/json" \
-d '{ "checkout": "cs_test_…", "note": "The coffee beans you buy every month" }'
# Then follow it until "succeeded" (or declined, expired…)
curl https://api.binkly.tech/v1/agent/purchases/agp_… \
-H "Authorization: Bearer agk_test_…"
Over a limit, the answer says which one (over_limit, over_budget…) so the assistant can tell the customer.
Each one uses the same pieces as the API: a hosted checkout per order and a signed webhook when it is paid.
A payment gateway with Blocks checkout support. Orders are marked paid from the signed webhook, refunds work both ways, and every request carries an idempotency key.
Download the plugin (.zip)The binkly button, the hosted checkout url, or payment links you create in the dashboard.
A Shopify payments app. It can be installed once Shopify approves binkly as a payments partner.
Request accessBuilt and tested. It will be switched on once Zid lists binkly as a payment provider.
Request accessNo real money moves in test mode. You can start before you connect a payment provider.
Create an account and copy your sk_test_ key from the dashboard.
Pay with the test tokens tok_success, tok_declined, tok_insufficient_funds and tok_processing_error, and point a webhook at your server.
Request live access. binkly reviews your business; once it is approved, your sk_live_ key starts working.
Tell us about your business. We review it and email you an invite to go live.
Want to start today? Create a business account and use test mode right away.