PayGate

Payment Links

Create shareable payment links without writing code.

Payment Links

Payment Links allow you to accept payments without building a checkout flow. Create a link, share it with your customers, and get paid.

Overview

Payment Links are perfect for:

  • Invoicing - Send payment requests via email, SMS, or WhatsApp
  • Social selling - Share on Instagram, Twitter, or Facebook
  • No-code payments - Accept payments without a website
  • Quick payments - Get paid for one-off items or services

Payment Links use our hosted checkout page, so you don't need to handle sensitive payment data.

Via Dashboard

  1. Go to Payments > Payment Links in your Dashboard
  2. Click Create payment link
  3. Enter the amount and description
  4. Copy and share your link

Via API

const paymentLink = await paygate.paymentLinks.create({
  amount: 10000, // GHS 100.00
  currency: 'GHS',
  name: 'Premium Subscription',
  description: 'Monthly subscription to Premium plan',
  metadata: {
    product_id: 'prod_123'
  }
})

console.log(paymentLink.url)
// https://paygate.44.200.142.19.nip.io/pay/pl_abc123
payment_link = client.payment_links.create(
    amount=10000,
    currency='GHS',
    name='Premium Subscription',
    description='Monthly subscription to Premium plan',
    metadata={'product_id': 'prod_123'}
)

print(payment_link.url)
# https://paygate.44.200.142.19.nip.io/pay/pl_abc123
$paymentLink = $paygate->paymentLinks->create([
    'amount' => 10000,
    'currency' => 'GHS',
    'name' => 'Premium Subscription',
    'description' => 'Monthly subscription to Premium plan',
    'metadata' => ['product_id' => 'prod_123']
]);

echo $paymentLink->url;
// https://paygate.44.200.142.19.nip.io/pay/pl_abc123
curl -X POST https://api.44.200.142.19.nip.io/v1/payment_links \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "currency": "GHS",
    "name": "Premium Subscription",
    "description": "Monthly subscription to Premium plan",
    "metadata": {
      "product_id": "prod_123"
    }
  }'
{
  "id": "pl_abc123def456",
  "object": "payment_link",
  "active": true,
  "amount": 10000,
  "currency": "GHS",
  "name": "Premium Subscription",
  "description": "Monthly subscription to Premium plan",
  "url": "https://paygate.44.200.142.19.nip.io/pay/pl_abc123def456",
  "metadata": {
    "product_id": "prod_123"
  },
  "created_at": "2024-01-15T10:00:00Z"
}

Configuration Options

Fixed vs Variable Amount

// Fixed amount - customer pays exactly GHS 100
const fixedLink = await paygate.paymentLinks.create({
  amount: 10000,
  currency: 'GHS',
  name: 'Product Purchase'
})

// Variable amount - customer enters their own amount
const variableLink = await paygate.paymentLinks.create({
  currency: 'GHS',
  name: 'Donation',
  allow_custom_amount: true,
  minimum_amount: 100, // GHS 1.00 minimum
  maximum_amount: 1000000 // GHS 10,000 maximum
})

Redirect URLs

const paymentLink = await paygate.paymentLinks.create({
  amount: 10000,
  currency: 'GHS',
  name: 'Product Purchase',
  success_url: 'https://yoursite.com/success?session={SESSION_ID}',
  cancel_url: 'https://yoursite.com/cancelled'
})

Collect Customer Information

const paymentLink = await paygate.paymentLinks.create({
  amount: 10000,
  currency: 'GHS',
  name: 'Event Ticket',
  collect_phone: true,
  collect_email: true,
  collect_name: true,
  collect_address: false
})

Expiration

const paymentLink = await paygate.paymentLinks.create({
  amount: 10000,
  currency: 'GHS',
  name: 'Limited Time Offer',
  expires_at: '2024-12-31T23:59:59Z'
})
const links = await paygate.paymentLinks.list({
  limit: 10,
  active: true
})
const link = await paygate.paymentLinks.retrieve('pl_abc123')
const link = await paygate.paymentLinks.update('pl_abc123', {
  name: 'Updated Product Name',
  description: 'New description'
})
const link = await paygate.paymentLinks.update('pl_abc123', {
  active: false
})

Track Payments

When a customer pays via a Payment Link, a standard Payment object is created. You can:

// List all payments made through a specific link
const payments = await paygate.payments.list({
  payment_link: 'pl_abc123'
})

console.log(`This link has ${payments.data.length} payments`)

Use Webhooks

Listen for payment.succeeded events:

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

  if (event.type === 'payment.succeeded') {
    const payment = event.data.object

    if (payment.payment_link) {
      console.log(`Payment via link: ${payment.payment_link}`)
      // Process the order
    }
  }

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

Payment Links can be shared anywhere:

Email

Hi [Customer Name],

Please complete your payment for [Product Name] using this link:
https://paygate.44.200.142.19.nip.io/pay/pl_abc123

Amount: GHS 100.00

Thank you!

WhatsApp/SMS

Pay GHS 100.00 for your order: https://paygate.44.200.142.19.nip.io/pay/pl_abc123

QR Code

Generate a QR code for your payment link for in-person payments:

import QRCode from 'qrcode'

const qrDataUrl = await QRCode.toDataURL(paymentLink.url)
// Display or download the QR code

Best Practices

1. Use Descriptive Names

Help customers understand what they're paying for:

// Good
name: 'January 2024 Invoice #1234'

// Not as helpful
name: 'Payment'

2. Include Metadata

Track payments with your internal IDs:

const link = await paygate.paymentLinks.create({
  amount: 10000,
  currency: 'GHS',
  name: 'Order #1234',
  metadata: {
    order_id: '1234',
    customer_id: 'cus_xyz',
    invoice_number: 'INV-2024-001'
  }
})

3. Set Expiration for Time-Sensitive Payments

// Expires in 24 hours
const expiresAt = new Date()
expiresAt.setHours(expiresAt.getHours() + 24)

const link = await paygate.paymentLinks.create({
  amount: 10000,
  currency: 'GHS',
  name: 'Flash Sale Item',
  expires_at: expiresAt.toISOString()
})

Clean up links that are no longer needed:

// Deactivate old links
await paygate.paymentLinks.update('pl_abc123', {
  active: false
})