Reconcile settlements
Pull settlement data from the Payments API, the legacy path, and tie it back to the deposits in your bank account and the orders in your own system.
On this page12 sections
- Where settlements fit
- What you'll build
- Before you start
- Step 1: Fetch your settlements
- Store what you fetch
- Step 2: Fetch the transactions behind them
- Step 3: Match settlements to your bank account
- Step 4: Match transactions to your orders
- Step 5: Flag what doesn't match
- What not to reconcile against
- Statuses
- Next steps
Build with AI 1 package
A build package is every page for one task, with the API operations they use. Copy the prompt into a coding assistant, or hand it the package itself: slim links to each page, full inlines all of them in one document.
- Reconcile a settlementEverything needed to match the money Ozow pays into your bank account against the payments you collected, line item by line item, including the fees that make the two differ.
This guide shows you how to pull settlementSettlement Ozow paying the money you have collected into your bank account. Payins arrive at Ozow first and are settled to you on a schedule, so what a customer paid you today and what has been settled to you today are different amounts. data out of the Payments API and tie it back to the deposits in your bank account and the orders in your own system.
You're reading the legacy integration.
This applies if your integration posts to
api.ozow.com and builds a SHA512SHA-512 A hashing algorithm. Ozow uses it to sign the values in a request or a notification so you can tell that they arrived unaltered and came from us. Hashing is one-way: the hash cannot be turned back into what produced it.Wikipedia hash. Build a new integration against Reconcile
settlements on One API instead.
Where settlements fit
When a customer pays you through Ozow, the money lands with Ozow first. Ozow then transfers what you're owed to your bank account. That transfer is a settlement.
How payments are grouped into settlements depends on your settlement model and the payment method. By default Ozow groups transactions together into settlements, but there are several settlement models, and yours may include a custom arrangement. Your specific setup is agreed during onboarding; if you're not sure what applies to you, speak to your account manager.
For reconciliation, the practical consequence is: don't hard-code assumptions about how many records a settlement contains, or how often settlements arrive. Read what the API returns.
There are two separate things to reconcile:
- Did the customer pay? Answered by transaction status.
- Did Ozow pay me? Answered by settlement data, this guide.
A transaction reaching Complete doesn't mean the money has reached you. Settlement happens later,
on a cycle that depends on the payment method. See
Settlements for how that works.
If you reconcile occasionally, the Ozow Dashboard shows all of this with no development work. Build this when you're reconciling regularly or at volume.
What you'll build
Two endpoints do the work, and you need both:
| Endpoint | Gives you | Answers |
|---|---|---|
GET / |
One row per settlement | What did Ozow pay me? |
GET / |
One row per settled transaction | Which payments made that up? |
A typical daily job:
- Fetch your latest settlements and store them.
- Fetch the transactions behind them for the period.
- Match each settlement to a deposit on your bank statement.
- Match each transaction to an order in your system.
- Flag whatever doesn't match.
The rest of this guide walks through those steps. For complete field lists, all parameters and error responses, see the Payments API reference.
Before you start
You'll need your API key from the Ozow Dashboard.
Both endpoints are simple GETs authenticated with your API key in a header:
ApiKey: YOUR_API_KEY
Step 1: Fetch your settlements
GET https://api.ozow.com/secure/settlements?count=100
Staging: https://stagingapi.ozow.com/secure/settlements
The only parameter is count, how many of the most recent settlements to return, up to 100.
curl -X GET "https://api.ozow.com/secure/settlements?count=100" \
-H "ApiKey: <YOUR_API_KEY>" \
-H "Accept: application/json"
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("ApiKey", apiKey);
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.GetAsync("https://api.ozow.com/secure/settlements?count=100");
var body = await response.Content.ReadAsStringAsync();
$ch = curl_init('https://api.ozow.com/secure/settlements?count=100');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['ApiKey: ' . $apiKey, 'Accept: application/json'],
]);
$response = curl_exec($ch);
curl_close($ch);
const response = await fetch(
"https://api.ozow.com/secure/settlements?count=100",
{ headers: { ApiKey: apiKey, Accept: "application/json" } },
);
const data = await response.json();
import requests
response = requests.get(
"https://api.ozow.com/secure/settlements",
params={"count": 100},
headers={"ApiKey": api_key, "Accept": "application/json"},
)
data = response.json()
You get back a settlements array. Three fields do most of the work:
| Field | Use it for |
|---|---|
id |
Your primary key, and the join to the transaction detail in step 2 |
bank |
Matching to the deposit on your bank statement |
amount |
The amount actually transferred, in the settlement currency |
status will be Pending (the settlement was created) or Complete (the payment has been initiated).
Complete does not mean the money has arrived. It means Ozow has initiated the payment. Your
bank statement is the confirmation.
Check the errors array in the response before processing the settlements.
Store what you fetch
This endpoint has no date filter. You can only ask for the latest n, capped at 100; so you can't come back later and request last March.
Poll on a schedule, store every settlement keyed on id, and skip the ones you already have. Choose
a frequency where you can't possibly accumulate more than 100 new settlements between runs; daily is
comfortable for most merchants. If you do fall further behind than that, the missing settlements
aren't retrievable here and you'll need the Dashboard or Ozow Support.
Step 2: Fetch the transactions behind them
GET https://api.ozow.com/secure/settlements/getsitesettlements?fromDate=2026-09-01&toDate=2026-09-30
Staging: https://stagingapi.ozow.com/secure/settlements/getsitesettlements
Both fromDate and toDate are required, in yyyy-mm-dd format. Unlike step 1, this one does take
a date range; so it's where you go for history.
curl -X GET "https://api.ozow.com/secure/settlements/getsitesettlements?fromDate=2026-09-01&toDate=2026-09-30" \
-H "ApiKey: <YOUR_API_KEY>" \
-H "Accept: application/json"
var url =
"https://api.ozow.com/secure/settlements/getsitesettlements"
+ "?fromDate=2026-09-01&toDate=2026-09-30";
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("ApiKey", apiKey);
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.GetAsync(url);
var body = await response.Content.ReadAsStringAsync();
$url = 'https://api.ozow.com/secure/settlements/getsitesettlements'
. '?fromDate=2026-09-01&toDate=2026-09-30';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['ApiKey: ' . $apiKey, 'Accept: application/json'],
]);
$response = curl_exec($ch);
curl_close($ch);
const params = new URLSearchParams({
fromDate: "2026-09-01",
toDate: "2026-09-30",
});
const response = await fetch(
`https://api.ozow.com/secure/settlements/getsitesettlements?${params}`,
{ headers: { ApiKey: apiKey, Accept: "application/json" } },
);
const data = await response.json();
import requests
response = requests.get(
"https://api.ozow.com/secure/settlements/getsitesettlements",
params={"fromDate": "2026-09-01", "toDate": "2026-09-30"},
headers={"ApiKey": api_key, "Accept": "application/json"},
)
data = response.json()
You get an array with one entry per settled transaction. The fields you'll use:
| Field | Use it for |
|---|---|
settlement |
Grouping transactions by settlement, joins to id from step 1 |
transaction |
Matching to the order in your own system |
transaction |
Ozow's identifier for the payment, as a fallback join |
amount |
The settled amount for that transaction |
Group the rows by settlementId. Each group should total that settlement's amount from step 1. If
it does, your two views agree and you can reconcile with confidence. If a group does not total its
settlement, contact support@ozow.com with the settlementId.
Step 3: Match settlements to your bank account
Match on bankReference. It's Ozow's reference for the settlement and it's what appears on your
statement, which makes it a reliable join. Confirm the amount agrees.
Don't match on amount and date alone, two settlements of the same value in the same week is entirely possible.
Step 4: Match transactions to your orders
Match on transactionReference where you set your own reference when creating the payment.
That's the most reliable join, because it's your identifier.
Where you don't have one, match on transactionId: the Ozow identifier you stored when the
payment completed. If you aren't storing that at payment time, start; reconciliation is much harder
without it.
Never match on amount alone. Two customers paying the same amount on the same day is routine, and amount-matching produces quietly wrong results rather than obvious failures.
Step 5: Flag what doesn't match
Check both directions:
- Line items you can't place: a settled transaction with no matching order
- Orders you expected to see settled but didn't: a completed payment that hasn't appeared in any settlement
Give the second a tolerance window: a completed transaction that hasn't settled yet is normal, one that hasn't settled well past its expected cycle isn't.
What not to reconcile against
Three assumptions that produce apparent differences where none exist:
Refunds don't reduce settlements. Refunds come out of your float, not your settlement. A refunded transaction still settles in full.
Fees don't reduce settlements either. Billing is handled separately from settlement.
Only Complete transactions settle. Cancelled, abandoned, errored, voided and pending
transactions never appear in settlement data.
Settlement periods also won't line up with your accounting periods, a settlement can span a month boundary. Reconcile by settlement, then map settlements to periods, not the other way round.
Statuses
Settlement statuses are separate from transaction statuses and reuse many of the same words, so check which one you're reading before you branch on it. See Transaction and settlement statuses.
Next steps
- Full field lists, parameters and error responses; Payments API reference
- How settlements work, Settlements
- Statuses across transactions and settlements, Transaction and settlement statuses
- Moving to One API, Migrating to One API
In the API reference
2 entries
Last updated