silylink/laravel

SDK Laravel officiel pour l'API marchande SilyLink (checkout, charges, transfers, payouts, webhooks).

Maintainers

Package info

gitlab.com/sily-link/plugins/laravel

Issues

pkg:composer/silylink/laravel

Transparency log

Statistics

Installs: 26

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.0 2026-07-19 19:32 UTC

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 que composer require fonctionne sans dépôt path/vcs local.

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.

ModeActivationUsage typique
Client HTTPToujours disponibleContrôle total, sans magie Laravel
Facadefeatures.facade = true (défaut)DX rapide : SilyLink::checkout()->create(…)
EloquentSILYLINK_ELOQUENT=true + migratePersistance 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\Charge
  • SilyLink\Laravel\Models\Transfer
  • SilyLink\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éthodeClient / Facade
Infos marchand->account()->info()
Application->account()->application($accessCode?)
Transactions->account()->transactions(['per_page' => 25])

Checkout

MéthodeClient / 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éthodeClient / 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éthodeClient / Facade
Vérifier->transfers()->check($payload)
Demander->transfers()->request($payload)
Consulter->transfers()->show($requestId)

Payouts — permission payout

MéthodeClient / 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_code est 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.phpwebhook.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 :

EventDéclenché quand
SilyLink\Laravel\Events\CheckoutPaidCheckout payé
SilyLink\Laravel\Events\ChargeUpdatedStatut charge (pending / succeeded / …)
SilyLink\Laravel\Events\TransferUpdatedStatut transfer
SilyLink\Laravel\Events\PayoutUpdatedStatut 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) :

HTTPException typique
401AuthenticationException
403ForbiddenException
404NotFoundException
409ConflictException
422ValidationException
autreSilyLinkException
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