Create a ramp link
Create a session-bound hosted 0Gate link for email, QR, support, dashboard, or mobile handoff flows.
A ramp link is a session-bound hosted entry point into 0Gate. Use it when the user should open 0Gate from a message, QR code, dashboard action, support flow, or native app handoff instead of an embedded widget.
Safe link pattern
Prefer sending users to an app-owned URL that looks up the order, checks that the session is still usable, and then redirects to 0Gate. Avoid emailing or publishing raw client_secret values directly in long-lived links.
Implementation shape
- Create your order, invoice, top-up, or withdrawal intent.
- Create a 0Gate session with a return URL, cancel URL, flow lock, and
user_reference. - Store the session id and attempt id in your backend.
- Send the user an app-owned link such as
https://app.example/pay/order_123. - When the link opens, validate the order state and redirect using the hosted redirect SDK.
- Close the order only after webhook verification.
// App-owned route, not a public secret-bearing URL.
export async function openRampLink(orderId: string) {
const order = await db.orders.findById(orderId);
if (!order || order.status !== 'requires_payment') {
return { redirectTo: `/orders/${orderId}` };
}
return {
publishableKey: process.env.PUBLIC_GATE_KEY,
clientSecret: order.gateClientSecret,
};
}Link guardrails
| Risk | Guardrail |
|---|---|
| Link forwarded to another person | Authenticate the user before redirecting, or keep the hosted flow constrained and support-safe. |
| Link opens after session expiry | Check state and create a new attempt if the user still wants to proceed. |
| User opens multiple times | Use idempotency keys and one durable order attempt record. |
| Support asks for a link | Share the app-owned order URL, not secret keys or raw internal state. |
| Email previews or crawlers open links | Require a user click or authenticated app route before redirecting to the hosted flow. |