Initiate a payment
POST /payments/initiate creates an INITIATED transaction. The environment comes from the bearer secret key.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Amount in kobo. Minimum 100 (₦1). Never send a decimal. |
currency | string | No | Defaults to NGN; currently only NGN is supported. |
customerEmail | string | No | Customer email address. |
customerName | string | No | Customer display name. |
customerPhone | string | No | Customer phone number. |
gateway | string | No | Preferred enabled gateway slug. The payer may choose at checkout. |
callbackUrl | URL | No | Browser destination after checkout. |
webhookUrl | HTTPS URL | No | Transaction-specific event destination where supported. Prefer registered endpoints. |
metadata | object | No | Your order data. Maximum 50 keys. Do not put secrets in metadata. |
idempotencyKey | string | No | Unique key for one logical payment attempt. |
Node.js
const response = await fetch(`${baseUrl}/payments/initiate`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SKYPAY_SECRET_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 1250000,
currency: 'NGN',
callbackUrl: 'https://store.example.com/payments/return',
idempotencyKey: 'order-842-payment-1',
metadata: { orderId: 'order-842' },
}),
})
const result = await response.json()
if (!response.ok) throw new Error(result.error?.message ?? 'Request failed')
PHP
<?php
$payload = json_encode([
'amount' => 1250000,
'currency' => 'NGN',
'callbackUrl' => 'https://store.example.com/payments/return',
'idempotencyKey' => 'order-842-payment-1',
]);
$curl = curl_init('https://api.skypay.ng/api/v1/payments/initiate');
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SKYPAY_SECRET_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $payload,
]);
$result = json_decode(curl_exec($curl), true, flags: JSON_THROW_ON_ERROR);
curl_close($curl);
Python
import os
import requests
response = requests.post(
'https://api.skypay.ng/api/v1/payments/initiate',
headers={'Authorization': f"Bearer {os.environ['SKYPAY_SECRET_KEY']}"},
json={
'amount': 1_250_000,
'currency': 'NGN',
'callbackUrl': 'https://store.example.com/payments/return',
'idempotencyKey': 'order-842-payment-1',
},
timeout=15,
)
response.raise_for_status()
result = response.json()
cURL
curl --request POST "$SKYPAY_BASE_URL/payments/initiate" \
--header "Authorization: Bearer $SKYPAY_SECRET_KEY" \
--header 'Content-Type: application/json' \
--data '{"amount":1250000,"currency":"NGN","idempotencyKey":"order-842-payment-1"}'
Response
The standard success envelope contains reference, checkoutUrl, amount, currency, environment, status, and expiresAt. Redirect the payer to checkoutUrl. The link expires one hour after initiation.
Idempotency
Network retries can submit the same request more than once. Reuse the same idempotency key only when retrying the same logical attempt. SkyPay returns the original open transaction instead of creating a duplicate. A completed transaction cannot be reopened with that key.
Minimal wrapper
class SkyPay {
constructor(secretKey) {
this.baseUrl = 'https://api.skypay.ng/api/v1'
this.headers = {
Authorization: `Bearer ${secretKey}`,
'Content-Type': 'application/json',
}
}
async initiatePayment(params) {
const response = await fetch(`${this.baseUrl}/payments/initiate`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(params),
})
return response.json()
}
async getPayment(reference) {
const response = await fetch(
`${this.baseUrl}/payments/${encodeURIComponent(reference)}`,
{ headers: this.headers }
)
return response.json()
}
}