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

# Payment Provider Setup

> Configure payment providers for your SaaS app

## Overview

CrediBill supports 4 African payment providers. Each provider has different requirements, coverage, and features. This guide walks through configuring each provider.

## Getting Started

### General Setup Process

1. **Get active merchant account** with provider
2. **Obtain API credentials** (keys, tokens, secrets)
3. **Configure webhook** in provider dashboard
4. **Add to CrediBill** via settings
5. **Test connection** before going live

### CrediBill Configuration Steps

1. Go to **Settings → Payment Providers**
2. Click **Add Provider**
3. Select provider from dropdown
4. Enter credentials
5. Choose environment (Test or Live)
6. Optionally set as primary provider
7. Click **Save & Test Connection**

## Flutterwave

### Coverage

| Attribute             | Details                                                    |
| --------------------- | ---------------------------------------------------------- |
| **Countries**         | Uganda, Kenya, Rwanda, Nigeria, Ghana, South Africa        |
| **Payment Methods**   | Mobile Money (MTN, Airtel, Tigo), Cards, Bank Transfer     |
| **Currencies**        | UGX, KES, RWF, NGN, GHS, ZAR, USD                          |
| **Webhook Signature** | SHA256 hash via `verif-hash` header                        |
| **Documentation**     | [Flutterwave Docs](https://developer.flutterwave.com/docs) |

### Setup Steps

#### 1. Create Account

1. Go to [Flutterwave Dashboard](https://dashboard.flutterwave.com/signup)
2. Complete business verification (KYC)
3. Wait for approval (1-3 business days)

#### 2. Get Credentials

**Test Mode:**

1. Log in to Flutterwave dashboard
2. Navigate to **Settings → API**
3. Copy "Public Key (Test)" - format: `FLWPUBK_TEST-xxx`
4. Copy "Secret Key (Test)" - format: `FLWSECK_TEST-xxx`

**Live Mode:**

1. Complete business verification
2. Get approval from Flutterwave support
3. Switch to Live mode in dashboard
4. Copy "Public Key (Live)" - format: `FLWPUBK-xxx`
5. Copy "Secret Key (Live)" - format: `FLWSECK-xxx`

#### 3. Configure Webhook

1. In Flutterwave dashboard, go to **Settings → Webhooks**
2. Set webhook URL to: `https://your-credibill-instance.com/webhooks/flutterwave`
3. Copy the webhook hash (this is your webhook secret)
4. Enable webhook notifications
5. Test webhook delivery

#### 4. Add to CrediBill

In CrediBill Dashboard → Settings → Payment Providers:

```
Provider: Flutterwave
Public Key: FLWPUBK_TEST-xxx (or live key)
Secret Key: FLWSECK_TEST-xxx (or live key)
Webhook Secret: [webhook hash from step 3]
Environment: Test or Live
Set as Primary: Yes/No
```

Click **Save & Test Connection**

### Testing

#### Test Cards

```
Visa (Success):
  Card Number: 5531886652142950
  CVV: 564
  Expiry: 09/32
  PIN: 3310
  OTP: 12345

Mastercard (Success):
  Card Number: 5531886652142950
  CVV: 564
  Expiry: 09/32
```

#### Test Mobile Money

**MTN Uganda (Success):**

```
Phone: +256772000000
Amount: Any amount
```

**Airtel Uganda (Success):**

```
Phone: +256700000000
Amount: Any amount
```

**Test Failure Scenarios:**

```
Insufficient Funds: +256772000001
Invalid Account: +256772000002
Declined: +256772000003
```

### Webhook Format

Flutterwave sends webhooks in this format:

```json theme={null}
{
  "event": "charge.completed",
  "data": {
    "id": 123456,
    "tx_ref": "your-transaction-reference",
    "flw_ref": "FLW-REF-ABC123",
    "amount": 50000,
    "currency": "UGX",
    "status": "successful",
    "payment_type": "mobilemoneyuganda",
    "customer": {
      "id": 123456,
      "email": "customer@example.com",
      "phone_number": "+256772123456",
      "name": "John Doe"
    },
    "created_at": "2024-01-15T10:30:00Z"
  }
}
```

### Troubleshooting

| Issue                        | Solution                                                                         |
| ---------------------------- | -------------------------------------------------------------------------------- |
| Test credentials not working | Verify environment is "Test", check for extra spaces in keys                     |
| Webhook not received         | Check webhook URL is accessible, verify firewall, enable in Flutterwave settings |
| Payment stuck pending        | May take 5-10 seconds, check Flutterwave dashboard                               |
| Signature mismatch           | Use exact webhook hash from Flutterwave, no modifications                        |

## PawaPay

### Coverage

| Attribute             | Details                                             |
| --------------------- | --------------------------------------------------- |
| **Countries**         | Uganda, Kenya, Tanzania, Rwanda, Zambia, Mozambique |
| **Payment Methods**   | Mobile Money only (MTN, Airtel, Tigo, Vodacom)      |
| **Currencies**        | UGX, KES, TZS, RWF, ZMW, MZN                        |
| **Webhook Signature** | HMAC-SHA256 via `X-Signature` header                |
| **Documentation**     | [PawaPay Docs](https://docs.pawapay.io/)            |

### Setup Steps

#### 1. Create Account

1. Contact PawaPay sales: [hello@pawapay.io](mailto:hello@pawapay.io)
2. Complete KYC (Know Your Customer) verification
3. Sign merchant agreement
4. Receive API credentials via email

#### 2. Get Credentials

**Test Mode:**

```
API Token: Bearer test_xxx
API URL: https://api.sandbox.pawapay.io
Deposit URL: https://api.sandbox.pawapay.io/deposits
```

**Live Mode:**

```
API Token: Bearer prod_xxx
API URL: https://api.pawapay.io
Deposit URL: https://api.pawapay.io/deposits
```

#### 3. Configure Webhook

1. Contact PawaPay support
2. Provide webhook URL: `https://your-credibill-instance.com/webhooks/pawapay`
3. Request webhook secret for signature verification
4. PawaPay will configure on their end and send you the secret

#### 4. Add to CrediBill

In CrediBill Dashboard → Settings → Payment Providers:

```
Provider: PawaPay
API Token: Bearer test_xxx (or prod_xxx)
API URL: https://api.sandbox.pawapay.io (test) or https://api.pawapay.io (live)
Webhook Secret: [secret from PawaPay]
Environment: Test or Live
Set as Primary: Yes/No
```

Click **Save & Test Connection**

### Testing

#### Test Mobile Money Numbers

**MTN Uganda (Instant Success):**

```
Phone: +256777000001
MSISDN: 256777000001
```

**MTN Uganda (Delayed Success \~5s):**

```
Phone: +256777000003
Result: Success after 5 seconds
```

**Airtel Kenya (Success):**

```
Phone: +254733000001
MSISDN: 254733000001
```

**Failed Transactions:**

```
Insufficient Funds: +256777000002
Invalid Account: +256777000004
```

### Webhook Format

PawaPay sends webhooks in this format:

```json theme={null}
{
  "depositId": "dep_abc123",
  "status": "COMPLETED",
  "requestedAmount": "50000",
  "depositedAmount": "50000",
  "currency": "UGX",
  "country": "UGA",
  "correspondent": "MTN_MOMO_UGA",
  "payer": {
    "type": "MSISDN",
    "address": "256777123456"
  },
  "created": "2024-01-15T10:30:00Z"
}
```

**Status values:** `PENDING`, `COMPLETED`, `FAILED`, `CANCELLED`

### Troubleshooting

| Issue                    | Solution                                                       |
| ------------------------ | -------------------------------------------------------------- |
| API authentication fails | Check API token has "Bearer " prefix, verify exact spacing     |
| Webhook secret invalid   | Contact PawaPay support for new secret, ensure copied exactly  |
| Test numbers don't work  | Use exact numbers above, wait 5+ seconds for delayed scenarios |
| Payment stuck pending    | PawaPay mobile money may take 1-5 minutes, check dashboard     |

## Pesapal

### Coverage

| Attribute             | Details                                                       |
| --------------------- | ------------------------------------------------------------- |
| **Countries**         | Kenya, Uganda, Tanzania, Rwanda, Malawi, Zambia               |
| **Payment Methods**   | Cards (Visa, Mastercard), Mobile Money (M-Pesa, Airtel, Tigo) |
| **Currencies**        | KES, UGX, TZS, RWF, MWK, ZMW, USD                             |
| **Webhook Signature** | OAuth + API verification                                      |
| **Documentation**     | [Pesapal Docs](https://developer.pesapal.com/)                |

### Setup Steps

#### 1. Create Account

1. Go to [Pesapal](https://www.pesapal.com/)
2. Register as merchant
3. Complete business verification (KYC)
4. Wait for approval

#### 2. Get Credentials

**Test Mode:**

1. Log in to Pesapal dashboard
2. Go to **Settings → API Integration**
3. Copy "Consumer Key (Demo)" - format: `qkio1BGGYAXTu2JOfm7XSXNruoZsrqEW`
4. Copy "Consumer Secret (Demo)" - format: `osGQ364R49cXKeOYSpaOnT++rHs=`

**Live Mode:**

1. Switch to Live mode in dashboard
2. Copy "Consumer Key (Live)"
3. Copy "Consumer Secret (Live)"

#### 3. Configure IPN (Webhook)

1. In Pesapal dashboard, go to **Settings → IPN**
2. Set IPN URL to: `https://your-credibill-instance.com/webhooks/pesapal`
3. Enable IPN notifications
4. Save settings

#### 4. Add to CrediBill

In CrediBill Dashboard → Settings → Payment Providers:

```
Provider: Pesapal
Consumer Key: qkio1BGGYAXTu2JOfm7XSXNruoZsrqEW (or live key)
Consumer Secret: osGQ364R49cXKeOYSpaOnT++rHs= (or live secret)
IPN URL: https://your-credibill-instance.com/webhooks/pesapal
Environment: Test or Live
Set as Primary: Yes/No
```

Click **Save & Test Connection**

### Testing

#### Test Cards

**Visa (Success):**

```
Card Number: 4111111111111111
CVV: 123
Expiry: 12/25
```

**Mastercard (Success):**

```
Card Number: 5500000000000004
CVV: 123
Expiry: 12/25
```

#### Test M-Pesa

```
Phone: +254722000000
PIN: Any 4 digits
Result: Success
```

#### Test Failure Scenarios

```
Insufficient Funds: 4000000000000002
Declined: 4000000000000069
Invalid Card: Any invalid number
```

### Webhook Format

Pesapal sends IPN (Instant Payment Notification) in this format:

```json theme={null}
{
  "OrderTrackingId": "abc-123-def-456",
  "OrderMerchantReference": "your-transaction-ref",
  "OrderNotificationType": "COMPLETED",
  "Status": "COMPLETED",
  "OrderAmount": "500.00",
  "OrderCurrency": "KES"
}
```

**Status values:** `COMPLETED`, `FAILED`, `CANCELLED`, `PENDING`

### Troubleshooting

| Issue                   | Solution                                                      |
| ----------------------- | ------------------------------------------------------------- |
| Credentials not working | Verify copy-paste accuracy, check for leading/trailing spaces |
| IPN not received        | Ensure HTTPS certificate is valid, check firewall             |
| Test cards declined     | Use exact numbers above, check expiry date format             |
| Integration fails       | Check OAuth credentials, verify IPN URL is HTTPS              |

## DPO (Direct Pay Online)

### Coverage

| Attribute             | Details                                           |
| --------------------- | ------------------------------------------------- |
| **Countries**         | Pan-Africa (40+ countries)                        |
| **Payment Methods**   | Cards (Visa, Mastercard, Amex), Mobile Money, EFT |
| **Currencies**        | Multiple African currencies + USD, EUR, GBP       |
| **Webhook Signature** | XML API verification with CompanyToken            |
| **Documentation**     | [DPO Docs](https://www.directpay.online/docs/)    |

### Setup Steps

#### 1. Create Account

1. Contact DPO sales: [https://www.directpay.online/](https://www.directpay.online/)
2. Complete merchant application
3. Provide business documentation
4. Wait for approval (3-5 business days)

#### 2. Get Credentials

**Test Mode:**

```
Company Token: 9F416C11-127B-4DE2-AC7A-D5E4E4CAA09C
Service Type: 3854
API URL: https://secure.3gdirectpay.com/
```

**Live Mode:**

```
Company Token: [Your unique token - provided by DPO]
Service Type: [Your service type - provided by DPO]
API URL: https://secure.3gdirectpay.com/
```

#### 3. Configure Callback URL

1. Log in to DPO merchant portal
2. Go to **Settings → Integration**
3. Set Callback URL: `https://your-credibill-instance.com/webhooks/dpo`
4. Save settings

#### 4. Add to CrediBill

In CrediBill Dashboard → Settings → Payment Providers:

```
Provider: DPO
Company Token: 9F416C11-127B-4DE2-AC7A-D5E4E4CAA09C (or live token)
Service Type: 3854 (or live service type)
API URL: https://secure.3gdirectpay.com/
Environment: Test or Live
Set as Primary: Yes/No
```

Click **Save & Test Connection**

### Testing

#### Test Cards

**Visa (Success):**

```
Card Number: 4000000000000002
CVV: 123
Expiry: 12/25
```

**Mastercard (Success):**

```
Card Number: 5200000000000007
CVV: 123
Expiry: 12/25
```

#### Test Mobile Money

```
Select MTN Mobile Money
Phone: Any valid number format
Result: Simulated success
```

#### Test Failure Scenarios

```
Approved: 4000000000000002
Declined: 4000000000000010
Insufficient Funds: 4000000000000028
```

### Webhook Format

DPO sends callbacks in XML format:

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<API3G>
  <CompanyToken>9F416C11-127B-4DE2-AC7A-D5E4E4CAA09C</CompanyToken>
  <Result>000</Result>
  <ResultExplanation>Transaction Paid</ResultExplanation>
  <TransactionToken>ABC-123-DEF</TransactionToken>
  <TransactionRef>your-transaction-reference</TransactionRef>
  <TransactionAmount>500.00</TransactionAmount>
  <TransactionCurrency>UGX</TransactionCurrency>
  <TransactionStatus>Paid</TransactionStatus>
  <TransactionDate>2024-01-15 10:30:00</TransactionDate>
</API3G>
```

**Result codes:** `000` (Paid), `001` (Failed), other codes for specific errors

### Troubleshooting

| Issue                  | Solution                                         |
| ---------------------- | ------------------------------------------------ |
| Company Token rejected | Verify token format, check for extra spaces      |
| Service Type incorrect | Use exactly "3854" for test, verify live type    |
| Callback not received  | Ensure callback URL has HTTPS, valid certificate |
| XML parsing error      | Check raw callback response format               |

## Multi-Provider Strategy

### Primary + Backup Setup

**Recommended configuration:**

1. Set one provider as **primary** (default for all payments)
2. Add second provider as **backup** for failover
3. CrediBill automatically fails over if primary unavailable

**Example:**

```
Primary: Flutterwave (best coverage in Uganda)
Backup: PawaPay (mobile money specialist)
```

### Country-Specific Routing

Route by customer country:

```
Uganda:
  Primary: Flutterwave
  Backup: PawaPay

Kenya:
  Primary: PawaPay
  Backup: Pesapal

Tanzania:
  Primary: PawaPay
  Backup: DPO

Multi-Country:
  Mobile Money: PawaPay (lowest fees)
  Cards: DPO (best coverage)
```

### Payment Method Routing

Route by payment method:

```
Mobile Money:
  Primary: PawaPay (lowest fees, fastest)
  Backup: Flutterwave (wide coverage)

Cards:
  Primary: DPO (pan-African)
  Backup: Pesapal (strong in East Africa)

Bank Transfer:
  Primary: Flutterwave (best support)
```

## Production Checklist

### Provider Setup

* [ ] Live merchant account created
* [ ] Business verification completed with provider
* [ ] Live API credentials obtained
* [ ] Webhook URL configured in provider dashboard
* [ ] Webhook signature verified working
* [ ] SSL/HTTPS certificate is valid
* [ ] Test connection succeeds in CrediBill

### CrediBill Configuration

* [ ] Environment set to **Live** (not Test)
* [ ] Primary provider configured
* [ ] Backup provider configured (optional)
* [ ] Webhook secret matches provider exactly
* [ ] No test data in production
* [ ] Error notifications configured

### Testing

* [ ] Test successful payment end-to-end
* [ ] Test failed payment and retry logic
* [ ] Test webhook delivery and signature verification
* [ ] Test multiple payment methods (if provider supports)
* [ ] Test idempotency (duplicate webhook handling)
* [ ] Monitor logs for first 24 hours

### Monitoring

* [ ] Payment success rate tracked (target: >95%)
* [ ] Webhook delivery monitored (target: 99.9%)
* [ ] Failed payments monitored
* [ ] Error alerts configured
* [ ] Provider status page monitored
* [ ] Daily reconciliation spot-checks

## Common Issues

### Test Credentials Not Working

**Cause:** Using test credentials in Live mode or vice versa

**Solution:**

* Double-check environment is "Test" in CrediBill
* Verify credentials are for test, not live
* Don't use live credentials in test environment

### Webhook Not Received

**Causes:**

* Webhook URL not publicly accessible
* HTTPS certificate invalid
* Firewall blocking provider IPs
* Provider disabled webhooks

**Solution:**

* Test webhook URL manually: `curl -X POST https://your-url.com/webhooks/provider`
* Check provider dashboard for webhook delivery logs
* Verify firewall rules
* Enable webhooks in provider settings

### Payment Stuck in Pending

**Cause:** Provider API slow response or webhook delivery delay

**Solution:**

* Check provider dashboard for payment status
* Wait 5-10 minutes for mobile money
* Check webhook logs for delivery attempts
* Contact provider support if stuck > 1 hour

### Signature Verification Fails

**Cause:** Webhook secret wrong or corrupted

**Solution:**

* Copy webhook secret again from provider dashboard
* Don't add/remove any characters
* Clear any extra spaces
* Test connection again in CrediBill

## Support

### Provider Support Contacts

* **Flutterwave:** [support@flutterwavego.com](mailto:support@flutterwavego.com)
* **PawaPay:** [hello@pawapay.io](mailto:hello@pawapay.io)
* **Pesapal:** [support@pesapal.com](mailto:support@pesapal.com)
* **DPO:** [support@directpay.online](mailto:support@directpay.online)

### CrediBill Support

* **Technical issues:** [support@credibill.tech](mailto:support@credibill.tech)
* **Integration help:** [integration@credibill.tech](mailto:integration@credibill.tech)
* **Billing questions:** [billing@credibill.tech](mailto:billing@credibill.tech)
