Security

How payments and credentials are handled, and where in the software each control lives.

  • Card details never reach our servers.

    Payment is completed on the payment provider’s hosted page. We store the provider’s transaction reference and the outcome, and nothing that could be used to make a further charge.

    src/lib/gateway/*
  • An invoice is settled only by a server-to-server confirmation.

    The payer’s return to this site is treated as a request to display state, never as evidence of payment. The callback route is the only code path that marks an invoice paid.

    src/app/api/gateway/[provider]/callback/route.ts
  • A confirmed amount is checked against the invoice.

    A valid signature proves where a message came from, not that the sum agreed. A confirmation reporting a different amount than the one billed is recorded and refused rather than settled.

    src/lib/invoices/service.ts
  • API keys are stored hashed.

    Only a SHA-256 digest of each platform key is stored, so a copy of the database yields no usable credential. A lost key is rotated, never recovered.

    src/lib/api-key.ts
  • Administrator passwords are stored as salted scrypt hashes.

    Verification is constant-time, and the cost parameters are recorded with each hash so they can be raised.

    src/lib/password.ts
  • Outbound notifications are signed, and cannot be replayed.

    Each notification carries an HMAC-SHA256 signature over its body with the timestamp inside the signed material, so a captured request stops verifying once it falls outside the tolerance window.

    src/lib/webhooks/signature.ts
  • Billing the same period twice is prevented by the database.

    An invoice reference is unique per platform, so a retried request returns the invoice that already exists instead of issuing a second demand.

    src/db/schema/index.ts
  • Scheduled work is authenticated.

    The route that drives redelivery and expiry changes state, so it requires a secret rather than relying on an unguessable path.

    src/app/api/internal/cron/route.ts

Reporting a vulnerability

Email us with a description and, if you have one, a reproduction. We will acknowledge within two working days. Please do not test against live invoices belonging to other customers.