The Billing Engine charges gym members through several payment processors, across card, ACH and cash, on schedules that retry when a payment fails.
It is GymRevenue's client-end billing module: membership fee calculation, invoice generation, payment processing, and subscription management, for a business whose revenue arrives in more than one shape.
Problem
A gym does not have one way of taking money. Membership is recurring and dated. The counter sells inventory, services, and subscriptions in the moment. Service agreements carry their own terms, their own billing dates, and their own annual dues. Each of those ends in a payment, and each payment can fail for reasons the gym did not cause and cannot see.
Handling them separately means the same arithmetic for fees, tax, and retries written more than once, in places that then disagree.
Constraints
No single payment processor could be assumed. The module had to work against several vendors, which rules out building the billing logic around any one vendor's model of a transaction.
Sales tax is a function of where the sale happened, and the rates change without asking. A rate compiled into the system is a rate that is wrong at some point after release.
A failed payment is not an error to log and move past. It is money the business is owed, so every attempt has to leave a record that a human can act on later.
Approach
Vendor support is a seam rather than a branch: the module speaks to multiple payment processors, and to card, ACH, and cash, through the same billing path.
Recurring payments and billing run on the schedule the agreement sets. Failures fall to automated retries first, and to a manual retry when a person needs to intervene. Late fees are calculated on the same schedule, automatically, so the fee and the charge it is attached to are never computed by two different rules.
Sales tax is applied by location and updated automatically, which is the only shape that survives a rate change.
Payment status and payment attempts are tracked as separate things, because a payment that eventually succeeded after three attempts is a different fact from a payment that succeeded.
Outcome
One module covers membership fee calculation, invoice generation, payment processing, and subscription management, with recurring billing, retries, late fees, and location-based tax handled in the same place rather than repeated per sales path.