Accepting payments
Create payment links and let customers pay on a Paylinky-hosted checkout.
Hosted Page API
Create a link on your server, redirect the customer to it, and let Paylinky handle country selection, operator, phone number, OTP steps and crypto addresses.
Flow
- Your backend calls
POST /api/v1/payment-links. - Paylinky returns a
payment_link(valid 30 minutes by default). - Redirect your customer to
payment_link. - The customer pays on the hosted page (Mobile Money or crypto).
- Paylinky sends a signed
payment.completed/payment.failedwebhook to your server. - The customer's browser is redirected to your
success_url(if set).
Create a link
http
1POST https://paylinky.vercel.app/api/v1/payment-links| Field | Required | Description |
|---|---|---|
title | Yes* | Short title shown to the customer (*or description) |
description | No | Longer text |
amount | If fixed | Amount in currency |
currency | Yes | XAF, XOF, CDF, NGN, GHS, KES… — must match a country in /countries |
is_fixed_amount | No | Default true. If false the customer enters the amount |
allowed_countries | No | Array of country codes, e.g. ["CM"] |
expires_in_minutes | No | Default 30; 0 or null = never; max 525600 |
reference | No | Your order reference |
success_url / cancel_url | No | Redirect targets after a final result |
Idempotency-Key header | No | Same key returns the same link (reused: true) |
bash
1curl -X POST https://paylinky.vercel.app/api/v1/payment-links \2 -H "Authorization: Bearer $PAYLINKY_KEY" \3 -H "Idempotency-Key: order-12345" \4 -H "Content-Type: application/json" \5 -d '{6 "title": "Order #12345",7 "amount": 10000,8 "currency": "XAF",9 "is_fixed_amount": true,10 "allowed_countries": ["CM"],11 "success_url": "https://shop.example/thanks"12 }'Response 201:
json
1{2 "success": true,3 "payment_id": "5d2f3c0a-8f0e-4f9b-9d7e-0c1a2b3c4d5e",4 "slug": "pl-k3m9x2q7ab",5 "payment_link": "https://paylinky.vercel.app/pay/pl-k3m9x2q7ab",6 "title": "Order #12345",7 "description": null,8 "is_fixed_amount": true,9 "amount": 10000,10 "currency": "XAF",11 "allowed_countries": ["CM"],12 "status": "active",13 "payments_count": 0,14 "reference": null,15 "sandbox": false,16 "expires_at": "2026-01-01T10:30:00.000Z",17 "created_at": "2026-01-01T10:00:00.000Z",18 "reused": false19}Retrieve a link
http
1GET https://paylinky.vercel.app/api/v1/payment-links/{payment_id_or_slug}Returns the same object plus paid_at (time of the confirmed payment, or null).
Link statuses
| Status | Meaning |
|---|---|
active | Can be paid |
paid | A fixed-amount link that has been paid (single use) |
expired | Past expires_at — the hosted page shows "link expired" |
disabled | Disabled by the merchant or an administrator |
Variable-amount links (is_fixed_amount: false) stay active after payments and increment payments_count.
Return URLs
After a final result, the hosted page redirects to success_url with ?reference=PLK-…&status=success. Never fulfil an order from this redirect alone — use the webhook or GET /transaction/{id}.
Payment links created with a sandbox key (
plk_test_…) open a sandbox checkout banner and never move real money.