> ## 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.

# Relworx

> Configure Relworx mobile money collections, including the signed webhook that completes a payment.

# Collect payments with Relworx

`RELWORX` collects mobile money through the Relworx aggregator. Centipid Billing
posts a request, the payer authorizes it on their handset, and Relworx confirms
the result on a **signed webhook**.

Offered in the country catalog for **Kenya (KE)** and **Tanzania (TZ)**.

## Before you start

1. Complete Relworx merchant onboarding in an account owned by the ISP.
2. From the Relworx dashboard collect the **account number** (shown as
   `account_no`), the **API key**, and the **webhook signing key**.
3. Confirm your workspace has a public HTTPS domain — Relworx must reach the
   callback, and the callback is what completes a payment.

## Configure the gateway

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

  <Step title="Enter the account number">
    **Relworx account number** (required) is the `account_no` from your
    dashboard, not your merchant name.
  </Step>

  <Step title="Enter the API key">
    **Relworx API key** (required) authenticates outgoing payment requests.
  </Step>

  <Step title="Enter the webhook signing key">
    **Webhook signing key** (required, stored as a secret) verifies callbacks.
    Get it exactly right — see the warning below.
  </Step>

  <Step title="Run a controlled test payment">
    Pay a small amount from the captive portal and confirm both halves: the
    prompt arrives, **and** the payment appears in the ledger. A prompt that
    succeeds while the ledger stays empty means the webhook is being rejected.
  </Step>
</Steps>

## Credentials

| Field                  | Required | Notes                                         |
| ---------------------- | -------- | --------------------------------------------- |
| Relworx account number | Yes      | The `account_no` from your Relworx dashboard. |
| Relworx API key        | Yes      | Sent as a bearer token on every request.      |
| Webhook signing key    | Yes      | Secret. Verifies the callback signature.      |

## Callback URLs

Settings → Payments shows `https://<your-host>/api/payments/relworx/callback`.
Register it in your Relworx dashboard.

<Warning>
  Every callback must carry a valid `Relworx-Signature`. Centipid Billing
  recomputes an HMAC-SHA256 over the URL, the timestamp, and the reference and
  status fields, using your webhook signing key, and rejects the callback with
  HTTP 400 if it does not match — or if its timestamp is more than 10 minutes
  from now.

  A wrong signing key therefore fails silently in the worst possible way:
  **payers are charged and never provisioned**, because every confirmation is
  rejected. If test payments prompt but never land, suspect this key first.
</Warning>

## What the payer must provide

A mobile money number. It is normalized to international format using your
account's country before it is sent — numbers that cannot be normalized are
refused before any request reaches Relworx.

The currency is taken from the payment, then your configured currency, then your
country (`UG` → `UGX`, `KE` → `KES`, `TZ` → `TZS`). If none resolves to a
three-letter code, the request is refused rather than sent in the wrong currency.

## How a payment completes

<Steps>
  <Step title="Request">
    Centipid Billing posts the request to the Relworx API (v2), with a short
    timeout and two retries.
  </Step>

  <Step title="Authorization">
    The payer approves on their handset. The local transaction stays in progress.
  </Step>

  <Step title="Confirmation">
    Relworx calls the signed webhook. The signature is verified, the transaction
    matched on its customer or internal reference, and the payment recorded.
  </Step>
</Steps>

## Troubleshooting

| Symptom                                                        | What it means                                                                                                       | What to do                                                                                   |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| *"Relworx configuration incomplete. Please contact support."*  | One of the three fields is missing.                                                                                 | Complete all three in Settings → Payments.                                                   |
| *"Phone number format is invalid for Relworx payments."*       | The payer's number could not be normalized for your country.                                                        | Re-enter it in local or international format. Check your account's country is set correctly. |
| *"Currency configuration missing or unsupported for Relworx."* | No three-letter currency could be resolved.                                                                         | Set the currency on your account, or confirm the country is one Relworx supports.            |
| *"Unable to reach Relworx. Please try again later."*           | The request could not connect.                                                                                      | Check outbound connectivity from the application host.                                       |
| *"Relworx rejected the payment request."*                      | Relworx refused it — commonly bad credentials or an unsupported number.                                             | Verify the account number and API key against the dashboard.                                 |
| Prompts succeed, ledger stays empty                            | Callbacks are being rejected — usually a wrong webhook signing key, sometimes a URL that is not publicly reachable. | Re-copy the signing key, confirm the callback URL is registered and reachable, then re-test. |
| Callbacks rejected only intermittently                         | The webhook timestamp fell outside the 10-minute tolerance.                                                         | Check the clock on the application host.                                                     |

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