> ## Documentation Index
> Fetch the complete documentation index at: https://docs.centipidbilling.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Monnify

> Configure Monnify checkout for Nigerian bank transfers, cards, and USSD.

# Collect payments with Monnify

`MONNIFY` uses a **hosted checkout** offering bank transfer, card, and USSD.
Centipid Billing initializes a transaction, sends the payer to Monnify's
checkout page, and confirms the result on a signed webhook that is re-verified
against Monnify before anything is credited.

Offered in the country catalog for **Nigeria (NG)**.

## Before you start

1. Complete Monnify merchant onboarding in an account owned by the ISP.
2. From the Monnify dashboard collect the **API key**, the **secret key**, and
   the **contract code**.
3. Decide whether you are configuring **Live** or **Sandbox** — they are
   different hosts, and credentials are not interchangeable.
4. Plan the walled garden: the payer's browser must reach Monnify's checkout
   page, so a Hotspot subscriber who is not yet online cannot pay unless Monnify
   is reachable pre-authentication.

## Configure the gateway

<Steps>
  <Step title="Open Settings → Payments → Monnify">
    Select Monnify from the payment marketplace.
  </Step>

  <Step title="Enter the API key and secret key">
    Both are required and stored as secrets. The secret key does double duty: it
    authenticates requests **and** signs the webhook Monnify sends back.
  </Step>

  <Step title="Enter the contract code">
    **Contract code** (required) identifies the contract the money settles
    against.
  </Step>

  <Step title="Choose the environment">
    **Environment** is `Live` or `Sandbox`. Live requests go to
    `https://api.monnify.com`, sandbox to `https://sandbox.monnify.com`.
  </Step>

  <Step title="Register the webhook">
    See [Callback URLs](#callback-urls) below.
  </Step>

  <Step title="Run a controlled test payment">
    Pay a small amount from the captive portal on an unauthenticated device, and
    confirm the payment reaches the ledger.
  </Step>
</Steps>

## Credentials

| Field         | Required | Notes                                                   |
| ------------- | -------- | ------------------------------------------------------- |
| API key       | Yes      | Secret.                                                 |
| Secret key    | Yes      | Secret. Also signs the webhook.                         |
| Contract code | Yes      | From the Monnify dashboard.                             |
| Environment   | No       | `Live` or `Sandbox`. Decides which host requests go to. |

The API key, secret key, and contract code gate the switch; the environment does
not, so check it deliberately.

## Callback URLs

| Name         | Path                                       |
| ------------ | ------------------------------------------ |
| Webhook URL  | `https://<your-host>/api/monnify/callback` |
| Redirect URL | `https://<your-host>/api/monnify/return`   |

Register the webhook URL in the Monnify dashboard. The redirect is where the
payer's browser returns after checkout.

<Warning>
  Webhooks carry an HMAC-SHA512 `monnify-signature` computed with your **secret
  key**. A wrong secret key means every webhook is rejected with HTTP 400, so
  payers are charged and never provisioned.
</Warning>

## What the payer must provide

Whatever the Monnify checkout page asks for — card, bank transfer, or USSD. The
payer's name and email are sent with the request when known; when no email is
available a placeholder is sent so the transaction can be initialized, so do not
rely on the email shown in Monnify to identify a subscriber.

The currency is your account's configured currency, defaulting to `NGN`.

<Note>
  Amounts are sent in **naira**, not kobo. Monnify does not use the smallest
  unit here, so the ledger amount and the Monnify amount should match exactly —
  a factor-of-100 difference means something is wrong, not a unit convention.
</Note>

## How a payment completes

<Steps>
  <Step title="Initialize">
    Centipid Billing authenticates, initializes the transaction with the amount,
    reference, and contract code, and receives a checkout URL. A pending row is
    written against the payment reference.
  </Step>

  <Step title="Payment">
    The payer completes the payment on Monnify's page.
  </Step>

  <Step title="Confirmation">
    Monnify posts the signed webhook. The signature is validated, the result is
    then re-verified against the Monnify API, and only then is the payment
    recorded and the package applied. Repeated webhooks are ignored rather than
    double-credited.
  </Step>
</Steps>

## Troubleshooting

| Symptom                                                | What it means                                                                                              | What to do                                                                                                                                  |
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| *"Unable to process payment. Please try again later."* | Credentials are missing, authentication failed, or initialization was refused.                             | Check the API key, secret key, and contract code, and that the environment matches the credentials.                                         |
| Sandbox works, live does not                           | The environment still says `Sandbox`, or live credentials were pasted into a sandbox configuration.        | Change the environment and the credentials together.                                                                                        |
| The checkout page never loads on a Hotspot device      | The walled garden does not allow Monnify.                                                                  | Allow Monnify's checkout domain pre-authentication — see [Captive device cannot reach checkout](/billing/payment-gateways/troubleshooting). |
| Payments complete at Monnify, ledger stays empty       | Webhooks are being rejected — usually a wrong secret key, or a webhook URL that is not publicly reachable. | Re-copy the secret key, confirm the webhook URL is registered and reachable, then re-test.                                                  |
| *"Monnify payment verification failed"*                | The re-verification against Monnify did not confirm the payment.                                           | Check the transaction on the Monnify dashboard before recording anything by hand.                                                           |

For every gateway's fields in one place, see the
[credential reference](/billing/payment-gateways/credentials-reference).
