# Mobile money payments API for developers

For developers

LonghoPay gives your server one request to create a hosted checkout, signed webhooks to learn the outcome, and a sandbox that behaves like the real networks. Your customers pay with MTN Mobile Money or Orange Money, and the money reaches the business you build for.

No merchant business, payout number or verification is needed to start. The sandbox costs nothing.

Order 1001

Two tickets for the Saturday departure.

Payment amount

FCFA 5,000

Mobile money number

655010010

Your name

Aisha N.

Optional info Email for your receipt

## What you get

### Hosted checkout

One authenticated request returns a checkout URL. The LonghoPay page handles the phone number, the fees and the approval on the customer’s handset.

### Signed webhooks

Payment succeeded, failed, processing and expired events, signed with HMAC-SHA256, retried with backoff and replayable from the portal.

### A real sandbox

A sandbox credential reaches a simulator. The payer number chooses the outcome, so you can rehearse a decline or a no-answer without a real phone.

### Logs, usage and status

Request logs, delivery history and API usage per application, plus a status read for the moments a webhook is late.

## How the pieces talk

Four calls and one webhook. The two dashed arrows are the ones that never prove a payment on their own.

## What your server sends

The same request in three languages. Keep the credential on the server; the browser only ever receives checkout_url.

## From account to first payment

Register and verify your email address.

Open your workspace and submit a sandbox application.

A platform administrator reviews and approves it.

Create a server credential and a webhook endpoint.

Integrate, rehearse in the sandbox, then go live with a production application.

## Integration guide, step by step

From an empty account to a live payment. Each step names the screen or the request it involves, and nothing in it assumes a merchant business already exists.

### 1. Create your developer account and open a workspace

Register with your name and email address, open the verification link and choose a password. Then open the developer portal and open your workspace. No merchant business, payout number or business verification is needed for any of this.

One person may hold both a merchant account and a developer workspace, but each is authorised separately: registering as a developer grants no access to any merchant’s payments.

### 2. Submit an application and wait for approval

In Applications, submit one application per environment. Start with a sandbox application: it reaches a simulated network, so nothing you do with it moves money.

A platform administrator reviews every application, sandbox and production alike. Until it is approved you cannot issue credentials or register webhooks. Changing the integration type, the return domains or the IP restrictions withdraws approval and asks for another review.

### 3. Create a server credential

Once approved, open API credentials and create a credential with only the scopes your server needs. For a hosted checkout that is payments:create, payments:read and webhooks:manage.

### 4. Create a checkout session from your server

Your website or app asks your server to start a payment. Your server records the order, then asks LonghoPay for a checkout session. Every request carries the credential as a Bearer token, a unique X-Request-ID, and an Idempotency-Key that you keep with the order.

Field

What it must be

The answer is 201 with the session under data. Store its id, external_reference, amount, currency, expires_at and checkout_url. The status starts as OPEN; payment_status and status_token stay null until a customer starts paying.

Retrying is safe. The same key with the same body returns the existing session, again with 201. The same key with a different amount, reference, return URL or metadata is refused with 409 IDEMPOTENCY_KEY_CONFLICT. After a timeout, retry with the original key and body, never with a new reference while the original is unresolved.

### 5. Send the customer to the checkout page

Redirect the customer’s browser to checkout_url. The LonghoPay page shows the amount and the fees, asks for the customer’s name and MTN or Orange number, and sends the approval request to their handset. Your credential is never used by the browser.

Once the payment has succeeded or failed, the page offers a button back to your return URL with longhopay_reference=<session id> appended. A customer arriving on that page is not proof of payment: look the order up in your own records and show what your backend knows.

### 6. Receive webhooks and verify their signature

In Webhooks, add an HTTPS endpoint subscribed at least to payment.succeeded and payment.failed; add payment.processing and payment.expired to follow the whole lifecycle. The signing secret is shown once, like a credential.

Read the raw bytes before parsing JSON. X-MobilePay-Signature is an HMAC-SHA256 over <timestamp>.<raw body>, keyed with the whole signing secret including its whsec_ prefix. Compare in constant time, reject a stale timestamp, and store the event id under a unique constraint so a redelivery is a no-op. Answer 2xx quickly and do the real work from your own queue.

If you would rather use a Standard Webhooks library, give it the signing_secret_standard value and let it verify the webhook-id, webhook-timestamp and webhook-signature headers instead. Verify one scheme completely; do not mix the two.

### 7. Confirm the payment and fulfil the order

A payment.succeeded event looks like this. Fields may be added; never removed.

Delivery is at least once: a failed delivery is retried up to seven times over roughly a day, and any event can be replayed from the portal. Your receiver must treat a duplicate as already handled.

### 8. Recover when a webhook does not arrive

Run a background check for orders still open past their expiry. Fetch the session with its token, then the payment status with the status_token the session returns.

What you see

What to do

Webhooks and this check can race. Both must go through the same fulfilment deduplication.

### 9. Rehearse in the sandbox

A sandbox credential reaches a simulator, never MTN or Orange. The outcome is scripted from the payer number typed on the checkout page.

Payer number

Outcome

To force the pending case to an ending, call the sandbox route with the payment reference, the trid from the status resource.

FAILED is the other accepted outcome. Rehearse success, decline, the unresolved payment, an unused session expiring, a lost response retried with the same key, a webhook outage and its replay, and duplicate or out-of-order events. Sandbox payments are never settled and never appear on any merchant’s dashboard.

### 10. Go live

The merchant owns the funds and the payouts. Revoking the authorisation stops new checkouts; payments already submitted still reach their recorded outcome.

### Errors and status codes

Branch on the HTTP status and the code field in the response, never on the message text.

Status

Meaning and action

A client timeout during a money command is an unknown outcome. Query by your stored reference, reuse the same idempotency key, and let the webhook or the status check settle it. Keep request_id from every response for support.

The complete OpenAPI specification can be downloaded from inside the developer portal.

## Start building today

Create your developer account, submit a sandbox application, and make your first test payment.
