loanref

package
v1.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: AGPL-3.0 Imports: 3 Imported by: 0

Documentation

Overview

Package loanref generates and validates short loan references.

A loan reference is the only binding between a paybill payment and the loan it repays. It is typed by the borrower on a feature phone, read aloud over the phone, and resolved by C2B validation and C2B Hakikisha before a database is ever consulted. Every property of the format follows from those three constraints: it is short, read-aloud safe, non-enumerable, and carries a check character so a mistyped reference fails in milliseconds rather than after a round trip.

The format is a 2-character prefix, 6 random Crockford base32 characters, and 1 check character — 9 characters total, three under Daraja's 12-character AccountReference cap.

Index

Constants

View Source
const DefaultPrefix = "MV"

DefaultPrefix is used when none is configured.

Variables

This section is empty.

Functions

func Generate

func Generate(prefix string) (string, error)

Generate produces a new reference under prefix, sourcing randomness from crypto/rand so references are not enumerable. The previous format embedded a millisecond timestamp in hex; that made the reference space searchable, which is unacceptable now that the reference alone binds a payment to a loan.

Generate does not check uniqueness against the database: the caller inserts under a unique index and retries on conflict. At 6 random characters the birthday bound is comfortable for years, so a conflict is rare and a bounded retry turns it into a second attempt rather than a 500.

func GenerateDeterministic

func GenerateDeterministic(prefix string, seed [16]byte) (string, error)

GenerateDeterministic produces a reference derived from a fixed seed, used by the backfill migration so a re-run produces the same reference for the same row rather than a new random one. It is not for new loans: two seeds that differ produce uncorrelated references, but the same seed always produces the same one.

func Validate

func Validate(prefix, ref string) bool

Validate reports whether ref is a well-formed reference under prefix: right length, all characters in the alphabet, and a correct check character. A value that fails Validate never reaches a database lookup.

func ValidatePrefix

func ValidatePrefix(prefix string) error

ValidatePrefix rejects any prefix that is not exactly prefixLen characters from the Crockford alphabet. The confusables I, L, O and U are excluded deliberately: a prefix that allows them reintroduces the misreading the alphabet exists to prevent, on a value that is read aloud and typed on a feature phone. A wrong value is a configuration error and must fail startup, not the first repayment.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL