1. loan.approved Store loan terms and deduction settings
|
2. loan.disbursed Start deducting from merchant sales
|
3. On each sale Validate -> Deduct -> Report
|
4. loan.nearly_complete Cap deductions using max_deduction_amount
|
5. loan.completed Stop all deductions immediately
|
6. settlement.created Batch deductions for a period
|
7. settlement.transferred Confirm bank transferloan.approved outbound webhook -- Store the loan terms, deduction percentage, minimum deduction amount, and repayment schedule. No deductions yet.loan.disbursed outbound webhook -- The merchant has received funds. Start deducting the specified percentage from every sale.POST /api/v1/marketplace/loans/deductions/validate with the sale_amountshould_deduct, per-loan deduction amounts, and merchant_receivesrepayment.deducted inbound webhook to OpenSyloloan.nearly_complete -- The loan is >90% repaid. Cap the next deduction using the max_deduction_amount from the webhook to avoid over-collection.loan.completed -- Stop all deductions for this loan immediately. Any excess collected will be reconciled.settlement.created -- Batch all deductions for a period (daily or weekly) into a settlement and notify OpenSylo.settlement.transferred -- Confirm that the settlement funds have been transferred to OpenSylo's bank account.GET /api/v1/marketplace/loans/active?merchant_id=xxx{
"merchant_id": "merch_001",
"active_loans": [
{
"loan_id": "loan_uuid_1",
"reference": "LOAN-2026-001",
"principal_amount": 500000,
"total_repayment": 525000,
"outstanding_balance": 175000,
"deduction_percentage": 10,
"minimum_deduction": 500,
"currency": "NGN",
"status": "ACTIVE",
"disbursed_at": "2026-02-01T09:00:00.000Z",
"due_date": "2026-05-01T00:00:00.000Z"
}
],
"total_outstanding": 175000
}GET /api/v1/marketplace/loans/{loanId}/status{
"loan_id": "loan_uuid_1",
"reference": "LOAN-2026-001",
"status": "ACTIVE",
"deduction_required": true,
"deduction_percentage": 10,
"collection_priority": "NORMAL",
"is_overdue": false,
"total_due": 525000,
"total_paid": 350000,
"outstanding": 175000,
"percent_complete": 66.67,
"due_date": "2026-05-01T00:00:00.000Z"
}POST /api/v1/marketplace/loans/deductions/validate{
"should_deduct": true,
"sale_amount": 50000,
"total_deduction": 5000,
"merchant_receives": 45000,
"currency": "NGN",
"loans": [
{
"loan_id": "loan_uuid_1",
"reference": "LOAN-2026-001",
"deduction_amount": 5000,
"deduction_percentage": 10,
"outstanding_after": 170000,
"is_capped": false
}
],
"validation_id": "val_uuid",
"valid_until": "2026-01-29T10:45:00.000Z"
}validation_id is valid for 15 minutes. Apply the deduction within that window.should_deduct is false, the sale amount is below all minimum deduction thresholds -- pass the full amount to the merchant.is_capped is true for a loan, the deduction amount has been capped to avoid over-collection (loan is nearly complete).{
"should_deduct": true,
"sale_amount": 50000,
"total_deduction": 7500,
"merchant_receives": 42500,
"currency": "NGN",
"loans": [
{
"loan_id": "loan_uuid_1",
"reference": "LOAN-2026-001",
"deduction_amount": 5000,
"deduction_percentage": 10,
"outstanding_after": 170000,
"is_capped": false
},
{
"loan_id": "loan_uuid_2",
"reference": "LOAN-2026-002",
"deduction_amount": 2500,
"deduction_percentage": 5,
"outstanding_after": 97500,
"is_capped": false
}
],
"validation_id": "val_uuid",
"valid_until": "2026-01-29T10:45:00.000Z"
}POST /api/v1/marketplace/loans/bulk-status{
"loans": [
{
"loan_id": "loan_uuid_1",
"reference": "LOAN-2026-001",
"status": "ACTIVE",
"deduction_required": true,
"outstanding": 175000
},
{
"loan_id": "loan_uuid_2",
"reference": "LOAN-2026-002",
"status": "REPAID",
"deduction_required": false,
"outstanding": 0
},
{
"loan_id": "loan_uuid_3",
"reference": "LOAN-2026-003",
"status": "ACTIVE",
"deduction_required": true,
"outstanding": 300000
}
],
"checked_at": "2026-01-29T10:00:00.000Z"
}repayment.deducted inbound webhook.settlement.created webhook to OpenSylo with the full summary:{
"event": "settlement.created",
"event_id": "evt_stl_001",
"timestamp": "2026-02-03T00:00:00.000Z",
"marketplace": {
"id": "marketplace_uuid",
"name": "Your Marketplace"
},
"settlement": {
"reference": "stl_2026_w05",
"period_start": "2026-01-27T00:00:00.000Z",
"period_end": "2026-02-02T23:59:59.000Z",
"currency": "NGN",
"created_at": "2026-02-03T00:00:00.000Z"
},
"summary": {
"total_deductions": 12,
"total_amount": 60000,
"merchants_included": 3
},
"loans_included": [
{
"opensylo_id": "loan_uuid_1",
"opensylo_reference": "LOAN-2026-001",
"deduction_count": 8,
"deduction_total": 40000
},
{
"opensylo_id": "loan_uuid_2",
"opensylo_reference": "LOAN-2026-002",
"deduction_count": 4,
"deduction_total": 20000
}
],
"bank_transfer": {
"status": "pending",
"destination_bank": "OpenSylo Collections",
"destination_account": "0123456789"
}
}settlement.transferred webhook:{
"event": "settlement.transferred",
"event_id": "evt_stl_002",
"timestamp": "2026-02-03T10:30:00.000Z",
"marketplace": {
"id": "marketplace_uuid",
"name": "Your Marketplace"
},
"settlement": {
"reference": "stl_2026_w05",
"currency": "NGN"
},
"transfer": {
"reference": "txn_bank_001",
"amount": 60000,
"bank_name": "OpenSylo Collections",
"account_number": "0123456789",
"transferred_at": "2026-02-03T10:30:00.000Z",
"bank_reference": "NIP/230203/ABCDEF"
}
}loan.completed webhook while processing a sale, stop deducting for that loan immediately. If a deduction has already been applied but not yet reported, send a repayment.reversed webhook for the excess amount.repayment.failed webhook:{
"event": "repayment.failed",
"event_id": "evt_rep_fail_001",
"failure": {
"reference": "fail_ref_001",
"attempted_amount": 5000,
"reason": "Merchant wallet balance insufficient for deduction",
"code": "INSUFFICIENT_BALANCE",
"attempted_at": "2026-01-30T11:00:00.000Z"
}
}repayment.reversed webhook:{
"event": "repayment.reversed",
"event_id": "evt_rep_rev_001",
"reversal": {
"reference": "rev_ref_001",
"original_deduction_reference": "deduct_ref_001",
"amount": 5000,
"reason": "Original sale was refunded by buyer",
"reversed_at": "2026-02-01T14:00:00.000Z"
}
}loan.defaulted webhook, follow the collection_instructions in the payload. This typically means increasing the deduction percentage and optionally withholding merchant settlements until the outstanding balance is recovered.