PayGate

Checkout Sessions

Create hosted checkout experiences for your customers.

Checkout Sessions API

Checkout Sessions provide a hosted payment page that handles the entire payment flow.

The 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,
  "payment_status": "unpaid",
  "customer": null,
  "customer_email": "customer@example.com",
  "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-16T10:00:00Z",
  "created_at": "2024-01-15T10:00:00Z"
}

Attributes

AttributeTypeDescription
idstringUnique identifier
objectstringAlways "checkout.session"
statusstringopen, complete, expired
urlstringURL to redirect customer to
amountintegerAmount in pesewas
currencystringCurrency code
paymentstringPayment ID (when complete)
payment_statusstringunpaid, paid
customerstringCustomer ID
customer_emailstringPre-filled email
success_urlstringRedirect URL on success
cancel_urlstringRedirect URL on cancel
metadataobjectCustom metadata
expires_atstringWhen session expires
created_atstringCreation timestamp

Create a Checkout Session

Creates a new checkout session.

POST /v1/checkout/sessions

Request Body

ParameterTypeRequiredDescription
amountintegerYesAmount in pesewas
currencystringNoCurrency (default: GHS)
success_urlstringYesRedirect URL on success
cancel_urlstringYesRedirect URL on cancel
customerstringNoExisting customer ID
customer_emailstringNoPre-fill email
customer_phonestringNoPre-fill phone
payment_method_typesarrayNoAllowed payment methods
metadataobjectNoCustom metadata
expires_atstringNoExpiration timestamp
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",
    "customer_email": "customer@example.com",
    "metadata": {
      "order_id": "1234"
    }
  }'
const session = await 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',
  customer_email: 'customer@example.com',
  metadata: {
    order_id: '1234'
  }
})

// Redirect customer to session.url
console.log(session.url)
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',
    customer_email='customer@example.com',
    metadata={'order_id': '1234'}
)

print(session.url)
$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',
    'customer_email' => 'customer@example.com',
    'metadata' => ['order_id' => '1234']
]);

echo $session->url;

URL Parameters

Use {CHECKOUT_SESSION_ID} in your URLs to include the session ID:

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

On redirect, {CHECKOUT_SESSION_ID} is replaced with the actual session ID:

https://yoursite.com/success?session_id=cs_abc123def456

Retrieve a Checkout Session

Retrieves a checkout session by ID.

GET /v1/checkout/sessions/:id
curl https://api.44.200.142.19.nip.io/v1/checkout/sessions/cs_abc123def456 \
  -H "Authorization: Bearer sk_test_..."
const session = await paygate.checkout.sessions.retrieve('cs_abc123def456')
session = client.checkout.sessions.retrieve('cs_abc123def456')

List Checkout Sessions

Returns a list of checkout sessions.

GET /v1/checkout/sessions

Query Parameters

ParameterTypeDescription
limitintegerNumber of results (1-100)
starting_afterstringCursor for pagination
statusstringFilter by status
customerstringFilter by customer
paymentstringFilter by payment ID
curl "https://api.44.200.142.19.nip.io/v1/checkout/sessions?status=complete&limit=10" \
  -H "Authorization: Bearer sk_test_..."
const sessions = await paygate.checkout.sessions.list({
  status: 'complete',
  limit: 10
})
sessions = client.checkout.sessions.list(status='complete', limit=10)

Expire a Checkout Session

Manually expire an open session.

POST /v1/checkout/sessions/:id/expire
curl -X POST https://api.44.200.142.19.nip.io/v1/checkout/sessions/cs_abc123def456/expire \
  -H "Authorization: Bearer sk_test_..."
const session = await paygate.checkout.sessions.expire('cs_abc123def456')
session = client.checkout.sessions.expire('cs_abc123def456')

Session Statuses

StatusDescription
openSession is active and customer can pay
completeCustomer completed payment
expiredSession expired

Payment Statuses

StatusDescription
unpaidPayment not yet made
paidPayment successful

Webhook Events

EventDescription
checkout.session.completedCustomer completed payment
checkout.session.expiredSession expired
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)

    // Optionally send confirmation email
    await sendConfirmationEmail(session.customer_email)
  }

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

Always use webhooks to verify payment completion. Don't rely solely on the redirect.


Integration Example

Backend (Express)

app.post('/create-checkout', 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}/cart`,
    metadata: { order_id: orderId }
  })

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

// Success page verification
app.get('/verify-session', async (req, res) => {
  const { session_id } = req.query

  const session = await paygate.checkout.sessions.retrieve(session_id)

  if (session.status === 'complete' && session.payment_status === 'paid') {
    res.json({ success: true, orderId: session.metadata.order_id })
  } else {
    res.json({ success: false })
  }
})

Frontend (React)

function CheckoutButton({ orderId, amount }) {
  const [loading, setLoading] = useState(false)

  const handleCheckout = async () => {
    setLoading(true)

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

    const { checkoutUrl } = await response.json()

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

  return (
    <button onClick={handleCheckout} disabled={loading}>
      {loading ? 'Loading...' : 'Checkout'}
    </button>
  )
}