elbrahms/ipaymoney

Un package Laravel complet pour intégrer la passerelle de paiement iPay Money (Mobile Money & Carte) en Afrique de l'Ouest.

Maintainers

Package info

github.com/Elbrahms05/ipaymoney

Homepage

pkg:composer/elbrahms/ipaymoney

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-07-31 20:09 UTC

This package is auto-updated.

Last update: 2026-07-31 20:10:08 UTC


README

Tests

Un package Laravel complet pour intégrer la passerelle de paiement iPay Money (Mobile Money & Carte bancaire) en Afrique de l'Ouest - Niger, Bénin, et autres pays de la zone XOF.

  • ✅ Création de paiements (Mobile Money & Carte)
  • ✅ Consultation du statut d'une transaction
  • ✅ Réception & vérification des webhooks (signature secret-hash)
  • ✅ Événements Laravel (PaymentSucceeded, PaymentFailed, WebhookReceived)
  • Persistance des transactions (modèle + migration, mise à jour auto par webhook)
  • Commande Artisan de test d'intégration (php artisan ipaymoney:test)
  • ✅ Bouton de checkout front-end (SDK JavaScript)
  • ✅ Environnements sandbox et live
  • ✅ Façade, auto-discovery, config publiable, tests inclus

Installation

composer require elbrahms/ipaymoney

Le package utilise l'auto-discovery Laravel. Publiez ensuite la configuration :

php artisan vendor:publish --tag=ipaymoney-config

Pour activer la persistance des transactions (optionnelle), publiez et exécutez la migration :

php artisan vendor:publish --tag=ipaymoney-migrations
php artisan migrate

Variables d'environnement

Ajoutez à votre fichier .env :

IPAYMONEY_ENVIRONMENT=sandbox           # sandbox | live
IPAYMONEY_SECRET_KEY=sk_xxxxxxxxxxxxx   # clé secrète (côté serveur)
IPAYMONEY_PUBLIC_KEY=pk_xxxxxxxxxxxxx   # clé publique (front / checkout)
IPAYMONEY_COUNTRY=NE                    # NE (Niger), BJ (Bénin), ...
IPAYMONEY_CURRENCY=XOF
IPAYMONEY_PAYMENT_TYPE=mobile           # mobile | card

# Webhook
IPAYMONEY_WEBHOOK_ENABLED=true
IPAYMONEY_WEBHOOK_PATH=ipaymoney/webhook
IPAYMONEY_WEBHOOK_SECRET=sk_xxxxxxxxxxxxx   # le "Secret Hash" du dashboard

# Persistance des transactions (optionnelle)
IPAYMONEY_RECORD_TRANSACTIONS=true
IPAYMONEY_TABLE=ipaymoney_transactions

⚠️ Ne partagez jamais votre clé secrète et ne la committez pas.

Vos clés sont disponibles dans votre dashboard iPay Money : Développeurs → Clés API.

Utilisation

1. Créer un paiement Mobile Money, MyNIta ou Amanata

use IPayMoney\Laravel\Facades\IPayMoney;
use IPayMoney\Laravel\Data\PaymentRequest;

$payment = IPayMoney::requestPayment(
    PaymentRequest::make()
        ->amount(1000)                 // montant > 100
        ->msisdn('40410000000')        // numéro du client
        ->transactionId('CMD-'.$order->id) // référence unique de VOTRE côté
        ->customerName('Amadou Diallo')
        ->country('NE')                // optionnel (défaut: config)
        ->mobile()                     // ->card() pour une carte
        //->MyNIta()
        //->Amanata()

);

if ($payment->isSuccessful()) {
    // Conservez la référence iPay Money pour le suivi
    $order->update(['ipay_reference' => $payment->reference]);
}

Vous pouvez aussi passer un simple tableau :

$payment = IPayMoney::requestPayment([
    'amount' => 1000,
    'msisdn' => '40410000000',
    'transaction_id' => 'CMD-42',
    'customer_name' => 'Amadou Diallo',
    'payment_type' => 'mobile',
]);

Réponse (PaymentResponse) :

Propriété Description
status Enum PaymentStatus (succeeded/failed/pending)
reference La référence générée par iPay Money
externalReference Votre transaction_id
msisdn Le numéro du client
isSuccessful() true si succeeded
isFailed() true si failed
isPending() true si pending

2. Consulter le statut d'un paiement

$status = IPayMoney::getPaymentStatus('vslfxgawkpkm');

if ($status->isSuccessful()) {
    // ...
}

3. Forcer un environnement à la volée

IPayMoney::usingEnvironment('live')->requestPayment(...);

Webhooks

iPay Money notifie votre serveur du résultat final d'une transaction. Le package enregistre automatiquement une route protégée par la vérification de signature.

  • URL par défaut : POST /ipaymoney/webhook (nommée ipaymoney.webhook)
  • Vérification : l'en-tête secret-hash est comparé, en temps constant, à config('ipaymoney.webhook.secret_hash').

Configurez cette URL dans votre dashboard iPay Money (Développeurs → Webhooks) et renseignez votre Secret Hash.

Excluez ce chemin de la protection CSRF (VerifyCsrfToken) - c'est déjà le cas si vous conservez le middleware api par défaut.

Écouter les événements

Dans un EventServiceProvider :

use IPayMoney\Laravel\Events\PaymentSucceeded;
use IPayMoney\Laravel\Events\PaymentFailed;

protected $listen = [
    PaymentSucceeded::class => [
        \App\Listeners\MarkOrderAsPaid::class,
    ],
    PaymentFailed::class => [
        \App\Listeners\NotifyPaymentFailure::class,
    ],
];

Exemple de listener :

use IPayMoney\Laravel\Events\PaymentSucceeded;

class MarkOrderAsPaid
{
    public function handle(PaymentSucceeded $event): void
    {
        $payment = $event->payment; // PaymentResponse

        Order::where('reference', $payment->externalReference)
            ->update([
                'status' => 'paid',
                'ipay_reference' => $payment->reference,
            ]);
    }
}

L'événement WebhookReceived est émis pour toute notification vérifiée (idéal pour la journalisation).

Checkout front-end (SDK JavaScript)

Pour un paiement redirigé (bouton de paiement iPay Money) dans une vue Blade :

{!! IPayMoney::checkout()
        ->amount(1000)
        ->transactionId('CMD-42')
        ->redirectUrl(route('checkout.done'))
        ->callbackUrl(route('ipaymoney.webhook'))
        ->label('Payer 1 000 XOF')
        ->button() !!}

{{-- Avant </body> --}}
{!! IPayMoney::checkout()->script() !!}

Rendu généré :

<button type="button" class="ipaymoney-button"
        data-amount="1000"
        data-environement="sandbox"
        data-key="pk_xxxxxxxxxxxxx"
        data-transaction-id="CMD-42"
        data-redirect-url="https://votre-app.test/checkout/done"
        data-callback-url="https://votre-app.test/ipaymoney/webhook">
    Payer 1 000 XOF
</button>
<script src="https://i-pay.money/checkout.js"></script>

Sandbox : numéros de test

En environnement sandbox, utilisez ces numéros pour simuler les scénarios :

MSISDN Scénario
40410000000 Succès
40410000001 Succès
40410000002 Erreur
40410000003 Erreur
40410000004 Fonds insuffisants
40410000005 Fonds insuffisants
40410000006 Refusé
40410000007 Refusé
40410000008 En attente (180 s)
40410000009 En attente (180 s)

Persistance des transactions

Le package peut enregistrer automatiquement chaque paiement en base de données via le modèle IPayMoneyTransaction.

Activez-la avec IPAYMONEY_RECORD_TRANSACTIONS=true (après avoir publié et exécuté la migration). Dès lors :

  • IPayMoney::requestPayment(...) crée une ligne (statut pending) puis la met à jour avec la réponse de l'API.
  • Les webhooks retrouvent la transaction (par reference puis transaction_id) et synchronisent son statut ainsi que paid_at.
use IPayMoney\Laravel\Models\IPayMoneyTransaction;

// Retrouver une transaction
$tx = IPayMoneyTransaction::where('transaction_id', 'CMD-42')->first();

$tx->isSuccessful();  // bool
$tx->status;          // Enum PaymentStatus
$tx->reference;       // référence iPay Money
$tx->amount;          // decimal
$tx->paid_at;         // Carbon|null
$tx->meta;            // dernier payload brut (array)

Table ipaymoney_transactions (colonnes principales) :

Colonne Description
transaction_id Votre référence (unique)
reference Référence générée par iPay Money
status pending / succeeded / failed
payment_type mobile / myNita / amanata / card
environment sandbox / live
amount, currency, country Montant et localisation
customer_name, msisdn Infos client
meta Dernier payload brut (JSON)
paid_at Horodatage du succès

La persistance est tolérante aux pannes : toute erreur de base de données est journalisée sans jamais faire échouer un paiement ni un webhook.

Le modèle est aussi utilisable manuellement, même sans activer l'option record, si vous préférez gérer l'enregistrement vous-même.

Commande Artisan de test d'intégration

Validez votre configuration de bout en bout (config → paiement sandbox → statut) sans écrire une ligne de code :

php artisan ipaymoney:test

Options :

php artisan ipaymoney:test \
    --msisdn=40410000004 \   # scénario "fonds insuffisants"
    --amount=250 \
    --type=mobile \          # mobile | myNita | amanata | card
    --no-status              # ne pas consulter le statut après création

La commande :

  1. vérifie la présence des clés (les affiche masquées) et l'environnement ;
  2. crée un paiement de test avec une référence unique auto-générée ;
  3. consulte le statut renvoyé et affiche un résumé coloré.

En mode live, la commande demande une confirmation avant de lancer un vrai paiement.

Gestion des erreurs

use IPayMoney\Laravel\Exceptions\PaymentException;
use IPayMoney\Laravel\Exceptions\ConfigurationException;

try {
    IPayMoney::requestPayment(...);
} catch (PaymentException $e) {
    $e->getMessage();  // message renvoyé par l'API
    $e->statusCode;    // code HTTP
    $e->response();    // corps brut décodé
} catch (ConfigurationException $e) {
    // clé secrète manquante, etc.
}

Injection de dépendance

La façade est pratique, mais vous pouvez aussi résoudre le client :

use IPayMoney\Laravel\IPayMoney;

public function pay(IPayMoney $ipay)
{
    return $ipay->requestPayment(...);
}

Tests

composer install
composer test

Référence API

Opération Méthode HTTP Endpoint
Créer un paiement POST /api/v1/payments
Statut d'un paiement GET /api/v1/payments/{reference}

En-têtes envoyés : Authorization: Bearer {clé secrète}, Ipay-Payment-Type, Ipay-Target-Environment, Content-Type: application/json.

Licence

MIT. Voir LICENSE.md.