Skip to content

Standard Checkout

Redirect customers to a hosted checkout page on ZevPay. Create a session on your server with your secret key, then redirect the customer to the checkout URL.

How it works

  1. Your server creates a checkout session via the API (using your secret key)
  2. You redirect the customer to the returned checkout_url
  3. Customer selects a payment method and completes payment on the ZevPay checkout page
  4. Customer is redirected back to your callback_url with the payment status

Integration

Step 1: Create a session (server-side)

js
const response = await fetch('https://api.zevpaycheckout.com/v1/checkout/session/initialize', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'sk_test_your_secret_key',
  },
  body: JSON.stringify({
    amount: 500000, // ₦5,000 in kobo
    currency: 'NGN',
    email: 'customer@example.com',
    customer_name: 'John Doe', // optional
    callback_url: 'https://yoursite.com/payment/callback',
    reference: 'order_12345', // optional
    metadata: { orderId: '12345' }, // optional
  }),
});

const { data } = await response.json();
// data.checkout_url → "https://secure.zevpaycheckout.com/{sessionId}"
// data.session_id  → save this for verification
python
import requests

response = requests.post(
    "https://api.zevpaycheckout.com/v1/checkout/session/initialize",
    headers={
        "Content-Type": "application/json",
        "x-api-key": "sk_test_your_secret_key",
    },
    json={
        "amount": 500000,
        "currency": "NGN",
        "email": "customer@example.com",
        "customer_name": "John Doe",
        "callback_url": "https://yoursite.com/payment/callback",
        "reference": "order_12345",
    },
)

data = response.json()["data"]
checkout_url = data["checkout_url"]
session_id = data["session_id"]
php
$ch = curl_init('https://api.zevpaycheckout.com/v1/checkout/session/initialize');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'x-api-key: sk_test_your_secret_key',
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'amount' => 500000,
    'currency' => 'NGN',
    'email' => 'customer@example.com',
    'customer_name' => 'John Doe',
    'callback_url' => 'https://yoursite.com/payment/callback',
    'reference' => 'order_12345',
  ]),
  CURLOPT_RETURNTRANSFER => true,
]);

$response = json_decode(curl_exec($ch), true);
$checkoutUrl = $response['data']['checkout_url'];
$sessionId = $response['data']['session_id'];

Step 2: Redirect the customer

Redirect the customer to the checkout_url returned from the initialization call:

js
// Browser redirect
window.location.href = data.checkout_url;

Or link directly:

html
<a href="https://secure.zevpaycheckout.com/ecc48011-e36e-4741-9b99-657f4a1ee86e">
  Complete Payment
</a>

Step 3: Handle the callback

After the customer completes (or cancels) payment, they are redirected to your callback_url with query parameters:

https://yoursite.com/payment/callback?status=success&reference=ZVP-CKO-S-abc123

Callback query parameters:

ParameterValuesDescription
statussuccessPayment completed
statuscancelledCustomer cancelled/closed checkout
statusexpiredSession expired
referencestringTransaction reference (only on success)

Step 4: Verify the payment (server-side)

Always verify

Never trust the callback query parameters alone. Always verify payment on your server.

js
// Your callback route handler
app.get('/payment/callback', async (req, res) => {
  const { status, reference } = req.query;

  if (status === 'success') {
    // Verify with ZevPay
    const verification = await fetch(
      `https://api.zevpaycheckout.com/v1/checkout/session/${sessionId}/verify`,
      {
        headers: { 'x-api-key': 'sk_test_your_secret_key' },
      }
    );

    const { data } = await verification.json();

    if (data.status === 'completed') {
      // Payment confirmed — fulfill the order
      await fulfillOrder(data.reference, data.amount);
      res.redirect('/order/success');
    } else {
      res.redirect('/order/pending');
    }
  } else if (status === 'cancelled') {
    res.redirect('/checkout');
  } else if (status === 'expired') {
    res.redirect('/checkout?error=expired');
  }
});

Initialization parameters

ParameterTypeRequiredDescription
amountintegerYesAmount in kobo
currencystringYesCurrency code ("NGN")
emailstringYesCustomer's email address
callback_urlstringYesURL to redirect after payment
referencestringNoYour unique transaction reference
customer_namestringNoCustomer's name — displayed in the dashboard instead of "Anonymous"
metadataobjectNoCustom data attached to the session
payment_methodsstring[]NoEnabled methods: ["bank_transfer", "payid"]

Checkout page states

StateDescription
LoadingFetching session details
ReadyPayment methods displayed, awaiting selection
ExpiredSession has timed out, option to return to merchant
Not FoundInvalid session ID
ErrorAPI or network error

Full example (Express.js)

js
const express = require('express');
const app = express();

// Create checkout session
app.post('/create-checkout', async (req, res) => {
  const response = await fetch('https://api.zevpaycheckout.com/v1/checkout/session/initialize', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.ZEVPAY_SECRET_KEY,
    },
    body: JSON.stringify({
      amount: req.body.amount * 100, // Convert Naira to kobo
      currency: 'NGN',
      email: req.body.email,
      callback_url: `${req.protocol}://${req.get('host')}/payment/callback`,
      reference: `order_${Date.now()}`,
      metadata: { userId: req.user.id },
    }),
  });

  const { data } = await response.json();

  // Save session_id for later verification
  await saveSessionId(req.user.id, data.session_id);

  // Redirect to checkout
  res.redirect(data.checkout_url);
});

// Handle callback
app.get('/payment/callback', async (req, res) => {
  const { status, reference } = req.query;

  if (status !== 'success') {
    return res.redirect('/checkout?error=' + status);
  }

  // Verify payment
  const sessionId = await getSessionIdForUser(req.user.id);
  const verification = await fetch(
    `https://api.zevpaycheckout.com/v1/checkout/session/${sessionId}/verify`,
    { headers: { 'x-api-key': process.env.ZEVPAY_SECRET_KEY } }
  );

  const { data } = await verification.json();

  if (data.status === 'completed') {
    await fulfillOrder(data);
    res.redirect('/order/success');
  } else {
    res.redirect('/order/pending');
  }
});

app.listen(3000);

Compared to Inline Checkout

AspectStandardInline
Session creationServer-side (secret key)Client-side (public key)
User experienceFull-page redirectModal overlay
Backend requiredYesNo
Callback methodURL redirectJavaScript function
Best forE-commerce, invoicesQuick checkouts, SPAs

Resources

ZevPay Checkout Developer Documentation