Confirm milestone
curl --request POST \
--url https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId} \
--header 'Authorization: Bearer <token>' \
--header 'customer-id: <customer-id>'import requests
url = "https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}"
headers = {
"customer-id": "<customer-id>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'customer-id': '<customer-id>', Authorization: 'Bearer <token>'}
};
fetch('https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}', 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/escrow/milestone/confirm/{escrowId}/{milestoneId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("customer-id", "<customer-id>")
req.Header.Add("Authorization", "Bearer <token>")
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/escrow/milestone/confirm/{escrowId}/{milestoneId}")
.header("customer-id", "<customer-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}")
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>'
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Milestone confirmed successfully",
"data": {
"id": "665f1b2c9a1e4d0012ab3c10",
"paymentToken": "PY_8AB12C9D3045",
"state": "OPENED",
"status": "ONGOING",
"settlementType": "MILESTONE",
"milestones": [
{
"id": "665f1b2c9a1e4d0012ab3c21",
"title": "Design",
"amount": 300000,
"status": "RELEASED",
"releasedAt": "1750584900"
},
{
"id": "665f1b2c9a1e4d0012ab3c22",
"title": "Development",
"amount": 500000,
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c23",
"title": "Deployment",
"amount": 200000,
"status": "PENDING",
"releasedAt": null
}
]
}
}4. Create the deal: Milestone Escrow
Confirm milestone
Buyer approves one milestone; its full amount is released to the seller’s main balance. If the milestone was created with a customerId, the funds are released to that customer’s main balance instead. Requires the escrow to be funded (OPENED) and the caller to be the buyer. The escrow completes automatically when the final milestone is released.
POST
/
v1
/
escrow
/
milestone
/
confirm
/
{escrowId}
/
{milestoneId}
Confirm milestone
curl --request POST \
--url https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId} \
--header 'Authorization: Bearer <token>' \
--header 'customer-id: <customer-id>'import requests
url = "https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}"
headers = {
"customer-id": "<customer-id>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'customer-id': '<customer-id>', Authorization: 'Bearer <token>'}
};
fetch('https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}', 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/escrow/milestone/confirm/{escrowId}/{milestoneId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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"
"net/http"
"io"
)
func main() {
url := "https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("customer-id", "<customer-id>")
req.Header.Add("Authorization", "Bearer <token>")
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/escrow/milestone/confirm/{escrowId}/{milestoneId}")
.header("customer-id", "<customer-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.api.payluk.ng/v1/escrow/milestone/confirm/{escrowId}/{milestoneId}")
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>'
response = http.request(request)
puts response.read_body{
"status": 200,
"message": "Milestone confirmed successfully",
"data": {
"id": "665f1b2c9a1e4d0012ab3c10",
"paymentToken": "PY_8AB12C9D3045",
"state": "OPENED",
"status": "ONGOING",
"settlementType": "MILESTONE",
"milestones": [
{
"id": "665f1b2c9a1e4d0012ab3c21",
"title": "Design",
"amount": 300000,
"status": "RELEASED",
"releasedAt": "1750584900"
},
{
"id": "665f1b2c9a1e4d0012ab3c22",
"title": "Development",
"amount": 500000,
"status": "PENDING",
"releasedAt": null
},
{
"id": "665f1b2c9a1e4d0012ab3c23",
"title": "Deployment",
"amount": 200000,
"status": "PENDING",
"releasedAt": null
}
]
}
}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.
Path Parameters
The escrow's unique identifier.
The milestone's unique identifier.
⌘I