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_abc123session = 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_abc123curl -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>
}Using Webhooks (Recommended)
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
| Status | Description |
|---|---|
open | Session is active, customer can pay |
complete | Payment was successful |
expired | Session 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
| Event | Description |
|---|---|
checkout.session.completed | Payment successful |
checkout.session.expired | Session 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:
- Go to Settings > Branding
- Upload your logo
- Set your brand color
- 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'
})