andydefer/php-pawapay

PHP SDK for integrating Pawapay Mobile Money payments (pay-ins, pay-outs, and webhooks) across African markets

Maintainers

Package info

github.com/andydefer/php-pawapay

pkg:composer/andydefer/php-pawapay

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.2.1 2026-07-16 21:45 UTC

README

SDK PHP pour l'intégration des paiements Mobile Money Pawapay à travers les marchés africains.

📖 Introduction

Qu'est-ce que Pawapay ?

Pawapay est une plateforme de paiement qui permet d'accepter des paiements via Mobile Money (M-Pesa, MTN MoMo, Orange Money, etc.) dans plus de 15 pays africains.

Ce que fait ce SDK

Ce SDK transforme les appels HTTP bruts vers l'API Pawapay en objets PHP typés, validés et documentés.

Pourquoi l'utiliser ?

Sans SDK Avec SDK
json_decode() manuel Objets PHP typés (DepositDataStruct)
Validation manuelle Value Objects (PhoneNumberVO, UuidVO)
String magiques Enums (Provider::MTN_MOMO_ZMB)
Code répétitif Builders fluides

🚀 Installation

composer require andydefer/php-pawapay

⚙️ Configuration

Créer le client

<?php

use AndyDefer\PhpPawapay\PawapayClient;
use AndyDefer\PhpPawapay\Enums\PawaPayBaseUrl;

$client = new PawapayClient(
    apiToken: 'eyJraWQiOiIxIiwiYWxnIjoiRVMyNTYifQ...',  // Votre token API
    baseUrl: PawaPayBaseUrl::SANDBOX  // ou PRODUCTION
);

💰 1. Initier un dépôt (Initiate Deposit)

Ce que fait cette route

Elle permet à un client de payer avec son Mobile Money. Vous envoyez le numéro de téléphone, le montant et le fournisseur, et Pawapay initie le paiement.

Endpoint

POST /v2/deposits

Étape 1 : Créer les Value Objects

<?php

use AndyDefer\PhpPawapay\ValueObjects\UuidVO;
use AndyDefer\PhpPawapay\ValueObjects\PhoneNumberVO;
use AndyDefer\PhpPawapay\ValueObjects\AmountVO;
use AndyDefer\PhpPawapay\ValueObjects\ReferenceVO;
use AndyDefer\PhpPawapay\ValueObjects\MessageVO;
use AndyDefer\PhpPawapay\ValueObjects\PayerVO;
use AndyDefer\PhpPawapay\ValueObjects\AccountDetailsVO;
use AndyDefer\PhpPawapay\ValueObjects\InitiateDepositVO;
use AndyDefer\PhpPawapay\Enums\Currency;
use AndyDefer\PhpPawapay\Enums\Provider;
use AndyDefer\PhpPawapay\Enums\PayerType;

// 1. Identifiant unique du dépôt (UUID v4)
$depositId = new UuidVO('f4401bd2-1568-4140-bf2d-eb77d2b2b639');

// 2. Numéro de téléphone du client (format international sans le +)
$phoneNumber = new PhoneNumberVO('260763456789');  // Zambie

// 3. Montant
$amount = new AmountVO(15.00);

// 4. Détails du compte Mobile Money
$accountDetails = new AccountDetailsVO(
    phoneNumber: $phoneNumber,
    provider: Provider::MTN_MOMO_ZMB  // MTN MoMo Zambie
);

// 5. Payeur
$payer = new PayerVO(
    type: PayerType::MMO,  // Mobile Money Operator
    accountDetails: $accountDetails
);

// 6. Créer le dépôt
$deposit = new InitiateDepositVO(
    depositId: $depositId,
    payer: $payer,
    amount: $amount,
    currency: Currency::ZMW,
    clientReferenceId: new ReferenceVO('INV-123456'),
    customerMessage: new MessageVO('Payment for order #123456')
);

Étape 2 : Envoyer la requête

$response = $client->initiateDeposit($deposit);

Étape 3 : Traiter la réponse

if ($response->isSuccess()) {
    // Succès (status 200)
    
    if ($response->isAccepted()) {
        echo "✅ Dépôt accepté !\n";
        echo "ID: " . $response->getDepositId() . "\n";       // f4401bd2-1568-...
        echo "Statut: " . $response->getStatus()->value;      // ACCEPTED
        echo "Créé: " . $response->getCreated();              // 2020-10-19T11:17:01Z
    
    } elseif ($response->isDuplicateIgnored()) {
        echo "⚠️ Dépôt dupliqué ignoré\n";
    }
    
} else {
    // Échec
    
    echo "❌ Échec du dépôt\n";
    echo "Statut: " . $response->getStatus()->value;  // REJECTED
    
    if ($response->hasFailureReason()) {
        $failure = $response->getFailureReason();
        echo "Code: " . $failure->failureCode;        // INVALID_PHONE_NUMBER
        echo "Message: " . $failure->failureMessage;  // The phone number '2607634'...
    }
}

Avec le Builder (recommandé)

Le builder rend le code plus lisible et réduit les erreurs :

$deposit = InitiateDepositBuilder::create()
    ->withAutoGeneratedDepositId()           // UUID automatique
    ->withPhoneNumber('260763456789')
    ->withProvider(Provider::MTN_MOMO_ZMB)
    ->withAmount(15.00)
    ->withCurrency(Currency::ZMW)
    ->withClientReferenceId('INV-123456')
    ->withCustomerMessage('Payment for order #123456')
    ->withMetadataKey('orderId', 'ORD-123456789')
    ->build();

🔍 2. Vérifier le statut d'un dépôt

Ce que fait cette route

Elle permet de savoir où en est un dépôt : accepté, en cours, terminé ou échoué.

Endpoint

GET /v2/deposits/{depositId}

Utilisation

<?php

use AndyDefer\PhpPawapay\Builders\CheckDepositStatusBuilder;

$response = CheckDepositStatusBuilder::create('your-api-token')
    ->withDepositId('60bd6a3d-177e-4ec2-a65c-d622ede29c99')
    ->execute();

if ($response->isFound()) {
    $data = $response->getDepositData();
    
    echo "Statut: " . $data->status->value;  // COMPLETED, PROCESSING, FAILED...
    
    if ($data->status->isCompleted()) {
        echo "✅ Le paiement a été confirmé !";
    } elseif ($data->status->isPending()) {
        echo "⏳ En attente de confirmation...";
    } elseif ($data->status->isFailed()) {
        echo "❌ Le paiement a échoué.";
        if ($data->failureReason !== null) {
            echo "Raison: " . $data->failureReason->failureMessage;
        }
    }
} else {
    echo "❌ Dépôt non trouvé";
}

Les statuts possibles

Statut Signification
ACCEPTED Dépôt accepté, en attente
PROCESSING En cours de traitement
IN_RECONCILIATION En réconciliation
COMPLETED ✅ Terminé avec succès
FAILED ❌ Échoué
REJECTED ❌ Rejeté

🔄 3. Renvoyer un callback de dépôt

Ce que fait cette route

Si votre serveur n'a pas reçu le webhook de confirmation, vous pouvez demander à Pawapay de le renvoyer.

Endpoint

POST /v2/deposits/resend-callback/{depositId}

Utilisation

<?php

use AndyDefer\PhpPawapay\Builders\ResendDepositCallbackBuilder;

$response = ResendDepositCallbackBuilder::create('your-api-token')
    ->withDepositId('9b724dbf-32a7-4e63-96bb-59a4747e43ca')
    ->execute();

if ($response->isAccepted()) {
    echo "✅ Callback renvoyé avec succès !";
} else {
    echo "❌ Échec";
    $failure = $response->getFailureReason();
    echo "Code: " . $failure->failureCode;   // NOT_FOUND ou INVALID_STATE
    echo "Message: " . $failure->failureMessage;
}

📄 4. Créer une page de paiement

Ce que fait cette route

Elle génère une URL vers une page de paiement Pawapay que vous pouvez rediriger votre client vers.

Endpoint

POST /v2/paymentpage

Utilisation

<?php

use AndyDefer\PhpPawapay\Builders\CreatePaymentPageBuilder;
use AndyDefer\PhpPawapay\Enums\Currency;
use AndyDefer\PhpPawapay\Enums\Country;
use AndyDefer\PhpPawapay\Enums\Language;

$response = CreatePaymentPageBuilder::create('your-api-token')
    ->withAutoGeneratedDepositId()
    ->withPhoneNumber('243827833329')           // RDC
    ->withAmount(24.60)
    ->withCurrency(Currency::USD)
    ->withReturnUrl('https://example.com/success')
    ->withLanguage(Language::FR)
    ->withCountry(Country::COD)
    ->withCustomerMessage('Paiement commande')
    ->withReason('Commande #12345')
    ->execute();

if ($response->isSuccess()) {
    $redirectUrl = $response->getRedirectUrl();
    // Rediriger le client vers cette URL
    header('Location: ' . $redirectUrl);
    exit;
}

🧩 Les Value Objects

Les Value Objects sont des classes qui valident les données au moment de leur création.

VO Validation Exemple
UuidVO Format UUID v4 new UuidVO('f4401bd2-...')
PhoneNumberVO Format E.164 sans + new PhoneNumberVO('260763456789')
AmountVO Positif, numérique new AmountVO(15.00)
ReferenceVO String new ReferenceVO('INV-123456')
MessageVO String, max 22 caractères new MessageVO('Payment')
MetadataVO 10 champs max, valeurs scalaires new MetadataVO($data)

🌍 Enums disponibles

Enum Valeurs Exemple
Provider Fournisseurs Mobile Money Provider::MTN_MOMO_ZMB
Currency Devises Currency::ZMW, Currency::USD
Country Pays Country::ZMB, Country::COD
Language Langues Language::EN, Language::FR
DepositStatus Statuts de dépôt DepositStatus::COMPLETED
PawaPayBaseUrl URL de base PawaPayBaseUrl::SANDBOX

❌ Gestion des erreurs

Exemple complet

try {
    $response = $client->initiateDeposit($deposit);
    
    if ($response->isSuccess()) {
        // Traitement du succès
        return;
    }
    
    if ($response->hasFailureReason()) {
        $failure = $response->getFailureReason();
        
        // Gestion par code d'erreur
        switch ($failure->failureCode) {
            case 'INVALID_PHONE_NUMBER':
                // Demander à l'utilisateur de corriger son numéro
                break;
                
            case 'AUTHENTICATION_ERROR':
                // Vérifier votre token API
                break;
                
            case 'PROVIDER_TEMPORARILY_UNAVAILABLE':
                // Réessayer plus tard
                break;
                
            default:
                // Erreur inconnue
                break;
        }
    }
    
} catch (Exception $e) {
    // Erreur réseau ou exception inattendue
    Log::error('Pawapay error: ' . $e->getMessage());
}

📝 Exemples concrets par pays

Zambie - MTN MoMo

$deposit = InitiateDepositBuilder::create()
    ->withAutoGeneratedDepositId()
    ->withPhoneNumber('260763456789')
    ->withProvider(Provider::MTN_MOMO_ZMB)
    ->withAmount(15.00)
    ->withCurrency(Currency::ZMW)
    ->build();

RDC - Vodacom MPesa (USD)

$deposit = InitiateDepositBuilder::create()
    ->withAutoGeneratedDepositId()
    ->withPhoneNumber('243812345678')
    ->withProvider(Provider::VODACOM_MPESA_COD)
    ->withAmount(25.50)
    ->withCurrency(Currency::USD)
    ->build();

Kenya - M-Pesa

$deposit = InitiateDepositBuilder::create()
    ->withAutoGeneratedDepositId()
    ->withPhoneNumber('254712345678')
    ->withProvider(Provider::MPESA_KEN)
    ->withAmount(100.00)
    ->withCurrency(Currency::KES)
    ->build();

Nigeria - MTN MoMo

$deposit = InitiateDepositBuilder::create()
    ->withAutoGeneratedDepositId()
    ->withPhoneNumber('2348034567890')
    ->withProvider(Provider::MTN_MOMO_NGA)
    ->withAmount(5000.00)
    ->withCurrency(Currency::NGN)
    ->build();

📄 Licence

MIT © Andy Defer