# Building a secure integration

> Where Ozow's security responsibility ends and yours begins: credentials, webhook endpoints, verifying notifications, and validating amounts.

Source: https://hub.ozow.com/getting-started/building-a-secure-integration/

Security is a shared responsibility between Ozow and you as the merchant. Understanding where Ozow's
responsibility ends and yours begins is essential to building an integration that is safe for your
customers and your business.

## The shared security model

Ozow secures the payment infrastructure. You secure how you integrate with it.

| Ozow is responsible for | You are responsible for |
|---|---|
| The security of the payment processing infrastructure | How you store and handle your API credentials |
| Encryption of payment data in transit and at rest within Ozow systems | The security of your callback and webhook endpoints |
| The integrity and availability of Ozow APIs | Verifying that notifications genuinely came from Ozow |
| Fraud monitoring within the Ozow platform | Validating transaction details before crediting orders |
| Physical and network security of Ozow's environments | Access controls on your systems and Ozow Dashboard |
| Compliance with applicable payment regulations on Ozow's side | Monitoring your own integration for anomalous activity |

A secure Ozow integration is not only about calling the right endpoints, it is about what happens on
your side of the connection too.

## Your security responsibilities

### Credentials and secrets

Your API credentials are the keys to your Ozow integration. If they are compromised, an attacker
could initiate payments or payouts on your behalf.

- Store all Ozow credentials, API keys, private keys, Client IDs, Client Secrets, and Payout API
  keys; in a secrets manager or environment variables. Never hardcode them or commit them to source
  control.
- Keep test and production credentials in strictly separate environments. Never use production
  credentials in a development or staging environment.
- Restrict access to production credentials to a named list of people and services. Access must be least-privilege.
- Have a documented process and a named owner for rotating credentials. Know what you would do if a
  key were compromised.

### Callback and webhook endpoint security

Ozow communicates payment outcomes by sending notifications to a URL you specify. This endpoint is a
critical part of your integration.

- Your callback and webhook URLs must be HTTPS only, using TLS 1.2 or later.
- Your endpoint must not expose stack traces, internal errors, or verbose logs in its response to callers.

### Verifying notifications

Receiving a notification is not the same as trusting it. You must verify that every notification
genuinely came from Ozow before acting on it.

- For Payments API integrations: verify every incoming notification using the hash check before
  updating any order status.
- For One API integrations: validate the message signature on every incoming webhook before acting
  on it.
- Log and alert on verification failures rather than silently discarding them. A pattern of
  verification failures is a signal worth investigating.
- Never mark a payment as complete based on the browser redirect alone. Always confirm status via
  the API or a verified webhook notification.
- Implement replay protection so that a previously processed transaction reference cannot be
  reprocessed to double-credit an order.

> ⚠️ **Important**: Ozow may occasionally send duplicate notifications for the same transaction.
> Your system must handle this gracefully, processing the same transaction twice must not result in
> double-crediting an order.

### Transaction integrity

Before crediting an order, validate that the payment details match what you originally requested.

- Verify that the amount, currency, and merchant reference in the notification match your original
  payment request.
- Handle duplicate notifications idempotently, receiving the same notification twice must have no
  additional effect.
- Periodically reconcile your order records against Ozow's transaction records rather than relying
  solely on webhook delivery.

### Payout-specific responsibilities

Payouts carry additional security requirements because they involve outgoing funds.

**Authorisation**

- For bulk payouts: Ozow recommends that the person who requests a bulk payout is different from the
  person who approves it. Ozow does not enforce this.
- For API payouts: access to the systems, credentials, and code that can trigger a payout must be
  restricted to a named list of people, with any changes requiring review.
- Your system must enforce a business-level authorisation step before calling Ozow's payout API.
  Being authenticated is not sufficient, there must be a deliberate approval within your own system
  before a payout is initiated.

**Beneficiary handling**

- Verify beneficiary bank details before the first payout to any new beneficiary.
- If you are not using stored beneficiary profiles, validate destination bank details on every
  payout request.
- Any change to stored beneficiary details must trigger a mandatory review or re-verification step
  before the next payout.
- Generate and persist a unique encryption key per payout request. Never reuse an encryption key
  across multiple payout requests.
- Enforce velocity and amount limits on payouts.
- Implement real-time alerting for anomalous payout activity, unusual amounts, unfamiliar
  beneficiaries, or off-hours activity are all signals worth acting on immediately.

**Verification request handling**

- Validate the access token on all incoming payout verification requests.
- Verify the hash on every verification request to confirm it genuinely originated from Ozow.
- Validate that the payout details in the verification request match a payout your system actually
  initiated: do not return a decryption key based on token and hash checks alone without confirming
  the payout is expected.

**Payout status verification**

- Confirm payout completion via the API, rather than assuming completion from the initial payout response.
- Verify the hash on every incoming payout status notification before trusting it.

### Access and monitoring

- Apply least-privilege access for all roles with access to your Ozow merchant Dashboard.
- Monitor for abnormal patterns in your payin traffic, spikes in failed verifications or unusual
  volumes are worth investigating.
- Maintain an immutable audit trail of who requested and who approved every payout, and when.
- Reconcile your internal ledger against Ozow's payout records on a regular cadence.

## Quick reference checklist

Use this checklist before going live with any Ozow integration.

### Payin integrations

- [ ] API credentials are stored securely and never hardcoded or committed to source control
- [ ] Test and production credentials are in strictly separate environments
- [ ] Production credentials are restricted to a named list of people and services
- [ ] Credential rotation process is documented with a named owner
- [ ] Callback URL is HTTPS only with TLS 1.2 or later
- [ ] Callback endpoint does not expose internal errors or stack traces
- [ ] Every notification is verified using hash check (Payments API) or message signature (One API)
  before being trusted
- [ ] Verification failures are logged and alerted on
- [ ] Payment status is confirmed via API, not the browser redirect alone
- [ ] Replay protection is in place for transaction references
- [ ] Amount, currency, and merchant reference are validated against the original request before crediting
- [ ] Duplicate notifications are handled idempotently
- [ ] Order records are periodically reconciled against Ozow transaction records
- [ ] Dashboard access follows least-privilege
- [ ] Monitoring is in place for anomalous payin traffic

### Payout integrations

- [ ] Payout API key is stored securely and never hardcoded or committed to source control
- [ ] Test and production payout credentials are in strictly separate environments
- [ ] Access to payout-triggering systems and code is restricted to a named list
- [ ] Bulk payout requestor and approver are different people (recommended, not enforced by Ozow)
- [ ] Business-level authorisation step is enforced before calling the payout API
- [ ] Beneficiary bank details are verified before the first payout to any new beneficiary
- [ ] A unique encryption key is generated and persisted per payout request
- [ ] Velocity and amount limits are enforced on payouts
- [ ] Real-time alerting is in place for anomalous payout activity
- [ ] Incoming verification requests are validated on token, hash, and expected payout details
- [ ] Payout completion is confirmed via API, not assumed from the initial response
- [ ] Payout status notifications are verified by hash before being trusted
- [ ] An immutable audit trail exists for every payout
- [ ] Internal ledger is reconciled against Ozow payout records regularly