Embedded payments view
Drop a NexusPay payments table into your own app — for your ops staff, for your customers, or both — without building it yourself. One backend call mints a short-lived token, one <iframe> renders it.
How it works
Your backend (using your sk_* key) calls POST /v1/embed_tokens with the project the iframe should show and the audience (your own ops staff, or one specific end-user). We return a signed token that expires in 30 minutes by default. You drop that token into an <iframe> URL pointing at /embed/payments/<uuid> and render the page. Each token is bound to one project and one audience scope — it can't be reused to view another merchant's data, and a token minted for one embed surface can't unlock another.
1. Mint a token (backend)
Server-side, from any language. With your live or test secret key:
curl -X POST "https://nexuspayph.com/v1/embed_tokens" \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"project_uuid": "<YOUR_PROJECT_UUID>",
"audience": "merchant",
"ttl_seconds": 1800
}'Response:
{
"token": "eyJ2IjoyLC...",
"expires_at": "2026-05-30T14:42:18.000Z",
"project_uuid": "...",
"audience": "merchant",
"scope_field": null,
"ttl_seconds": 1800
}2. Render the iframe (frontend)
Drop the token into the src URL and load /embed.js on the host page so the iframe auto-sizes to its content.
<iframe id="nxp-payments"
src="https://nexuspayph.com/embed/payments/<YOUR_PROJECT_UUID>?token=<TOKEN>"
style="width: 100%; height: 200px; border: 0"></iframe>
<script src="https://nexuspayph.com/embed.js"></script>Optional query params: ?theme=dark for a dark palette. Default is light.
Audiences
The same embed URL serves two audiences. The token's claims decide which one the iframe shows.
Merchant — your own ops view
Shows every payment for that project, newest first. Use when you want your staff to see all activity (e.g. an internal dashboard).
{
"project_uuid": "...",
"audience": "merchant"
}Customer — one end-user's view
Shows only payments matching one identifier you control. Use this when an end-user (player, customer, sub-merchant) logs into your app and you want them to see only their own transactions. NexusPay never authenticates end-users; you vouch for them by issuing the token.
Two scope keys are supported. Pick whichever matches your existing integration.
// If you set "external_id" when creating payments
// (e.g. your order ID — typical for compat integrations):
{
"project_uuid": "...",
"audience": "customer",
"scope_field": "external_id",
"scope_value": "ORDER-12345"
}
// If you use the modern Customers API (cus_* identifiers):
{
"project_uuid": "...",
"audience": "customer",
"scope_field": "customer_id",
"scope_value": "cus_abc123"
}For customer_id we validate the customer exists and belongs to you at mint time — typos fail fast with a 404. For external_id we trust whatever string you pass (it's your own reference) and the iframe simply shows zero rows if no payment matches.
Token lifecycle
- TTL: 30 minutes by default. Override with
ttl_secondson the mint call (range: 60 – 86400). - One-shot rendering: mint a fresh token each time your backend serves the page to an end-user. Don't cache or share tokens across sessions.
- Expiry: once expired the iframe shows an “invalid or expired” card. Refresh the page to mint a new one.
Security model
- HMAC-signed: tokens are signed with our embed secret. Tampered tokens are rejected.
- Bound to one project: a token minted for project A only renders at
/embed/payments/<A-uuid>. Using it at a different UUID returns 401. - Iframe allowlist (frame-ancestors CSP): we can lock each project to a specific set of parent origins so a token that leaks can't be rendered inside an arbitrary site. Email us with the origins you want allowed for your project.
- No Referer leak: embed pages emit
Referrer-Policy: no-referrerso the token in the URL never crosses the embed to a third-party resource via the Referer header. - Read-only: embed tokens can't mutate anything; they only unlock the payments view for one project and (optionally) one scope.
Errors
From POST /v1/embed_tokens:
401 unauthenticated // missing/invalid sk_* 404 project_not_found // project doesn't exist OR isn't yours 403 project_disabled // project exists but is disabled 400 missing_scope // audience=customer without scope_field/scope_value 400 unexpected_scope // audience=merchant with stray scope_value 404 customer_not_found // scope_field=customer_id, no such cus_* for you 400 invalid_request // zod body validation (bad uuid, ttl out of range, ...)
From GET /embed/payments/<uuid> the iframe shows a small error card — the underlying HTTP status is 401 for token problems, 404 when the project is gone.