silylink / laravel
SDK Laravel officiel pour l'API marchande SilyLink (checkout, charges, transfers, payouts, webhooks).
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.8
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/routing: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
This package is not auto-updated.
Last update: 2026-07-20 19:09:28 UTC
README
Package Composer officiel pour intégrer SilyLink (paiements, checkout, charges, transfers, payouts) dans une application Laravel.
Prérequis
- PHP
^8.2 - Laravel
^11|^12|^13 - Une application marchande SilyLink avec :
SLK-Api-Key(slk_test_…/slk_live_…)encryption_password(secret HMAC)access_code(requis pour Charges, Transfers, Payouts)
Installation
Via Packagist :
composer require silylink/laravel
Le package doit être publié sur Packagist et tagué (
v1.0.0, etc.) pour quecomposer requirefonctionne sans dépôtpath/vcslocal.
Publier la config :
php artisan vendor:publish --tag=silylink-config
Si vous activez le mode Eloquent (Cashier-like) :
php artisan vendor:publish --tag=silylink-migrations
php artisan migrate
Configuration
Variables d’environnement (.env) :
SILYLINK_API_BASE_URL=https://api.silylink.com/api/v1
SILYLINK_API_KEY=slk_live_xxxxxxxx
SILYLINK_ENCRYPTION_PASSWORD=votre_secret_hmac
SILYLINK_ACCESS_CODE=123456
# Fonctionnalités (toutes optionnelles sauf le client HTTP)
SILYLINK_ELOQUENT=false
SILYLINK_WEBHOOK_ROUTE=true
Fichier config/silylink.php (extrait) :
return [
'api_base_url' => env('SILYLINK_API_BASE_URL'),
'api_key' => env('SILYLINK_API_KEY'),
'encryption_password' => env('SILYLINK_ENCRYPTION_PASSWORD'),
'access_code' => env('SILYLINK_ACCESS_CODE'),
'features' => [
'facade' => true, // SilyLink::…
'eloquent' => env('SILYLINK_ELOQUENT', false), // modèles locaux
'webhook_route' => env('SILYLINK_WEBHOOK_ROUTE', true), // POST /silylink/webhook
],
'webhook' => [
'path' => '/silylink/webhook',
'middleware' => [],
],
];
Trois modes d’intégration
Le package est conçu en couches. Vous choisissez le niveau qui vous convient — les trois coexistent.
| Mode | Activation | Usage typique |
|---|---|---|
| Client HTTP | Toujours disponible | Contrôle total, sans magie Laravel |
| Facade | features.facade = true (défaut) | DX rapide : SilyLink::checkout()->create(…) |
| Eloquent | SILYLINK_ELOQUENT=true + migrate | Persistance locale + sync via webhooks |
flowchart LR
App[Votre app Laravel]
Client[SilyLinkClient]
Facade[Facade SilyLink]
Models[Modeles Eloquent]
API[API SilyLink]
App -->|mode client| Client
App -->|mode facade| Facade --> Client
App -->|mode eloquent| Models --> Client
Client --> API
1. Client HTTP pur
Aucune route, aucune migration. Idéal pour les microservices ou les jobs.
use SilyLink\Laravel\Client\SilyLinkClient;
$client = app(SilyLinkClient::class);
$session = $client->checkout()->create([
'amount' => 50000, // GNF, entier
'order_id' => 'ORD-1001',
'description' => 'Commande #1001',
'return_url' => 'https://monsite.com/paiement/retour',
'cancel_url' => 'https://monsite.com/paiement/annule',
'notify_url' => 'https://monsite.com/silylink/webhook',
]);
return redirect($session['payment_url']);
2. Facade (recommandé pour démarrer)
use SilyLink\Laravel\Facades\SilyLink;
$session = SilyLink::checkout()->create([
'amount' => 50000,
'order_id' => 'ORD-1001',
'notify_url' => url('/silylink/webhook'),
'options' => [
'customer' => [
'firstname' => 'Jean',
'lastname' => 'Diallo',
'email' => 'jean@example.com',
'tel' => '620000000',
],
],
]);
// Suivi
SilyLink::checkout()->session($session['operation_id']);
SilyLink::checkout()->order('ORD-1001');
// Compte
SilyLink::account()->info();
SilyLink::account()->transactions(['per_page' => 25]);
3. Eloquent (style Cashier)
Activez SILYLINK_ELOQUENT=true, publiez et lancez les migrations.
use SilyLink\Laravel\Models\Payment;
$payment = Payment::createCheckout([
'amount' => 50000,
'order_id' => 'ORD-1001',
'notify_url' => url('/silylink/webhook'),
]);
// Colonnes locales : operation_id, payment_url, status, amount, order_id, …
return redirect($payment->payment_url);
Le webhook met à jour automatiquement status et déclenche les events Laravel (voir ci-dessous).
Même principe pour :
SilyLink\Laravel\Models\ChargeSilyLink\Laravel\Models\TransferSilyLink\Laravel\Models\Payout
Authentification & signature HMAC
Toutes les requêtes envoient SLK-Api-Key.
Les méthodes mutantes (POST, PUT, PATCH, DELETE) ajoutent :
SLK-HMAC-Signature: <hmac_sha256_hex>
Calcul (identique au serveur SilyLink) :
hash_hmac('sha256', $rawBody, $encryptionPassword);
Le package signe le corps JSON exact envoyé — ne re-sérialisez jamais le payload après signature côté custom.
Surface API
Préfixe distant : {SILYLINK_API_BASE_URL} (ex. …/api/v1).
Account
| Méthode | Client / Facade |
|---|---|
| Infos marchand | ->account()->info() |
| Application | ->account()->application($accessCode?) |
| Transactions | ->account()->transactions(['per_page' => 25]) |
Checkout
| Méthode | Client / Facade |
|---|---|
| Créer une session | ->checkout()->create($payload) |
Lire par operation_id | ->checkout()->session($operationId) |
Lire par order_id | ->checkout()->order($orderId) |
Payload typique create :
[
'amount' => 50000, // requis, entier ≥ 1 (GNF)
'order_id' => 'ORD-1001', // optionnel
'description' => '…',
'fee_handling' => 'deduct', // deduct | add
'return_url' => 'https://…',
'cancel_url' => 'https://…',
'notify_url' => 'https://…', // webhooks
'options' => [/* customer, auto-redirect, … */],
]
Charges (Pull) — permission charge
| Méthode | Client / Facade |
|---|---|
| Vérifier | ->charges()->check($payload) |
| Demander | ->charges()->request($payload) |
| Consulter | ->charges()->show($requestId) |
| Confirmer OTP | ->charges()->confirm($requestId, ['onetime_pin' => '1234']) |
Transfers (Push) — permission transfer
| Méthode | Client / Facade |
|---|---|
| Vérifier | ->transfers()->check($payload) |
| Demander | ->transfers()->request($payload) |
| Consulter | ->transfers()->show($requestId) |
Payouts — permission payout
| Méthode | Client / Facade |
|---|---|
| Settings | ->payouts()->settings() |
| Mettre à jour | ->payouts()->updateSettings($payload) |
| Lister demandes | ->payouts()->requests(['filter' => 'unpaid']) |
| Créer demande | ->payouts()->createRequest($payload) |
| Consulter | ->payouts()->showRequest($id) |
| Annuler | ->payouts()->cancelRequest($id) |
access_codeest lu depuis la config (SILYLINK_ACCESS_CODE). Vous pouvez le surcharger par appel si besoin.
Webhooks
Route intégrée (opt-in)
Par défaut, le package enregistre :
POST /silylink/webhook
Désactiver :
SILYLINK_WEBHOOK_ROUTE=false
Ou personnaliser le chemin dans config/silylink.php → webhook.path.
Important : exclure cette route du CSRF dans votre app Laravel :
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'silylink/webhook',
]);
})
Vérification manuelle
use SilyLink\Laravel\Webhooks\WebhookVerifier;
use Illuminate\Http\Request;
public function __invoke(Request $request, WebhookVerifier $verifier)
{
$payload = $verifier->verify($request); // lève une exception si signature invalide
// $payload['operation_id'] | $payload['request_id'] | $payload['status']
}
La vérification utilise le corps brut ($request->getContent()), jamais un json_encode reconstruit.
Events Laravel
Écoutez-les dans un EventServiceProvider / AppServiceProvider :
| Event | Déclenché quand |
|---|---|
SilyLink\Laravel\Events\CheckoutPaid | Checkout payé |
SilyLink\Laravel\Events\ChargeUpdated | Statut charge (pending / succeeded / …) |
SilyLink\Laravel\Events\TransferUpdated | Statut transfer |
SilyLink\Laravel\Events\PayoutUpdated | Statut payout |
use SilyLink\Laravel\Events\CheckoutPaid;
Event::listen(CheckoutPaid::class, function (CheckoutPaid $event) {
// $event->payload, $event->payment (si eloquent)
});
Idempotence
SilyLink peut renvoyer plusieurs webhooks pour la même opération. Utilisez operation_id ou request_id comme clé d’idempotence côté métier.
Exemples rapides
Charge (Pull)
use SilyLink\Laravel\Facades\SilyLink;
$check = SilyLink::charges()->check([
'amount' => 12000,
'payment_channel' => 'orange_money',
'account_number' => '620000000',
'account_name' => 'Jean Diallo',
]);
$charge = SilyLink::charges()->request([
'amount' => 12000,
'payment_channel' => 'orange_money',
'account_number' => '620000000',
'notify_url' => url('/silylink/webhook'),
'order_id' => 'ORD-CHARGE-1',
]);
// Si OTP requis :
SilyLink::charges()->confirm($charge['request_id'], [
'onetime_pin' => '123456',
]);
Transfer (Push)
SilyLink::transfers()->request([
'amount' => 10000,
'payment_channel' => 'orange_money',
'account_number' => '620000000',
'account_name' => 'Mohamed Diallo',
'notify_url' => url('/silylink/webhook'),
]);
Payout
SilyLink::payouts()->createRequest([
'application_pin' => '4321',
'payout_amount' => 100000,
'note' => 'Versement hebdo',
]);
Gestion des erreurs
Les erreurs API sont levées sous forme d’exceptions typées (namespace SilyLink\Laravel\Exceptions) :
| HTTP | Exception typique |
|---|---|
| 401 | AuthenticationException |
| 403 | ForbiddenException |
| 404 | NotFoundException |
| 409 | ConflictException |
| 422 | ValidationException |
| autre | SilyLinkException |
try {
SilyLink::checkout()->create(['amount' => 50000]);
} catch (\SilyLink\Laravel\Exceptions\ValidationException $e) {
// $e->getMessage(), $e->errors()
}
Canaux de paiement
Selon le produit (charge / transfer), les canaux courants incluent notamment :
paycard, orange_money, mtn_momo, cc, kulu, soutra_money, wave, cash (transfers).
La disponibilité réelle dépend de votre compte marchand et de la configuration SilyLink.
Développement local (ce dépôt)
composer install
vendor/bin/pest
Lier le package dans une app Laravel de test (composer.json de l’app) :
{
"repositories": [
{
"type": "path",
"url": "../Plugins/LARAVEL"
}
],
"require": {
"silylink/laravel": "*"
}
}
composer update silylink/laravel
Licence
MIT — © SilyLink