Verify payment
curl --request POST \
--url https://staging.api.payluk.ng/v1/payment/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'customer-id: <customer-id>' \
--data '
{
"reference": "99999533334",
"otp": "123456"
}
'import requests
url = "https://staging.api.payluk.ng/v1/payment/verify"
payload = {
"reference": "99999533334",
"otp": "123456"
}
headers = {
"customer-id": "<customer-id>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'customer-id': '<customer-id>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({reference: '99999533334', otp: '123456'})
};
fetch('https://staging.api.payluk.ng/v1/payment/verify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://staging.api.payluk.ng/v1/payment/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reference' => '99999533334',
'otp' => '123456'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"customer-id: <customer-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/payment/verify"
payload := strings.NewReader("{\n \"reference\": \"99999533334\",\n \"otp\": \"123456\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("customer-id", "<customer-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://staging.api.payluk.ng/v1/payment/verify")
.header("customer-id", "<customer-id>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reference\": \"99999533334\",\n \"otp\": \"123456\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/payment/verify")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["customer-id"] = '<customer-id>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reference\": \"99999533334\",\n \"otp\": \"123456\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Payment intent verified successfully",
"data": {
"id": "6a3cea83734e96016b227460",
"amount": 1000,
"reference": "t53gtryhtyut",
"fee": 0,
"transactionType": "wallet_transfer",
"currency": "NGN",
"transferDetails": null,
"cardId": null,
"walletDetails": {
"phone": "09022334422",
"name": "King David",
"narration": "test"
},
"blockchainDetails": null,
"withdrawalDetails": null,
"escrowDetails": null,
"metadata": null,
"status": "success",
"creditType": "debit",
"createdAt": "2026-06-25T08:44:51.817Z",
"updatedAt": "2026-06-25T08:46:39.479Z"
}
}{
"status": 400,
"message": "amount is required",
"data": {}
}6. Fund it: Payments
Verify payment
Submits a previously created payment intent for processing. Payment uses a deliberate two-step flow for security: Create payment intent only stages the transaction (no money moves), and this endpoint is what actually executes it: debiting the wallet and carrying out the withdrawal, crypto transfer, card charge, or wallet transfer.
Pass the single reference returned when the intent was created. If the transaction requires confirmation (e.g. an SMS OTP / transaction PIN), include it as otp. Requires the customer-id header.
POST
/
v1
/
payment
/
verify
Verify payment
curl --request POST \
--url https://staging.api.payluk.ng/v1/payment/verify \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'customer-id: <customer-id>' \
--data '
{
"reference": "99999533334",
"otp": "123456"
}
'import requests
url = "https://staging.api.payluk.ng/v1/payment/verify"
payload = {
"reference": "99999533334",
"otp": "123456"
}
headers = {
"customer-id": "<customer-id>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'customer-id': '<customer-id>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({reference: '99999533334', otp: '123456'})
};
fetch('https://staging.api.payluk.ng/v1/payment/verify', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://staging.api.payluk.ng/v1/payment/verify",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'reference' => '99999533334',
'otp' => '123456'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"customer-id: <customer-id>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/payment/verify"
payload := strings.NewReader("{\n \"reference\": \"99999533334\",\n \"otp\": \"123456\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("customer-id", "<customer-id>")
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://staging.api.payluk.ng/v1/payment/verify")
.header("customer-id", "<customer-id>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"reference\": \"99999533334\",\n \"otp\": \"123456\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/payment/verify")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["customer-id"] = '<customer-id>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"reference\": \"99999533334\",\n \"otp\": \"123456\"\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Payment intent verified successfully",
"data": {
"id": "6a3cea83734e96016b227460",
"amount": 1000,
"reference": "t53gtryhtyut",
"fee": 0,
"transactionType": "wallet_transfer",
"currency": "NGN",
"transferDetails": null,
"cardId": null,
"walletDetails": {
"phone": "09022334422",
"name": "King David",
"narration": "test"
},
"blockchainDetails": null,
"withdrawalDetails": null,
"escrowDetails": null,
"metadata": null,
"status": "success",
"creditType": "debit",
"createdAt": "2026-06-25T08:44:51.817Z",
"updatedAt": "2026-06-25T08:46:39.479Z"
}
}{
"status": 400,
"message": "amount is required",
"data": {}
}Authorizations
Your secret key as a Bearer token. The key prefix selects the environment: sk_test_... (test) or sk_live_... (live).
Headers
The merchant customer this request acts on behalf of.
Body
application/json
Response
Payment intent submitted and processed.
⌘I