Automatic Wave reconciliation = match Wave transactions with site/app orders. Critical for SYSCOHADA accounting + reporting. Here's the 2026 production stack.
TL;DR
- 30% accounting errors without auto reconciliation.
- Wave API provides transaction history.
- Matching by: amount + date + reference.
- Automatic Sage / Pennylane / Excel exports.
Reconciliation architecture
- Pull Wave transactions (daily API)
- Compare with DB orders
- Matching:
- Exact amount
- Date ±24h
- Client_reference (if available)
- 3 result statuses:
- Matched (auto)
- Manual review (fuzzy)
- Unmatched (alert)
- Accounting export
Pull transactions API
`typescript
async function getWaveTransactions({
fromDate,
toDate,
page = 1,
limit = 100,
}: {
fromDate: string; // ISO 8601
toDate: string;
page?: number;
limit?: number;
}) {
const res = await axios.get(
${WAVE_API}/transactions,
{
params: {
from: fromDate,
to: toDate,
page,
limit,
},
headers: {
Authorization: Bearer ${WAVE_TOKEN},
},
}
);
return res.data.transactions;
}
// Usage: get all month's transactions
async function syncMonth(year: number, month: number) {
const fromDate = new Date(year, month - 1, 1).toISOString();
const toDate = new Date(year, month, 0).toISOString();
let allTx: any[] = [];
let page = 1;
while (true) {
const tx = await getWaveTransactions({ fromDate, toDate, page });
if (tx.length === 0) break;
allTx = allTx.concat(tx);
page++;
}
return allTx;
}
`
Matching algorithm
`typescript
async function reconcile(waveTx: WaveTransaction[]) {
const results = {
matched: [] as Array<{ tx: WaveTransaction; order: Order }>,
manual: [] as Array<{ tx: WaveTransaction; candidates: Order[] }>,
unmatched: [] as WaveTransaction[],
};
for (const tx of waveTx) {
// 1. Exact match by client_reference
if (tx.client_reference) {
const order = await db.orders.findOne({ id: tx.client_reference });
if (order && order.amount === tx.amount) {
results.matched.push({ tx, order });
continue;
}
}
// 2. Match by amount + date
const candidates = await db.orders.find({
amount: tx.amount,
createdAt: {
$gte: new Date(tx.created_at).getTime() - 24 * 3600 * 1000,
$lte: new Date(tx.created_at).getTime() + 24 * 3600 * 1000,
},
status: 'pending_payment',
});
if (candidates.length === 1) {
// Auto match
Need a professional website?
Kolonell builds websites that attract clients, optimized for the Sénégalese market. Free quote in 2 minutes.
results.matched.push({ tx, order: candidates[0] });
} else if (candidates.length > 1) {
// Manual review (multiple same-amount orders)
results.manual.push({ tx, candidates });
} else {
// Unmatched
results.unmatched.push(tx);
}
}
return results;
}
`
SYSCOHADA accounting export
`typescript
import { createObjectCsvWriter } from 'csv-writer';
async function exportToSyscohada(matched: Array<{ tx: any; order: any }>) {
const csv = createObjectCsvWriter({
path: '/tmp/wave-reconciliation.csv',
header: [
{ id: 'date', title: 'Date' },
{ id: 'account', title: 'Account' },
{ id: 'debit', title: 'Debit' },
{ id: 'credit', title: 'Credit' },
{ id: 'description', title: 'Description' },
{ id: 'reference', title: 'Reference' },
],
});
const rows = matched.flatMap(({ tx, order }) => [
{
date: tx.created_at.slice(0, 10),
account: '512100', // Wave Bank
debit: tx.amount,
credit: '',
description: Wave receipt ${tx.id},
reference: order.id,
},
{
date: tx.created_at.slice(0, 10),
account: '411000', // Customers
debit: '',
credit: tx.amount,
description: Customer receipt ${order.client_name},
reference: order.id,
},
]);
await csv.writeRecords(rows);
}
`
Directly importable into Sage / Pennylane / Cegid.
Daily cron job
`typescript
// With node-cron or Vercel Cron
import cron from 'node-cron';
cron.schedule('0 1 * * *', async () => {
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const tx = await getWaveTransactions({
fromDate: yesterday.toISOString().slice(0, 10),
toDate: new Date().toISOString().slice(0, 10),
});
const results = await reconcile(tx);
// Daily report email
await sendEmail('finance@kolonell.com', {
subject: 'Wave daily reconciliation',
body: Auto: ${results.matched.length}, Manual: ${results.manual.length}, Unmatched: ${results.unmatched.length},
});
});
`
FAQ
Q: Auto match reliability?
A: 95-98% transactions auto-match with amount + date + reference.
Q: Wave API sync delay?
A: Real-time via webhook. Daily API sync for backup + reporting.
Conclusion
2026 Wave automatic reconciliation: 95-98% auto-match. Daily cron + real-time webhook. SYSCOHADA export = direct accounting imports. Complete 2-5 day dev production stack.
Mohamed Bah
Fondateur, Kolonell
Passionate about digital and entrepreneurship in Africa, Mohamed has been helping Sénégalese businesses with their digital transformation since 2020. Founder of Kolonell, he believes every SME deserves a professional and accessible online présence.

