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

# Pay a Bill / Top-up

> Pay a bill (SenEau, Senelec) or top up a prepaid meter (Woyofal)

# Pay a Bill / Top-up

Settles a bill (SenEau, Senelec) or performs a prepaid top-up (Woyofal). The amount is **debited from your account balance** (bill amount + your service `FEE`).

<Warning>
  The debit only happens **after the provider accepts** the operation. On failure, no debit is applied (or an automatic refund is issued for asynchronous top-ups).
</Warning>

## Endpoint

```bash theme={null}
POST /api/v1/billing/pay
```

## Headers

| Name          | Type   | Required | Description           |
| ------------- | ------ | -------- | --------------------- |
| Authorization | string | Yes      | Bearer YOUR\_API\_KEY |
| Content-Type  | string | Yes      | application/json      |

## Request Body

```json theme={null}
{
  "serviceCode": string,              // Biller code
  "reference_client": string,         // Meter number / customer reference
  "amount": number,                   // Required for Woyofal (customer-chosen)
  "reference_facture": string,        // Optional: target a specific bill
  "externalTransactionId": string,    // Optional: your unique reference
  "callBackURL": string,              // Optional: notification URL
  "customData": string                // Optional
}
```

### Parameters

| Parameter             | Type   | Required | Description                                                                        |
| --------------------- | ------ | -------- | ---------------------------------------------------------------------------------- |
| serviceCode           | string | Yes      | `SENEAU_SN_BILL`, `SENELEC_SN_BILL` or `WOYOFAL_SN_BILL`                           |
| reference\_client     | string | Yes      | Meter number / police / customer reference                                         |
| amount                | number | Woyofal  | Top-up amount. **Required for Woyofal**; ignored for SenEau/Senelec (bill-imposed) |
| reference\_facture    | string | No       | Target a specific bill. Otherwise the first unpaid bill is settled                 |
| externalTransactionId | string | No       | Your unique identifier (idempotency)                                               |
| callBackURL           | string | No       | Webhook notification URL                                                           |
| customData            | string | No       | Free data echoed back in the callback                                              |

<Note>
  **Amount**: for SenEau and Senelec the amount is **imposed** by the bill (`amount` is ignored). For Woyofal (prepaid top-up) the customer **chooses** the amount via `amount`.
</Note>

## Response

### Bill paid (SenEau / Senelec — synchronous)

```json theme={null}
{
  "message": "Bill paid successfully",
  "transaction": {
    "success": true,
    "transactionId": "TID123456789",
    "externalTransactionId": "INV-001",
    "transactionType": "BILL",
    "amount": 104500,
    "transactionFee": 1045,
    "number": "210278816",
    "referenceFacture": "8000000680",
    "Status": "SUCCESS",
    "previousBalance": 500000,
    "currentBalance": 394455
  }
}
```

### Top-up successful (Woyofal — immediate token)

```json theme={null}
{
  "message": "Bill paid successfully",
  "transaction": {
    "success": true,
    "transactionId": "TID987654321",
    "transactionType": "BILL",
    "amount": 1000,
    "transactionFee": 10,
    "number": "07061270877",
    "token": "1283930093209223",
    "Status": "SUCCESS",
    "currentBalance": 498990
  }
}
```

<Note>
  **`token`** = recharge code to enter on the meter. Present only for prepaid top-ups (Woyofal).
</Note>

### Top-up processing (Woyofal — asynchronous)

If the provider does not confirm immediately, the transaction goes to `PROCESSING`. The token is delivered once resolved (available via webhook / transaction history).

```json theme={null}
{
  "message": "Bill paid successfully",
  "transaction": {
    "success": true,
    "transactionId": "TID987654321",
    "transactionType": "BILL",
    "amount": 1000,
    "Status": "PROCESSING",
    "message": "Top-up in progress — token available shortly"
  }
}
```

<Warning>
  For a `PROCESSING` top-up that ultimately fails, the debited amount (amount + fee) is **automatically refunded** to your balance and a `FAILED` callback is sent.
</Warning>

### Error Response

```json theme={null}
{
  "message": "Failed to pay bill",
  "transaction": {
    "success": false,
    "Status": "FAILED",
    "message": "Insufficient balance"
  }
}
```

## Error Codes

| HTTP Code | Description                                                 |
| --------- | ----------------------------------------------------------- |
| 400       | Invalid parameters, insufficient balance, bill already paid |
| 401       | Invalid API key                                             |
| 403       | API under maintenance                                       |
| 409       | externalTransactionId already used                          |

## Request Examples

### Pay a Senelec bill

```bash theme={null}
curl -X POST https://api-m.dexchange.sn/api/v1/billing/pay \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "serviceCode": "SENELEC_SN_BILL",
    "reference_client": "210278816",
    "externalTransactionId": "INV-001",
    "callBackURL": "https://your-domain.com/callback"
  }'
```

### Top up a Woyofal meter

```bash theme={null}
curl -X POST https://api-m.dexchange.sn/api/v1/billing/pay \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "serviceCode": "WOYOFAL_SN_BILL",
    "reference_client": "07061270877",
    "amount": 1000,
    "externalTransactionId": "RCH-001",
    "callBackURL": "https://your-domain.com/callback"
  }'
```

## Notification Webhook

As with regular transactions, a webhook is sent to `callBackURL` on status change (`SUCCESS` / `FAILED`):

```json theme={null}
{
  "id": "TID123456789",
  "externalTransactionId": "INV-001",
  "transactionType": "BILL",
  "AMOUNT": 104500,
  "FEE": 1045,
  "PHONE_NUMBER": "210278816",
  "STATUS": "SUCCESS",
  "COMPLETED_AT": "2024-03-20T10:35:00Z",
  "PREVIOUS_BALANCE": 500000,
  "CURRENT_BALANCE": 394455
}
```


## OpenAPI

````yaml POST /api/v1/billing/pay
openapi: 3.0.1
info:
  title: DEXCHANGE-API
  description: >-
    Unifiez tous vos paiements mobiles à travers une seule API puissante.
    DEXCHANGE-API est une passerelle de paiement qui regroupe plusieurs wallets
    (Orange Money, Wave, Free Money, Wizall) sur une seule API, simplifiant
    l'intégration des paiements mobiles en Afrique de l'Ouest.
  version: 1.0.0
  contact:
    name: DEXCHANGE Support
    email: team@dexchange.sn
    url: https://docs-api.dexchange.sn
  license:
    name: MIT
servers:
  - url: https://api-m.dexchange.sn
    description: Production Server
security:
  - bearerAuth: []
tags:
  - name: Transactions
    description: Operations for managing payment transactions
  - name: Merchant
    description: Merchant-specific payment operations
  - name: Services
    description: Service and balance information
  - name: Billing
    description: Bill payment and prepaid top-up operations
paths:
  /api/v1/billing/pay:
    post:
      tags:
        - Billing
      summary: Payer une facture / Recharger
      description: >-
        Règle une facture (SenEau, Senelec) ou effectue une recharge prépayée
        (Woyofal). Le montant est débité du solde (montant + FEE).
      operationId: billingPay
      requestBody:
        description: Détails du paiement
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BillingPayRequest'
        required: true
      responses:
        '201':
          description: Paiement effectué (ou recharge en cours)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BillingPayResponse'
        '400':
          description: Solde insuffisant, facture déjà payée, ou paramètres invalides
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    BillingPayRequest:
      type: object
      required:
        - serviceCode
        - reference_client
      properties:
        serviceCode:
          type: string
          enum:
            - SENEAU_SN_BILL
            - SENELEC_SN_BILL
            - WOYOFAL_SN_BILL
          description: Code du biller
          example: SENELEC_SN_BILL
        reference_client:
          type: string
          description: Numéro de compteur / police / référence client
          example: '210278816'
        amount:
          type: number
          description: >-
            Montant à recharger. Requis pour Woyofal ; ignoré pour
            SenEau/Senelec (montant imposé).
          example: 104500
        reference_facture:
          type: string
          description: >-
            Optionnel : cible une facture précise. Sinon la 1re impayée est
            réglée.
        externalTransactionId:
          type: string
          description: 'Optionnel : votre référence unique (idempotence)'
          example: INV-001
        callBackURL:
          type: string
          description: 'Optionnel : URL de notification webhook'
        customData:
          type: string
          description: Optionnel
    BillingPayResponse:
      type: object
      properties:
        message:
          type: string
          example: Bill paid successfully
        transaction:
          $ref: '#/components/schemas/BillingTransaction'
    Error:
      type: object
      properties:
        message:
          type: array
          items:
            type: string
        success:
          type: boolean
      required:
        - message
        - success
    BillingTransaction:
      type: object
      properties:
        success:
          type: boolean
          example: true
        transactionId:
          type: string
          example: TID123456789
        externalTransactionId:
          type: string
          example: INV-001
        transactionType:
          type: string
          example: BILL
        amount:
          type: number
          example: 104500
        transactionFee:
          type: number
          example: 1045
        number:
          type: string
          example: '210278816'
        referenceFacture:
          type: string
          example: '8000000680'
        token:
          type: string
          nullable: true
          description: Code de recharge (Woyofal) à saisir sur le compteur
          example: '1283930093209223'
        Status:
          type: string
          enum:
            - SUCCESS
            - PROCESSING
            - FAILED
          example: SUCCESS
        previousBalance:
          type: number
          example: 500000
        currentBalance:
          type: number
          example: 394455
        message:
          type: string
          description: Présent pour les recharges en cours (PROCESSING) ou les échecs
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'Entrez votre clé API comme: Bearer <API_KEY>'

````