NFT Checkout
Overview
Belong NFT Checkout lets a store accept an on-chain payment and automatically issue an NFT without moving its product catalog or order system into Belong.
The store remains responsible for products, inventory, orders, refunds, and physical fulfillment. Belong stores the checkout snapshot, payment status, NFT data, and verified on-chain result.
The integration is not tied to Shopify. A Shopify app, custom storefront, or any other commerce backend can use the same API and SDK. The store's developer performs the integration; Belong does not need access to the store admin.
crypto_wallet only. Customers pay from their Belong wallet. The universal checkout also supports thirdweb_card for merchants and networks where Belong has enabled it. Stripe, Crossmint, and Transak are not part of this checkout flow.What the store provides
- A backend that validates the product, inventory, and price.
- Its own pending order and a stable order reference.
- An exact HTTPS storefront origin.
- An HTTPS webhook endpoint.
- A frontend container where the Belong checkout iframe can open.
What Belong provides
- NFT collection creation and deployment through Belong CheckIn.
- A server API for creating idempotent checkout sessions.
- A hosted payment page embedded through
@belongnet/sdk. - Belong sign-in and the customer's Belong wallet.
- Wallet top-up guidance when the customer needs funds for payment or network fees.
- Thirdweb transaction execution.
- Automatic NFT issuance after a verified payment.
- Signed payment-completion webhooks.
End-to-end flow
One-time setup
- The store owner creates and deploys an EVM NFT collection in Belong CheckIn.
- The collection defines its chain, payment token, supply, metadata, and pricing strategy.
- Use dynamic pricing if different store products have different NFT prices. A static-price collection accepts only its configured mint price.
- Belong issues a server API key with
checkout:createand, if webhook retries are needed,checkout:retrypermission. - The store keeps the API key on its backend. It must never be added to storefront JavaScript.
This is a store NFT collection, not an NFT membership. The pilot creates one NFT for one verified store order.
Every order
- The customer starts checkout in the store.
- The store backend validates the product and price, then creates its own pending order.
- The backend creates a Belong checkout session using the order reference and NFT snapshot.
- Belong verifies that the API-key owner owns the deployed collection and returns
checkoutId,clientSecret, the hosted checkout URL, and an optional webhook signing secret. - The storefront passes only
checkoutIdandclientSecretto the SDK. - The SDK embeds the Belong checkout page. Belong verifies the actual store origin before showing payment actions.
- The customer signs in and continues with their Belong wallet.
- If the wallet does not have enough USDC, the customer funds it before continuing.
- On the BNB Chain wallet flow, the customer may also need a small amount of BNB for the USDC approval network fee. BNB top-up is available through Belong, after which the customer returns to the same checkout.
- The customer approves USDC spending and continues payment through Thirdweb. The main payment and NFT issuance continue automatically after approval.
- Belong verifies the on-chain result, records the NFT, and completes the checkout.
- The iframe updates the store UI. The store marks its order as paid only after verifying the signed
checkout.completedwebhook.
Unlike the previous Crossmint flow, wallet checkout is not completed in a single action when the customer still needs BNB for approval.
Create a checkout session
Create sessions from the store backend only.
POST https://api.belong.net/api/v3/checkout/sessions
Content-Type: application/json
x-api-key: YOUR_SERVER_API_KEY
{
"collectionId": "COLLECTION_ID",
"externalOrderId": "store:order:89351",
"items": [
{
"name": "Partner Product NFT",
"description": "Digital proof of purchase",
"mintPrice": 49,
"image": "https://shop.example/assets/product-nft.png",
"externalProductRef": "store:variant:4471",
"quantity": 1
}
],
"paymentMethods": ["crypto_wallet"],
"allowedOrigin": "https://shop.example",
"webhookUrl": "https://shop.example/api/belong/webhook",
"expiresInSeconds": 1800
}
Current checkout sessions accept exactly one item with quantity 1. mintPrice uses the payment token configured on the collection.
externalOrderId is idempotent for the API-key owner. Repeating the same request returns the same checkout. Reusing the order reference with different checkout data returns 409.
For the first partner, send only crypto_wallet. Add thirdweb_card only after Belong enables card payments for the collection and confirms support for the selected network.
Response
{
"checkoutId": "CHECKOUT_ID",
"clientSecret": "...",
"checkoutUrl": "https://checkin.belong.net/checkout/CHECKOUT_ID#clientSecret=...",
"webhookSecret": "...",
"status": "PENDING",
"expiresAt": "2026-09-08T15:00:00.000Z"
}
Send checkoutId and clientSecret only to the storefront that requested the order. Keep webhookSecret on the store backend.
The hosted URL stores the client secret in the URL fragment. Browsers do not send fragments in HTTP requests or referrer headers. The hosted page uses the X-Checkout-Client-Secret header when it reads the public session.
Embed the checkout
Install and import @belongnet/sdk, then mount the checkout in a container:
<div id="belong-checkout" style="height: 720px"></div>
import {
BELONG_CHECKOUT_ORIGIN,
createPaymentFrame,
isPaymentEvent,
PaymentEvent,
PaymentTarget,
} from '@belongnet/sdk'
const { checkoutId, clientSecret } = checkout
const { frame } = createPaymentFrame({
el: document.getElementById('belong-checkout')!,
params: {
target: PaymentTarget.Checkout,
checkoutId,
clientSecret,
},
})
function onMessage(event: MessageEvent) {
if (event.source !== frame.contentWindow) return
if (!isPaymentEvent(event, BELONG_CHECKOUT_ORIGIN)) return
if (event.data.type === PaymentEvent.PaymentSuccess) {
showPaymentPendingServerConfirmation()
}
if (event.data.type === PaymentEvent.PaymentError) {
showPaymentError(event.data.payload.error)
}
}
window.addEventListener('message', onMessage)
The SDK supplies window.location.origin to the hosted frame. It sends only the origin as the iframe referrer so Belong can verify the real embedding site without receiving the store page path.
Browser events are for UI updates only:
| Event | Meaning |
|---|---|
loaded | The hosted checkout is ready. |
payment-success | Belong accepted the payment result and is refreshing authoritative checkout state. |
payment-error | Payment could not continue. |
payment-canceled | The customer closed the checkout. |
Always verify both the message origin and event.source === frame.contentWindow.
Verify the completion webhook
Belong sends checkout.completed after it has verified the payment and NFT mint. The request includes:
x-belong-event-id: checkout-completed-CHECKOUT_ID
x-belong-signature: v1=HMAC_SHA256_SIGNATURE
Compute HMAC-SHA256 over the exact raw request body with the webhookSecret. Compare signatures in constant time, reject invalid requests, and process x-belong-event-id idempotently.
The payload includes the external order ID, transaction hash, paid amount, payment token, chain, NFT collection address, minted token IDs, and owner wallet.
Return a 2xx response only after your system has durably recorded the event. If delivery failed, an authorized backend can request another attempt:
POST https://api.belong.net/api/v3/checkout/sessions/CHECKOUT_ID/webhook/retry
x-api-key: YOUR_SERVER_API_KEY
Checkout states
| State | Meaning |
|---|---|
PENDING | The customer may continue payment. |
COMPLETED | The on-chain payment and NFT mint were verified. |
EXPIRED | A new payment cannot start because the session lifetime ended. |
FAILED | A terminal server-side failure stopped the checkout. |
A transaction prepared before expiry may still complete after expiry when its successful receipt is verified. A transaction hash can complete only one checkout.
Security checklist
- Create sessions only after validating the order and price on the store backend.
- Never expose the store API key or webhook secret to the browser.
- Register the exact HTTPS store origin. Wildcards are not supported.
- Treat the server webhook, not the browser event, as proof of payment.
- Store processed webhook event IDs and handle duplicate delivery safely.
- Reuse the same
externalOrderIdonly when retrying the exact same order snapshot. - Do not enable
thirdweb_carduntil Belong confirms it for the merchant and network.