Core concepts

Products, plans, billing models, customers, subscriptions, bills, usage, and manual payments.


Create objects in the order below. A product cannot be saved without a plan, and a plan cannot be saved without a billing model, so the first call creates all three. The requests themselves are in the API reference.

Merchant

The business that owns all biller data — FiberHub in this guide.

LakiPay creates the merchant when the business signs up. The biller API does not create a merchant and does not move data between merchants.

Sandbox

Testing mode

Only a test key is accepted. Live traffic must not use a test key.

Active

Live mode

Only a production key is accepted. Test traffic must not use a live key.

You do not send merchant fields — LakiPay reads the merchant from the key and sets merchant_id on everything you create.

Product

The service sold — Fiber Internet: one offering, one callback, one category.

Packages live under the product as pricing plans. It is the parent of every subscription. Title (3–100 chars) is what checkout and callbacks show. Description is at most 255 characters. callback_url receives later events; if empty, events are not delivered.

category is one of ELECTRICITY, WATER, INTERNET, GAS, WASTE_MANAGEMENT, CLEANING, MAINTENANCE, EDUCATION, HEALTHCARE, TRANSPORT, ENTERTAINMENT, TELECOM, INSURANCE, RENT, LOAN, OTHER.

Created active. Admin approval sends product:approved; decline sends product:declined and marks inactive. A product with no pricing plan is rejected.

Pricing plan

One package under the product — Starter, Plus, Pro, or Flex.

Each package has its own amount, billing period, late-fee rule, and billing model. A subscriber is on one package at a time.

PeriodBusiness meaning
`DAILY`A new bill every day, or every `recurring_interval` days.
`WEEKLY`A new bill every week.
`MONTHLY`A new bill every month. This is how Starter, Plus, Pro, and Flex renew.
`YEARLY`A new bill every year. Pro Annual is the prepaid year of the Pro package.

recurring_interval multiplies the period. is_default marks the package used when a caller does not pick one (Plus). amount is the fixed-plan price; Flex still has the field, but the bill comes from gigabytes used.

Penalty tiers

Late fee on the plan. When a bill passes its due date, LakiPay applies the tier whose overdue-day window contains the days late.

FieldMeaning
`penalty_type``FIXED` adds `value` as money. `PERCENTAGE` adds `value` percent of the bill.
`value`The fee or the percent. Zero or greater.
`min_overdue_days`The first day this tier applies. At least 1.
`max_overdue_days`The last day. Omit to leave open-ended. Must be ≥ `min_overdue_days`.
`sort_order`Which tier is considered first when windows overlap.
`penalty_max_cap`The most the late fee on this plan can reach.

Billing model

How the amount is calculated — and whether payment is advance or arrears.

One model per plan. You do not send a separate advance/arrears flag — model_type decides that.

FIXED

Every period costs the package amount. Plus is 1,499 ETB/month. Advance.

USAGE_BASED

Quantity × price_per_unit. Flex is 15 ETB/GB. Abel uses 12.5 GB → 187.50. Arrears.

TIERED

Quantity split across bands. Tiers required for TIERED only. Arrears.

HYBRID

Base package fee plus extra data (base_amount + price_per_unit). Arrears.

MANUAL

You already know the money — post manual_amount. Arrears.

usage_source: use MANUAL for third-party API key integrations (not the dashboard webhook source).

Advance vs arrears

When the bill is created and when it is due depends on the model type.

Advance

FIXED models

Customer pays for a period before it is consumed. Due date is the start of the period.

Plus: 1,499 ETB due on the first day of the month. Scheduler creates the bill about one period ahead (monthly ≈ 31 days).

Starter, Plus, and Pro do not need a usage report.

Arrears

USAGE / TIERED / HYBRID / MANUAL

Customer pays after the period. Due date is the end of the period.

Flex: post 12.5 GB for October; bill for 187.50 is due when October ends.

Without usage: usage data not found for billing period. Without manual amount: manual amount not provided for billing period.

Customer

The person or organization that pays — Abel Bekele, phone 251911000111.

Phone is 9–15 digits (checkout and notifications). Email is optional. The same person can hold more than one service (Plus at home, Pro at the office).

Create first and pass customer_id, or embed customer inside subscription create.

Subscription

Contract putting one customer on one package — product user HUB-10042 on Plus.

unique_account_id is your subscriber id (cannot belong to another merchant). subscribed_at is YYYY-MM-DD.

What you sendMeaningStatus at create
`{}`Renews until cancel. `ends_at` empty.`INCOMPLETE`
`duration`Fixed number of periods (e.g. 12 monthly = 1 year).`INCOMPLETE`
`ends_at`You already know the last day.`INCOMPLETE`
`trial_ends_at`Trial — no bills while trialing.`TRIALING`

Statuses

  • INCOMPLETEFirst bill can be created; not yet paid. Renewals wait until active.
  • TRIALINGTrial end set. Scheduler does not generate bills.
  • ACTIVEFirst bill paid or resumed. Keeps generating the next period's bill.
  • PAUSEDFixed term ended — subscription:paused. Account remains; new bills stop.
  • CANCELLEDYou cancelled it. Event: subscription:cancelled.

Bill

One amount for one period — a payment in the API.

Store payment.id and payment_reference. LakiPay creates the invoice during subscribe (billing day) or on the schedule for active renewals.

  • INITIATEDInvoice exists — bill:created
  • PENDINGCheckout started — bill:processed
  • COMPLETEMoney collected — bill:paid
  • OVERDUEPast due — bill:overdue
  • FAILEDAttempt failed — bill:failed
  • CANCELLEDCancelled — bill:cancelled

bill:regenerated replaces a failed attempt; use the new payment.id.

Usage record

One data report or money amount for one subscription period.

Abel's October Flex usage is 12.5 GB. Align with billing_period_start / billing_period_end. Starter, Plus, and Pro do not need a usage record.

Manual payment bank

Your collection account shown for bank-transfer payers.

FiberHub's CBE account is one of these. status: ACTIVE means new receipts may name this account. Keep bank_code stable for reconciliation.

Manual payment

Proof a transfer was made for a specific bill — unpaid until approval.

  1. 1

    Bill exists and is unpaid

    Advance or arrears — the receipt does not care which.

  2. 2

    Customer transfers to an active bank

  3. 3

    Submit receipt

    Pending claim. Event: manual_payment:submitted. Bill still unpaid.

  4. 4

    Approve or reject

    Approve → bill paid (manual_payment:approved, same result as bill:paid). Reject → reason stored, bill stays unpaid.