VeyqoDEVELOPERS
DocumentationPOST Create a checkout session

Checkout API

POST/checkout/sessions

Create a checkout session

Returns a checkout `url` where the customer pays without leaving Veyqo: by bank transfer, USSD or mobile money on the page itself, or by card in the gateway's own secure form over it. Created here with your secret key, the amount cannot be changed by the customer; open it with the JS SDK or redirect to `url`.

POSThttps://api.veyqo.org/api/v1/checkout/sessionsTry in console
Use your sandbox environment to start. Understand error codes and payment statuses before handling a live payment.
Create a checkout session
curl --request POST "https://api.veyqo.org/api/v1/checkout/sessions" \
  --header "Authorization: Bearer $VEYQO_SECRET_KEY" \
  --header "Accept: application/json" \
  --header "Idempotency-Key: $OPERATION_IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "amount": 50000,
  "currency": "NGN",
  "reference": "ORDER-1001",
  "provider": "paystack",
  "customer": {
    "email": "customer@example.com"
  },
  "success_url": "https://shop.example.com/thanks",
  "cancel_url": "https://shop.example.com/cart"
}'
{
  "success": true,
  "data": {
    "id": "cs_01M6EB66SC61Q3RQYAN0693DGM",
    "object": "checkout_session",
    "url": "https://veyqo.org/pay/cs_01M6EB66SC61Q3RQYAN0693DGM",
    "status": "open",
    "source": "api",
    "provider": "paystack",
    "amount": 50000,
    "currency": "NGN",
    "reference": "ORDER-1001",
    "description": "Order 1001",
    "customer_email": "customer@example.com",
    "payment": null,
    "success_url": "https://shop.example.com/thanks",
    "cancel_url": "https://shop.example.com/cart",
    "expires_at": "2026-11-02T13:00:00+00:00",
    "completed_at": null,
    "created_at": "2026-11-02T12:00:00+00:00"
  }
}

Illustrative examples. Replace IDs and environment variables with your own values. Keep secret keys on your server.

Headers

Authorizationstringrequired
Bearer <secret-key>. This key determines your project environment and must stay on your server.
Content-Typestringrequired
application/json
Acceptstringoptional
application/json
Idempotency-Keystringoptional
Persist one key for the operation and reuse it with the unchanged body on retries. Maximum 255 characters.

Endpoint

POST https://api.veyqo.org/api/v1/checkout/sessions

Server secret key required. Scope: payments:write. The key determines the project and environment; no project-selection header is accepted.

For each new operation, generate and persist one OPERATION_IDEMPOTENCY_KEY. Retry the unchanged request with that same key. Do not generate a new key on every retry.

Request body

amountintegerrequired
Integer minor-unit amount. NGN 500.00 is 50000; JPY 500 is 500. Minimum 1.
currencystringrequired
Three-letter currency supported by the selected provider. Maximum 3 characters.
referencestring | nulloptional
Order reference; a session can create multiple uniquely referenced payment attempts. Maximum 100 characters.
descriptionstring | nulloptional
Maximum 500 characters.
customerobjectoptional
See the JSON example.
customer.emailstring | nulloptional
Maximum 255 characters. Format: email.
customer.namestring | nulloptional
Maximum 255 characters.
metadataobject | array | nulloptional
Your non-sensitive JSON metadata. Objects are recommended; do not store secrets or card details. Maximum 20 entries.
providerstring | nulloptional
Gateway selected by your server or project default; the customer chooses a payment method, not the gateway. Maximum 40 characters.
success_urlstring | nulloptional
HTTP or HTTPS return URL. Use HTTPS in production. Maximum 2048 characters. Format: uri.
cancel_urlstring | nulloptional
HTTP or HTTPS cancellation URL. Use HTTPS in production. Maximum 2048 characters. Format: uri.

Response fields

idstringrequired
Checkout session ID (cs_ prefix).
object"checkout_session"required
See the JSON example.
urlstringrequired
Hosted Veyqo URL; redirect here or open this session using VeyqoCheckout. Format: uri.
statusstringrequired
Values: open, completed, expired.
sourcestringrequired
Values: api, browser, link.
providerstringrequired
Selected provider slug; this field is an object on the browser session detail endpoint.
amountintegerrequired
Server-defined amount in minor units.
currencystringrequired
Three-letter currency.
referencestring | nullrequired
Your order reference, when supplied.
descriptionstring | nullrequired
Checkout description.
customer_emailstring | nullrequired
Customer email if already supplied.
paymentobject | nullrequired
Current payment attempt, if any. A session can have multiple attempts over time.
success_urlstring | nullrequired
Configured return URL. A redirect is not proof of payment.
cancel_urlstring | nullrequired
Configured cancellation URL.
expires_atstringrequired
Session expiry time. Format: date-time.
completed_atstring | nullrequired
ISO 8601 timestamp. Format: date-time.
created_atstring | nullrequired
ISO 8601 timestamp. Format: date-time.

Errors and recovery

CodeHTTPRecoveryRetry policy
INVALID_API_KEY401Use a current kc_test_ or kc_live_ secret key on /api/v1. Use a pk_test_ or pk_live_ publishable key only on browser checkout.After fixing credentials.
INSUFFICIENT_PERMISSION403Grant the required scope or use a suitably scoped key. Dashboard organization roles and staff permissions are separate.After permission changes.
RATE_LIMIT_EXCEEDED429Honor Retry-After, use bounded exponential backoff with jitter, and reduce concurrent requests. Read X-RateLimit headers.Yes, after Retry-After; preserve write idempotency.
METHOD_NOT_ALLOWED405Use the method documented for the endpoint, such as POST for verification and refunds.After fixing the method.
INTERNAL_ERROR500Record X-Request-Id, timestamp and sanitized request context. Reconcile unknown payment outcomes before retrying a write; contact support if it persists.Safe reads: bounded backoff. Writes: reconcile first.
VALIDATION_FAILED422Read error.details when present, correct the named fields and retry only after correction. Validation messages may describe state/capability errors without field details.No automatic retry.
IDEMPOTENCY_KEY_REUSED409Reuse the exact original request to recover that operation, or use a new key only for a genuinely different operation.Do not retry a changed body with that key.
IDEMPOTENCY_IN_PROGRESS409Wait briefly, retry with the same key and unchanged request, then reconcile by reference if the result remains uncertain.Back off with jitter; preserve key/body.
PLAN_LIMIT_REACHED402Review the active plan, project/usage allowances and billing status with the organization owner.After resolving plan/billing restrictions.