PHP / Laravel
Package avepay/mcf (Packagist)
Client au-dessus de Guzzle, PHP 8.1+. Payload friendly (calculs auto) + échappatoire brute. Intégration Laravel (ServiceProvider + Facade + config publishable).
composer require avepay/mcfCertifier une facture
use AvePay\AvePay;
use AvePay\AvePayError;
$avepay = new AvePay(getenv('AVEPAY_API_KEY'), ['isf' => '1']);
$mcf = $avepay->mcf('EL02000015-1');
$receipt = $mcf->certify([
'number' => 'FV-2026-0001',
'type' => 'FV', // FV | FT | EV | ET (défaut FV)
'operator' => ['id' => 1, 'name' => 'Awa'],
'customer' => ['type' => 'PP', 'name' => 'Client Comptant'],
'items' => [['name' => 'Riz 25kg', 'taxGroup' => 'B', 'unitPrice' => 15000, 'quantity' => 1]],
'payments' => [['method' => 'cash', 'amount' => 15000]],
]);
echo $receipt->sig; // signature SECEF (codeSecef)
echo $receipt->qr; // contenu QR
echo $receipt->totalTtc; // 15000
print_r($receipt->counters); // ['tc'=>…, 'fvc'=>…, 'frc'=>…]taxGroup déduit le taxRate (A = 0 %, B = 18 %) ; method accepte cash/transfer/card/mobile/cheque/other. Les clés brutes (et snake_case) sont aussi acceptées.
Avoir (credit note)
$avoir = $mcf->creditNote([
'number' => 'FA-2026-0001',
'from' => $receipt, // dérive creditNoteRef = "{nim}-{fvc}"
// ou: 'creditNoteRef' => 'EL02000015-1-291',
'creditNoteNature' => 'COR', // COR | RAN | RAM | RRR (défaut COR)
'operator' => ['id' => 1, 'name' => 'Awa'],
'customer' => ['type' => 'PP'],
'items' => [['name' => 'Riz 25kg', 'taxGroup' => 'B', 'unitPrice' => 15000]],
'payments' => [['method' => 'cash', 'amount' => 15000]],
]);Info · cancel-pending · me
$info = $mcf->info(); // McfInfo (mode, compteurs, marchand)
$mcf->cancelPending(); // annule une transaction 38h pendante
$me = $avepay->me(); // org + NIM scopés + état des bridgesGestion d'erreurs
try {
$mcf->certify($invoice);
} catch (AvePayError $e) {
echo $e->errorCode(); // BRIDGE_OFFLINE, NIM_NOT_IN_SCOPE, …
echo $e->httpStatus();
echo $e->getMessage();
echo $e->requestId();
if ($e->isBridgeOffline()) { /* MCF hors ligne */ }
}Retry réseau/5xx automatique (backoff + Idempotency-Key réutilisée entre tentatives).
Laravel
// php artisan vendor:publish --tag=avepay-config → config/avepay.php
use AvePay\Laravel\AvePay; // Facade
$receipt = AvePay::mcf('EL02000015-1')->certify([...]);Webhooks
$event = $avepay->webhooks()->verify($rawBody, $request->header('X-Avepay-Signature'));
// $event['type'] : "cert.issued" | "mcf.connected" | "mcf.disconnected"