Skip to main content
SafarAPI never touches card data. Your bank collects the customer’s payment; Safariat invoices you monthly for the aggregate net amount (the net_amount frozen in each quote). This page is the money model your finance team needs.

The cycle

  1. Throughout the month you create bookings; each carries a paid_amount_net.
  2. At month end Safariat aggregates your bookings, refunds, and adjustments into one settlement.
  3. The settlement moves to ISSUED; a settlement.issued webhook fires and a PDF invoice becomes available.
  4. You pay the net_due by bank transfer before due_at.
  5. A Safariat admin marks it PAID once the transfer is received.
A booking’s settlement_id is null until it is invoiced, then points at the settlement that included it.

Amounts

All values follow the Money shape (MAD, 2-decimal string). SettlementDetail exposes the per-line breakdown:

Invoice numbering

Live settlements are numbered INV-PRT-<year>-<sequence>, for example INV-PRT-2026-000042. The sandbox does not issue settlements, so you will not retrieve any with a sk_test_* key. Should Safariat produce one for internal verification, it is numbered in a separate series, INV-PRT-TEST-<year>-<sequence>, carries a test banner on its PDF and test_mode: true on its payload. The two series never collide, so a verification document can never be mistaken for an accounting one.

Status lifecycle

Endpoints

  • GET /settlements — list (paginated; DRAFT is never returned).
  • GET /settlements/{id} — detail with lines.
  • GET /settlements/{id}/invoice.pdf — redirect to the pre-signed invoice PDF.
Sandbox (sk_test_*) never issues a settlement — bookings are flagged test_mode=true. Use the response examples to model your reconciliation logic, and validate it end to end only against production.