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

# Enterprise Integration Guide

> Dedicated shortcodes, sub-merchants, and advanced routing for aggregators and high-volume merchants.

## Who this guide is for

Use this guide if you are an aggregator or a high-volume merchant that needs:

* Dedicated M-Pesa shortcode routing
* Sub-merchant level transaction attribution
* Advanced payout routing controls

<Info>
  If you do not need dedicated shortcode routing or sub-merchant attribution, use the standard endpoint payloads and only send required fields.
</Info>

## Integration paths

| Path                   | Best for                        | Payload style                |
| ---------------------- | ------------------------------- | ---------------------------- |
| Standard merchant path | Most merchants                  | Required fields only         |
| Enterprise path        | Aggregators and large merchants | Required + enterprise fields |

## Enterprise-only fields by endpoint

The table below lists fields marked with the <span style={{background: '#FEF3C7', color: '#92400E', padding: '2px 8px', borderRadius: '4px', fontSize: '12px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span> badge in the API reference.

| Endpoint                | Field                                                                                                                                                                                                            | Notes                                                             |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `POST /v1/mpesa/charge` | `shortcode` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>                   | Route via your dedicated collections shortcode                    |
| `POST /v1/mpesa/charge` | `subMerchantId` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>               | Auto-created on first use if missing; blocked only when suspended |
| `POST /v1/mpesa/charge` | `metadata.subMerchantDetails` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span> | Optional enrichment details for first-time auto-create            |
| `POST /v1/mpesa/b2c`    | `shortcode` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>                   | Route via your dedicated payouts shortcode                        |
| `POST /v1/mpesa/b2c`    | `subMerchantId` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>               | Auto-created on first use if missing; blocked only when suspended |
| `POST /v1/mpesa/b2c`    | `metadata.subMerchantDetails` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span> | Optional enrichment details for first-time auto-create            |
| `POST /v1/mpesa/b2b`    | `shortcode` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>                   | Route via your dedicated payouts shortcode                        |
| `POST /v1/mpesa/b2b`    | `subMerchantId` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>               | Auto-created on first use if missing; blocked only when suspended |
| `POST /v1/mpesa/b2b`    | `metadata.subMerchantDetails` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span> | Optional enrichment details for first-time auto-create            |
| `GET /v1/transactions`  | `shortcode` <span style={{background: '#FEF3C7', color: '#92400E', padding: '1px 6px', borderRadius: '4px', fontSize: '11px', fontWeight: 600, border: '1px solid #F59E0B'}}>ENTERPRISE</span>                   | Filter results by dedicated shortcode number                      |

<Warning>
  Do not send enterprise-only fields unless your integration requires them. Over-specifying optional fields is a common source of integration errors.
</Warning>

## End-to-end enterprise setup

<Steps>
  <Step title="Provision dedicated shortcodes">
    Work with Fingo to provision dedicated shortcode setup for your organization.

    * Collections traffic is routed through your collections shortcode.
    * Payout traffic is routed through your payouts shortcode.
  </Step>

  <Step title="Set up sub-merchants (if applicable)">
    You can pass `subMerchantId` directly in requests.

    * If the ID does not exist yet for your organization, Fingo auto-creates it in `active` state.
    * If the ID exists and is `suspended`, the request is rejected.
    * You can pass `metadata.subMerchantDetails` to enrich first-time auto-created records.

    Use your own internal sub-merchant identifiers consistently in requests.
  </Step>

  <Step title="Start with minimal payloads">
    Go live first with required fields only, then add enterprise-only fields where you need deterministic routing.
  </Step>

  <Step title="Add enterprise routing fields intentionally">
    Add `shortcode` and `subMerchantId` only on flows that require them.

    <Tip>
      Apply enterprise fields per transaction type, not globally across all requests.
    </Tip>
  </Step>

  <Step title="Verify webhook payloads and reconciliation">
    Verify webhook signatures, reconcile by `merchantTransactionId` and `transactionId`, and monitor failure reasons for optional-field misuse.

    <Tip>
      Use the `shortcode` query parameter on `GET /v1/transactions` to scope transaction queries to a specific dedicated shortcode. This is useful for reconciling traffic per shortcode without client-side filtering.
    </Tip>
  </Step>
</Steps>

## Request patterns

### C2B charge

<CodeGroup>
  ```bash Standard payload theme={"dark"}
  curl -X POST "https://api.fingopay.io/v1/mpesa/charge" \
    -H "Authorization: Bearer $FINGO_API_KEY" \
    -H "Idempotency-Key: 8b47872a-4de9-4c13-b73a-19803f55b1e4" \
    -H "Content-Type: application/json" \
    -d '{
      "merchantTransactionId": "invoice_48291",
      "amount": 150000,
      "phoneNumber": "+254712345678",
      "narration": "Invoice 48291"
    }'
  ```

  ```bash Enterprise payload theme={"dark"}
  curl -X POST "https://api.fingopay.io/v1/mpesa/charge" \
    -H "Authorization: Bearer $FINGO_API_KEY" \
    -H "Idempotency-Key: 90d24f95-7f17-4f65-83fa-7369e555b12a" \
    -H "Content-Type: application/json" \
    -d '{
      "merchantTransactionId": "invoice_48291_sm_001",
      "amount": 150000,
      "phoneNumber": "+254712345678",
      "narration": "Invoice 48291",
      "shortcode": "600123",
      "subMerchantId": "SM-NAIROBI-001",
      "metadata": {
        "subMerchantDetails": {
          "name": "Nairobi West Branch",
          "riskLevel": "medium"
        }
      }
    }'
  ```
</CodeGroup>

### B2C payout

<CodeGroup>
  ```bash Standard payload theme={"dark"}
  curl -X POST "https://api.fingopay.io/v1/mpesa/b2c" \
    -H "Authorization: Bearer $FINGO_API_KEY" \
    -H "Idempotency-Key: 2d95d474-2ef8-4446-b9cb-5d8b3401434d" \
    -H "Content-Type: application/json" \
    -d '{
      "merchantTransactionId": "payout_97233",
      "amount": 420000,
      "phoneNumber": "+254701234567",
      "narration": "Salary payout"
    }'
  ```

  ```bash Enterprise payload theme={"dark"}
  curl -X POST "https://api.fingopay.io/v1/mpesa/b2c" \
    -H "Authorization: Bearer $FINGO_API_KEY" \
    -H "Idempotency-Key: 3a4cab6d-ff57-4b03-b2cd-20f8cad65baa" \
    -H "Content-Type: application/json" \
    -d '{
      "merchantTransactionId": "payout_97233_sm_001",
      "amount": 420000,
      "phoneNumber": "+254701234567",
      "narration": "Salary payout",
      "shortcode": "600123",
      "subMerchantId": "SM-NAIROBI-001",
      "metadata": {
        "subMerchantDetails": {
          "name": "Nairobi West Branch",
          "riskLevel": "high"
        }
      }
    }'
  ```
</CodeGroup>

### B2B transfer

<CodeGroup>
  ```bash Standard payload theme={"dark"}
  curl -X POST "https://api.fingopay.io/v1/mpesa/b2b" \
    -H "Authorization: Bearer $FINGO_API_KEY" \
    -H "Idempotency-Key: 5a101014-d59d-4d0b-a9a8-fd3092ab28f3" \
    -H "Content-Type: application/json" \
    -d '{
      "merchantTransactionId": "b2b_4521",
      "amount": 2500000,
      "accountNumber": "1234567",
      "accountNumberType": "paybill",
      "beneficiary": "INV-12345",
      "narration": "Restock float"
    }'
  ```

  ```bash Enterprise payload theme={"dark"}
  curl -X POST "https://api.fingopay.io/v1/mpesa/b2b" \
    -H "Authorization: Bearer $FINGO_API_KEY" \
    -H "Idempotency-Key: 805d1c59-6c47-4ac6-9537-4ddfef438584" \
    -H "Content-Type: application/json" \
    -d '{
      "merchantTransactionId": "b2b_4521_sc_600123",
      "amount": 2500000,
      "accountNumber": "1234567",
      "accountNumberType": "paybill",
      "beneficiary": "INV-12345",
      "narration": "Restock float",
      "shortcode": "600123",
      "subMerchantId": "SM-NAIROBI-001",
      "metadata": {
        "subMerchantDetails": {
          "name": "Nairobi West Branch",
          "riskLevel": "low"
        }
      }
    }'
  ```
</CodeGroup>

## Common mistakes to avoid

* Sending dedicated `shortcode` values that do not belong to your organization
* Reusing idempotency keys with different request bodies
* Including optional routing fields in all requests by default

## Next steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="square-terminal" href="/api-reference/introduction">
    View endpoint-level field details and interactive playground.
  </Card>

  <Card title="Webhooks" icon="bell-ring" href="/webhooks">
    Verify signatures and handle webhook events.
  </Card>
</CardGroup>
