More

Security

How payments, phones and keys are protected.

Payments#

  • One MoMo Transaction ID can verify one payment — enforced by unique constraints and serializable transactions with row locks.
  • SMS are accepted only from configured MoMo sender IDs; phone-number senders (spoofing attempts) are rejected.
  • Admin decisions are final and audited; review reasons explain every non-automatic case.

Relay phones#

  • Each phone gets its own secret at pairing (single-use, 10-minute code). Secrets are encrypted at rest with DEVICE_SECRET_KEY.
  • Every request is signed with HMAC-SHA256 over timestamp, nonce, method, path and body hash; stale timestamps and repeated nonces are rejected.
  • Revoking a phone takes effect immediately and the app unpairs itself.
  • The app can be locked with a PIN, password or biometrics.

API & dashboard#

  • API keys are stored as SHA-256 hashes and shown once; rotation is immediate.
  • Admin sessions use httpOnly, secure cookies plus a custom header check; login is rate-limited.
  • Webhooks are signed and timestamped.
  • Public payment pages expose only what the payer needs and are rate-limited.

Your infrastructure#

  • All data — SMS, payments, customers — stays in your PostgreSQL database on your server.
  • Postgres and the API listen on loopback only; nginx terminates TLS.
  • Nightly database backups (gzipped SQL, 14 days) are kept on the server — copy them off-site.