PayGate

Checkout Sessions

Build a hosted checkout experience for your customers.

Checkout Sessions

Checkout Sessions provide a hosted payment page that handles the entire payment flow. Simply redirect customers to PayGate's checkout page and we'll handle the rest.

Why Use Checkout?

  • Faster integration - No need to build a payment form
  • Mobile optimized - Works great on all devices
  • Secure - PCI compliant by default
  • Branded - Customize with your logo and colors
  • Conversion optimized - Tested and optimized for high conversion

Checkout Sessions are the fastest way to start accepting payments. You can be live in minutes.

How It Works

Create a Checkout Session

Your server creates a Checkout Session with the payment details.

Redirect to Checkout

Redirect your customer to the PayGate-hosted checkout page.

Customer Pays

Customer selects their payment method and completes the payment.

Redirect Back

Customer is redirected to your success or cancel URL.

Create a Checkout Session

const session = await paygate.checkout.sessions.create({
  amount: 5000, // GHS 50.00
  currency: 'GHS',
  success_url: 'https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancel_url: 'https://yoursite.com/cancel',
  metadata: {
    order_id: '1234'
  }
})

// Redirect customer to session.url
console.log(session.url)
// https://paygate.44.200.142.19.nip.io/checkout/cs_abc123
session = client.checkout.sessions.create(
    amount=5000,
    currency='GHS',
    success_url='https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
    cancel_url='https://yoursite.com/cancel',
    metadata={'order_id': '1234'}
)

print(session.url)
# https://paygate.44.200.142.19.nip.io/checkout/cs_abc123
$session = $paygate->checkout->sessions->create([
    'amount' => 5000,
    'currency' => 'GHS',
    'success_url' => 'https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
    'cancel_url' => 'https://yoursite.com/cancel',
    'metadata' => ['order_id' => '1234']
]);

echo $session->url;
// https://paygate.44.200.142.19.nip.io/checkout/cs_abc123
curl -X POST https://api.44.200.142.19.nip.io/v1/checkout/sessions \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "GHS",
    "success_url": "https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}",
    "cancel_url": "https://yoursite.com/cancel",
    "metadata": {
      "order_id": "1234"
    }
  }'

Checkout Session Object

{
  "id": "cs_abc123def456",
  "object": "checkout.session",
  "status": "open",
  "url": "https://paygate.44.200.142.19.nip.io/checkout/cs_abc123def456",
  "amount": 5000,
  "currency": "GHS",
  "payment": null,
  "customer": null,
  "customer_email": null,
  "success_url": "https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}",
  "cancel_url": "https://yoursite.com/cancel",
  "metadata": {
    "order_id": "1234"
  },
  "expires_at": "2024-01-15T11:00:00Z",
  "created_at": "2024-01-15T10:00:00Z"
}

Configuration Options

Pre-fill Customer Information

const session = await paygate.checkout.sessions.create({
  amount: 5000,
  currency: 'GHS',
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  customer_email: 'customer@example.com',
  customer_phone: '0241234567'
})

Attach to Existing Customer

const session = await paygate.checkout.sessions.create({
  amount: 5000,
  currency: 'GHS',
  customer: 'cus_abc123', // Existing customer ID
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel'
})

Custom Expiration

const session = await paygate.checkout.sessions.create({
  amount: 5000,
  currency: 'GHS',
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  expires_at: new Date(Date.now() + 30 * 60 * 1000).toISOString() // 30 minutes
})

Collect Additional Information

const session = await paygate.checkout.sessions.create({
  amount: 5000,
  currency: 'GHS',
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  collect_shipping_address: true,
  collect_billing_address: true
})

Handle Success

On Your Success Page

Retrieve the session to verify payment:

// pages/success.ts
export default async function SuccessPage({ searchParams }) {
  const sessionId = searchParams.session_id

  // Retrieve the session from your server
  const session = await paygate.checkout.sessions.retrieve(sessionId)

  if (session.status === 'complete' && session.payment_status === 'paid') {
    // Payment was successful!
    const orderId = session.metadata.order_id

    return (
      <div>
        <h1>Payment Successful!</h1>
        <p>Thank you for your order #{orderId}</p>
      </div>
    )
  }

  return <div>Payment not completed</div>
}

Don't rely solely on the redirect. Use webhooks to confirm payment:

app.post('/webhooks', (req, res) => {
  const event = Webhook.constructEvent(req.body, signature, secret)

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object

    // Fulfill the order
    await fulfillOrder(session.metadata.order_id)
  }

  res.json({ received: true })
})

Always verify payment on the server using webhooks or by retrieving the session. Don't trust the redirect alone.

Handle Cancellation

When a customer clicks the back button or cancels:

// pages/cancel.ts
export default function CancelPage() {
  return (
    <div>
      <h1>Payment Cancelled</h1>
      <p>Your order has not been processed.</p>
      <a href="/cart">Return to Cart</a>
    </div>
  )
}

Session Statuses

StatusDescription
openSession is active, customer can pay
completePayment was successful
expiredSession expired before payment

Session Expiration

Checkout Sessions expire after 24 hours by default. You can customize this:

// Expires in 1 hour
const session = await paygate.checkout.sessions.create({
  amount: 5000,
  currency: 'GHS',
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel',
  expires_at: new Date(Date.now() + 60 * 60 * 1000).toISOString()
})

Webhook Events

EventDescription
checkout.session.completedPayment successful
checkout.session.expiredSession expired

Integration Example

Express.js Backend

import express from 'express'
import PayGate from '@paygate/node'

const app = express()
const paygate = new PayGate(process.env.PAYGATE_SECRET_KEY!)

// Create checkout session
app.post('/create-checkout-session', async (req, res) => {
  const { orderId, amount } = req.body

  const session = await paygate.checkout.sessions.create({
    amount,
    currency: 'GHS',
    success_url: `${process.env.FRONTEND_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.FRONTEND_URL}/cancel`,
    metadata: { order_id: orderId }
  })

  res.json({ url: session.url })
})

// Webhook handler
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
  const event = paygate.webhooks.constructEvent(
    req.body,
    req.headers['x-paygate-signature'],
    process.env.PAYGATE_WEBHOOK_SECRET!
  )

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object
    // Fulfill order
    fulfillOrder(session.metadata.order_id)
  }

  res.json({ received: true })
})

React Frontend

function CheckoutButton({ orderId, amount }) {
  const handleCheckout = async () => {
    const response = await fetch('/create-checkout-session', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ orderId, amount })
    })

    const { url } = await response.json()

    // Redirect to PayGate checkout
    window.location.href = url
  }

  return (
    <button onClick={handleCheckout}>
      Checkout
    </button>
  )
}

Customization

Branding

Customize the checkout page appearance in your Dashboard:

  1. Go to Settings > Branding
  2. Upload your logo
  3. Set your brand color
  4. Preview and save

Payment Methods

Control which payment methods are available:

const session = await paygate.checkout.sessions.create({
  amount: 5000,
  currency: 'GHS',
  payment_method_types: ['mobile_money'], // Only mobile money
  success_url: 'https://yoursite.com/success',
  cancel_url: 'https://yoursite.com/cancel'
})