Payment Gateway

Hosted Checkout

Send customers to a PCI DSS SAQ A compliant payment page hosted by Paygate. Collect card payments securely with 0 cardholder data touching your servers.

Four Critical Rules Before You Begin
  • 1. Browser navigation is not proof of payment. Browsers drop connections, users close tabs, and networks flake. Server events are the authoritative proof of payment that should trigger order fulfilment.
  • 2. Store session.id before handoff. Persist session.id in your database beside the order before issuing the HTTP 303 handoff. If the user comes back, you need this ID to reconcile their state.
  • 3. The page cannot be embedded. Paygate sends strict Content-Security-Policy: frame-ancestors 'none' and X-Frame-Options: DENY headers. To keep customers on your site, use Magic Checkout instead (see the Magic Checkout section).
  • 4. Amount is always integer paise. Amounts are strictly specified in the smallest currency unit. For example, ₹1,250.00 is represented as 125000 paise. Decimal points are rejected.

Checkout Session vs Payment Link

Merchants often conflate checkout sessions with payment links. Choose the right tool for your workflow:

FeatureCheckout sessionPayment link
Created byAPI, at checkout timeDashboard, by a human
Lifetime15 minutes24 hours
Deliveryimmediate handoffemail
Reusableno (single use)resendable
Step 1

One-time setup

Before initializing sessions, configure your Statement Descriptor and authorized destination hosts in the Corporate Portal under Payment Gateway → Settings. Obtain your secret key (starting with sk_). The secret key is server-side only; never include it in mobile apps, single-page client apps, or the browser. Note: There is no live/test split yet; the entire environment currently operates in sandbox simulation mode.

Step 2

Create a session

Call POST /v1/checkout/sessions from your backend server. Always provide an Idempotency-Key header derived from the order (e.g. order-{id}-checkout) rather than a random timestamp or clock. The amount field must be integer paise (e.g., 125000 paise = ₹1,250.00). The reference field is required and serves as your primary reconciliation key.

curl -X POST https://api.paygate.futurepay.bank/v1/checkout/sessions \
  -H "Authorization: Bearer sk_live_merchant_secret_key" \
  -H "Idempotency-Key: order-88213-checkout" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 125000,
    "currency": "INR",
    "reference": "order-88213",
    "success_url": "https://merchant.example.com/checkout/complete",
    "cancel_url": "https://merchant.example.com/checkout/cancelled",
    "description": "Invoice #88213 Payment"
  }'
Step 3

Redirect the customer

Persist session.id in your database linked to the order record. Then redirect the customer’s browser to session.url with an HTTP 303 See Other response. To keep customers on your site, use Magic Checkout instead (see the Magic Checkout section). Avoid using window.open or popups, as mobile pop-up blockers will break the flow.

Step 4

What happens on our page

The customer arrives on Paygate’s secure payment page. The session has a strict 15 minutes expiry window. Customers can enter credit/debit card details with up to 3 retry attempts. The page prominently displays your configured statement descriptor line so customers recognize the charge on their billing statement. All cardholder data is collected directly by Paygate’s PCI DSS Level 1 certified infrastructure. No sensitive card data ever touches your servers or client applications, qualifying your business for the simplified SAQ A compliance questionnaire.

Step 5

Handle the return

When payment completes or the customer cancels, Paygate redirects back to your registered destination with query parameters: session_id, reference, status, timestamp, and signature. Verify the HMAC-SHA256 signature using your secret key. Do not fulfil the order here! The redirect is an acknowledgement for the browser UI only; the server event often arrives before the browser does.

import crypto from "node:crypto";

export function verifyReturnSignature({
  sessionId,
  reference,
  status,
  timestamp,
  signature,
  secretKey
}: {
  sessionId: string;
  reference: string;
  status: string;
  timestamp: string;
  signature: string;
  secretKey: string;
}): boolean {
  // Construct the canonical payload string
  const payload = `session_id=${sessionId}&reference=${reference}&status=${status}&timestamp=${timestamp}`;
  
  // Compute expected HMAC SHA-256 signature using your server-side secret key
  const expectedSignature = crypto
    .createHmac("sha256", secretKey)
    .update(payload)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature, "utf8"),
    Buffer.from(expectedSignature, "utf8")
  );
}
Step 6

Handle the webhook

Paygate delivers an asynchronous signed HTTP POST event checkout.session.completed upon successful payment. This webhook event is your authoritative signal to mark the order as paid, release goods, or initiate shipment. Please refer to the Payment Gateway Webhooks Reference for complete HMAC verification details and delivery retry rules.