scell / sdk
SDK PHP officiel pour l'API Scell.io - Facturation electronique (Factur-X/UBL/CII) et signature electronique (eIDAS EU-SES)
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.0
- psr/http-message: ^1.0 || ^2.0
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^9.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^11.0
Suggests
- illuminate/support: Required for Laravel integration (^11.0 || ^12.0)
README
SDK PHP officiel pour l'API Scell.io - Facturation electronique (Factur-X/UBL/CII) et signature electronique (eIDAS EU-SES).
Features
- Facturation electronique conforme (Factur-X, UBL 2.1, UN/CEFACT CII)
- Signature electronique simple (eIDAS EU-SES)
- Gestion multi-tenant (sub-tenants, factures directes et entrantes)
- Conformite fiscale ISCA (integrite, clotures, FEC, attestations)
- Statistiques et facturation plateforme
- Integration Laravel native avec auto-discovery
- Builders fluent pour factures et signatures
- Verification HMAC-SHA256 des webhooks
- Retry automatique avec backoff exponentiel
- DTOs types et Enums PHP 8.2+
- Gestion d'erreurs complete
Installation
composer require scell/sdk
Configuration
Variables d'environnement
# API SCELL_BASE_URL=https://api.scell.io/api/v1 SCELL_API_KEY=tk_live_... # Optionnel - Pour le dashboard (Bearer token) SCELL_BEARER_TOKEN=eyJ... # Webhooks SCELL_WEBHOOK_SECRET=whsec_...
Utilisation Standalone
Client API (integration backend)
Pour les integrations serveur-a-serveur avec API Key:
use Scell\Sdk\ScellApiClient; use Scell\Sdk\DTOs\Address; use Scell\Sdk\Enums\AuthMethod; // Initialisation $api = ScellApiClient::withApiKey('tk_live_...'); // Mode sandbox pour les tests $api = ScellApiClient::sandbox('tk_test_...');
Creer une facture
use Scell\Sdk\DTOs\Address; $invoice = $api->invoices()->builder() ->externalId('my-internal-id') ->outgoing() ->facturX() ->issueDate(new DateTime()) ->dueDate((new DateTime())->modify('+30 days')) ->seller( siret: '12345678901234', name: 'Ma Societe SARL', address: new Address( line1: '1 Rue de la Paix', postalCode: '75001', city: 'Paris' ) ) ->buyer( siret: '98765432109876', name: 'Client SA', address: new Address( line1: '2 Avenue du Commerce', postalCode: '69001', city: 'Lyon' ) ) ->addLine('Prestation de conseil', 10, 100.00, 20.0) ->addLine('Formation', 2, 500.00, 20.0) ->archiveEnabled() ->create(); echo "Facture creee: {$invoice->id}"; echo "Total TTC: {$invoice->totalTtc} EUR"; > **Note:** Invoice and credit note numbers are automatically generated by Scell.io. Draft documents receive a temporary number (DRAFT-XXXXX-00001), and the definitive fiscal number (XXXXX-YYYYMM-00001) is assigned at submission.
Facturation internationale
Pour les parties non-francaises, le SIRET n'est pas requis. Utilisez les numeros de TVA pour les entreprises EU et legal_id avec un code de schema pour les entreprises hors-EU.
Facture avec acheteur belge (EU)
$invoice = $client->invoices()->create([ 'issue_date' => '2026-03-29', 'due_date' => '2026-04-28', 'currency' => 'EUR', // Vendeur francais (SIRET requis) 'seller_siret' => '12345678901234', 'seller_name' => 'Ma Société SAS', 'seller_country' => 'FR', 'seller_vat_number' => 'FR12345678901', 'seller_address' => ['line1' => '10 rue de Paris', 'postal_code' => '75001', 'city' => 'Paris', 'country' => 'FR'], // Acheteur belge (pas de SIRET, numero de TVA) 'buyer_name' => 'Entreprise Belge SPRL', 'buyer_country' => 'BE', 'buyer_vat_number' => 'BE0123456789', 'buyer_address' => ['line1' => '15 Avenue Louise', 'postal_code' => '1050', 'city' => 'Bruxelles', 'country' => 'BE'], 'lines' => [ ['description' => 'Consulting services', 'quantity' => 10, 'unit_price' => 150.00, 'vat_rate' => 0], ], 'format' => 'ubl', ]);
Note : Pour les transactions B2B intra-communautaires (ex: FR -> BE, FR -> DE), le taux de TVA est generalement 0% via le mecanisme d'autoliquidation. L'acheteur comptabilise la TVA dans son propre pays.
Facture avec acheteur UK (hors-EU)
Pour les acheteurs hors-EU, utilisez buyer_legal_id et buyer_legal_id_scheme en plus du numero de TVA :
$invoice = $client->invoices()->create([ 'issue_date' => '2026-03-29', 'due_date' => '2026-04-28', 'currency' => 'GBP', 'seller_siret' => '12345678901234', 'seller_name' => 'Ma Société SAS', 'seller_country' => 'FR', 'seller_vat_number' => 'FR12345678901', 'seller_address' => ['line1' => '10 rue de Paris', 'postal_code' => '75001', 'city' => 'Paris', 'country' => 'FR'], // Acheteur UK — legal_id avec schema 'buyer_name' => 'British Ltd', 'buyer_country' => 'GB', 'buyer_vat_number' => 'GB123456789', 'buyer_legal_id' => '12345678', 'buyer_legal_id_scheme' => '0088', 'buyer_address' => ['line1' => '20 Baker Street', 'postal_code' => 'W1U 3BW', 'city' => 'London', 'country' => 'GB'], 'lines' => [ ['description' => 'Design services', 'quantity' => 5, 'unit_price' => 200.00, 'vat_rate' => 0], ], 'format' => 'ubl', ]);
Creer une signature
use Scell\Sdk\Enums\AuthMethod; $signature = $api->signatures()->builder() ->title('Contrat de prestation') ->description('Contrat annuel de maintenance') ->externalId('contract-2024-001') ->documentFromFile('/path/to/contract.pdf') ->addEmailSigner('Jean', 'Dupont', 'jean.dupont@example.com') ->addSmsSigner('Marie', 'Martin', '+33612345678') ->addSignaturePosition(page: 5, x: 100, y: 700, width: 200, height: 50) ->uiConfig([ 'sidebar_logo' => 'https://example.com/logo.png', 'sidebar_background_color' => '#0066CC', ]) ->redirectUrls( completeUrl: 'https://example.com/signed', cancelUrl: 'https://example.com/cancelled' ) ->expiresAt((new DateTime())->modify('+7 days')) ->create(); echo "Signature creee: {$signature->id}"; echo "Statut: {$signature->status->label()}"; // Recuperer les URLs de signature foreach ($signature->signers as $signer) { echo "{$signer->fullName()}: {$signer->signingUrl}"; }
White-label avance + options de signature (v1.12.0)
$signature = $api->signatures()->builder() ->title('Contrat NDA') ->documentFromFile('/path/to/nda.pdf') ->addEmailSigner('Jean', 'Dupont', 'jean@example.com', message: 'Bonjour, votre code OTP : {OTP}') ->addSignaturePosition(page: 1, x: 70, y: 85, width: 20, height: 5, unit: 'percent') ->uiConfig([ 'sidebar_logo' => 'https://cdn.example.com/logo.svg', 'sidebar_background_color' => '#0F172A', 'sidebar_text_color' => '#FFFFFF', 'hide_branding' => true, 'iframe_ancestors' => ['https://app.example.com'], ]) ->signatureOptions([ 'signature_mode' => 'both', // 'draw' | 'type' | 'both' 'signer_must_read' => true, 'user_editable_data' => false, 'timezone' => 'Europe/Paris', ]) ->create();
Client Dashboard (Bearer token)
Pour les operations via le dashboard utilisateur:
use Scell\Sdk\ScellClient; $client = new ScellClient($bearerToken); // Lister les factures $invoices = $client->invoices()->list([ 'direction' => 'outgoing', 'status' => 'validated', 'per_page' => 50, ]); foreach ($invoices->data as $invoice) { echo "{$invoice->invoiceNumber}: {$invoice->totalTtc} EUR"; } // Pagination if ($invoices->hasNextPage()) { $nextPage = $client->invoices()->list(['page' => $invoices->nextPage()]); } // Consulter le solde $balance = $client->balance()->get(); echo "Solde: {$balance->formatted()}"; if ($balance->isLow()) { echo "Attention: solde bas!"; } // Gerer les entreprises $companies = $client->companies()->list(); // Gerer les webhooks $webhooks = $client->webhooks()->list();
Onboarder un nouveau partenaire (SuperPDP OAuth2)
Le flow d'onboarding intègre SuperPDP pour gérer l'inscription, le KYB et la vérification d'identité de vos utilisateurs dans une popup. Une fois le flow complété, Scell provisionne automatiquement un tenant pour l'utilisateur.
use Scell\Sdk\ScellApiClient; $api = ScellApiClient::withApiKey('tk_live_...'); // Étape 1 : Créer une session d'onboarding $session = $api->onboarding()->createSession([ 'partner_ref' => 'mon-id-utilisateur-interne', 'redirect_url' => 'https://monapp.com/onboarding/complete', ]); // Étape 2 : Obtenir l'URL d'autorisation SuperPDP $auth = $api->onboarding()->getSuperPDPAuthorizeUrl($session->id); // Ouvrir $auth['authorize_url'] dans un popup côté frontend // SuperPDP gère l'inscription, le KYB et la vérification d'identité // Étape 3 : Réceptionner le callback SuperPDP (code + state) $result = $api->onboarding()->superpdpCallback( sessionId: $session->id, code: $request->input('code'), state: $request->input('state'), ); if ($result['success']) { $tenant = $result['tenant']; echo "Tenant enrôlé : {$tenant['name']} — SIRET {$tenant['siret']}"; // $tenant : ['id', 'name', 'siret', 'environment'] } // Consulter le statut d'une session $status = $api->onboarding()->getSession($session['id']);
| Méthode | Endpoint | Description |
|---|---|---|
createSession(array $input) |
POST /onboarding/sessions |
Créer une session d'onboarding |
getSession(string $id) |
GET /onboarding/sessions/:id |
Consulter le statut d'une session |
getSuperPDPAuthorizeUrl(string $sessionId) |
POST /onboarding/superpdp/authorize |
Obtenir l'URL OAuth2 SuperPDP |
superpdpCallback(string $sessionId, string $code, string $state) |
POST /onboarding/superpdp/callback |
Finaliser l'enrôlement après redirect |
Gerer les factures entrantes (fournisseurs)
use Scell\Sdk\Enums\RejectionCode; use Scell\Sdk\Enums\DisputeType; // Lister les factures entrantes $incoming = $api->invoices()->incoming([ 'status' => 'pending', 'per_page' => 25, ]); foreach ($incoming->data as $invoice) { echo "{$invoice->invoiceNumber} - {$invoice->sellerName}: {$invoice->totalTtc} EUR"; } // Accepter une facture $invoice = $api->invoices()->accept($invoiceId, [ 'comment' => 'Facture conforme', ]); echo "Facture acceptee: {$invoice->status->label()}"; // Rejeter une facture avec un code de rejet $invoice = $api->invoices()->reject( $invoiceId, 'Le montant ne correspond pas a la commande', RejectionCode::IncorrectAmount ); // Contester une facture (litige) $invoice = $api->invoices()->dispute( $invoiceId, 'Montant facture: 1500 EUR, montant commande: 1200 EUR', DisputeType::AmountDispute, expectedAmount: 1200.00 ); // Marquer une facture comme payee (obligatoire dans le cycle de vie) $invoice = $api->invoices()->markPaid($invoiceId, [ 'payment_reference' => 'VIR-2026-0124', 'paid_at' => '2026-01-24T10:30:00Z', 'note' => 'Paiement recu par virement bancaire' ]); echo "Facture payee: {$invoice->status->label()}"; echo "Reference: {$invoice->paymentReference}"; // Verifier si une facture est payee if ($invoice->isPaid()) { echo "Facture reglee le: {$invoice->paidAt->format('d/m/Y')}"; }
Telecharger des fichiers
// Obtenir une URL temporaire de telechargement (15 min) $download = $api->invoices()->download($invoiceId, 'converted'); echo "URL: {$download['url']}"; // Telecharger le contenu binaire d'une facture PDF (Factur-X) $pdfContent = $api->invoices()->downloadContent($invoiceId); file_put_contents('facture.pdf', $pdfContent); // Telecharger le contenu XML (UBL/CII) $xmlContent = $api->invoices()->downloadContent($invoiceId, 'xml'); file_put_contents('facture.xml', $xmlContent); // Telecharger un document signe $download = $api->signatures()->download($signatureId, 'signed'); // Convertir une facture vers un autre format $api->invoices()->convert($invoiceId, OutputFormat::UBL); // Piste d'audit (factures) $audit = $api->invoices()->auditTrail($invoiceId); foreach ($audit['data'] as $entry) { echo "{$entry['action']}: {$entry['details']}"; } // Piste d'audit (signatures) $audit = $api->signatures()->auditTrail($signatureId); foreach ($audit['data'] as $entry) { echo "{$entry['action']}: {$entry['details']}"; }
Gerer les sub-tenants
// Lister les sub-tenants $subTenants = $api->subTenants()->list(['per_page' => 50]); foreach ($subTenants->data as $subTenant) { echo "{$subTenant->name} ({$subTenant->siret})"; } // Creer un sub-tenant $subTenant = $api->subTenants()->create([ 'external_id' => 'CLIENT-001', 'name' => 'Mon Client SARL', 'siret' => '12345678901234', 'email' => 'contact@client.fr', 'address_line1' => '1 rue de la Paix', 'postal_code' => '75001', 'city' => 'Paris', ]); // Rechercher par ID externe $subTenant = $api->subTenants()->findByExternalId('CLIENT-001'); // Mettre a jour $subTenant = $api->subTenants()->update($subTenantId, [ 'email' => 'nouveau@email.fr', ]);
Factures pour les sub-tenants
// Creer une facture pour un sub-tenant $invoice = $api->tenantInvoices()->createForSubTenant($subTenantId, [ 'direction' => 'outgoing', 'output_format' => 'facturx', 'issue_date' => '2026-01-26', 'seller' => [...], 'buyer' => [...], 'lines' => [...], ]); // Soumettre pour traitement $api->tenantInvoices()->submit($invoiceId); // Factures directes (sans sub-tenant) $invoice = $api->directInvoices()->create([...]); // Operations en masse $api->directInvoices()->bulkCreate([...]); $api->directInvoices()->bulkSubmit([$id1, $id2, $id3]); // Factures entrantes (fournisseurs) $incoming = $api->incomingInvoices()->listForSubTenant($subTenantId, [ 'status' => 'received', ]); // Accepter / Rejeter / Marquer comme payee $api->incomingInvoices()->accept($invoiceId); $api->incomingInvoices()->reject($invoiceId, 'Montant incorrect'); $api->incomingInvoices()->markPaid($invoiceId, 'VIR-2026-001');
Conformite fiscale (ISCA)
// Dashboard de conformite $compliance = $api->fiscal()->compliance(); // Verification d'integrite $report = $api->fiscal()->integrity(); $history = $api->fiscal()->integrityHistory(['per_page' => 25]); // Clotures $closings = $api->fiscal()->closings(); $api->fiscal()->performDailyClosing(); // Export FEC $fec = $api->fiscal()->fecExport(['year' => 2025]); // Attestation annuelle $attestation = $api->fiscal()->attestation(2025); $pdf = $api->fiscal()->attestationDownload(2025); // Ecritures comptables $entries = $api->fiscal()->entries(['per_page' => 100]); // Ancres d'integrite $anchors = $api->fiscal()->anchors(); // Regles fiscales $rules = $api->fiscal()->rules(); $api->fiscal()->createRule([...]);
Documents de conformité ISCA
// Registre des mesures $pdf = $api->fiscal()->downloadMeasuresRegister(); file_put_contents('registre-mesures-isca.pdf', $pdf); // Dossier technique $pdf = $api->fiscal()->downloadTechnicalDossier(); file_put_contents('dossier-technique-isca.pdf', $pdf); // Auto-attestation ISCA $pdf = $api->fiscal()->downloadSelfAttestation(); file_put_contents('auto-attestation-isca.pdf', $pdf);
Statistiques et facturation
// Vue d'ensemble $stats = $api->stats()->overview(); // Statistiques mensuelles $monthly = $api->stats()->monthly(['year' => 2025]); // Stats par sub-tenant $stats = $api->stats()->subTenantOverview($subTenantId); // Facturation plateforme $invoices = $api->billing()->invoices(); $usage = $api->billing()->usage(); $transactions = $api->billing()->transactions(); // Recharger le solde $api->billing()->topUp(['amount' => 100.00]); // Confirmer un rechargement (apres validation paiement) $api->billing()->confirmTopUp(['payment_intent_id' => 'pi_...']);
Gerer les avoirs (Credit Notes)
// Lister les avoirs $creditNotes = $api->creditNotes()->list($subTenantId, [ 'status' => 'draft', 'per_page' => 25, ]); // Verifier les montants creditables $remaining = $api->creditNotes()->remainingCreditable($invoiceId); // Creer un avoir partiel $creditNote = $api->creditNotes()->create($subTenantId, [ 'invoice_id' => $invoiceId, 'reason' => 'Remise commerciale', 'type' => 'partial', 'items' => [ [ 'description' => 'Remise sur prestation', 'quantity' => 1, 'unit_price' => 100.00, 'tax_rate' => 20.0, ], ], ]); // Creer un avoir total $creditNote = $api->creditNotes()->create($subTenantId, [ 'invoice_id' => $invoiceId, 'reason' => 'Annulation de la commande', 'type' => 'full', ]); // Envoyer l'avoir $api->creditNotes()->send($creditNoteId); // Telecharger le PDF $pdf = $api->creditNotes()->download($creditNoteId); file_put_contents('avoir.pdf', $pdf);
Integration Laravel
Installation
Le SDK supporte l'auto-discovery Laravel. Publiez la configuration:
php artisan vendor:publish --tag=scell-config
Configuration (.env)
SCELL_API_KEY=tk_live_... SCELL_WEBHOOK_SECRET=whsec_...
Utilisation avec Facades
use Scell\Sdk\Laravel\Facades\ScellApi; use Scell\Sdk\Laravel\Facades\Scell; use Scell\Sdk\Laravel\Facades\ScellWebhook; // Creer une facture (API Key) $invoice = ScellApi::invoices()->builder() ->outgoing() ->facturX() // ... ->create(); // Consulter le solde (Bearer token) $balance = Scell::balance()->get(); // Verifier un webhook $payload = ScellWebhook::verify( request()->getContent(), request()->header('X-Scell-Signature') );
Controller de Webhook
namespace App\Http\Controllers; use Illuminate\Http\Request; use Scell\Sdk\Laravel\Facades\ScellWebhook; use Scell\Sdk\Exceptions\ScellException; class ScellWebhookController extends Controller { public function handle(Request $request) { try { $payload = ScellWebhook::verify( $request->getContent(), $request->header('X-Scell-Signature') ); } catch (ScellException $e) { return response()->json(['error' => 'Signature invalide'], 400); } $event = $payload['event']; $data = $payload['data']; match ($event) { 'invoice.validated' => $this->handleInvoiceValidated($data), 'invoice.transmitted' => $this->handleInvoiceTransmitted($data), 'signature.completed' => $this->handleSignatureCompleted($data), 'signature.refused' => $this->handleSignatureRefused($data), 'balance.low' => $this->handleBalanceLow($data), default => null, }; return response()->json(['received' => true]); } private function handleInvoiceValidated(array $data): void { // Traiter la facture validee $invoiceId = $data['id']; // ... } private function handleSignatureCompleted(array $data): void { // Telecharger le document signe $signatureId = $data['id']; $download = ScellApi::signatures()->download($signatureId, 'signed'); // ... } }
Injection de dependances
use Scell\Sdk\ScellApiClient; use Scell\Sdk\Webhooks\WebhookVerifier; class InvoiceService { public function __construct( private readonly ScellApiClient $api ) {} public function createInvoice(Order $order): Invoice { return $this->api->invoices()->builder() ->outgoing() ->facturX() // ... ->create(); } }
Gestion des erreurs
use Scell\Sdk\Exceptions\ScellException; use Scell\Sdk\Exceptions\ValidationException; use Scell\Sdk\Exceptions\AuthenticationException; use Scell\Sdk\Exceptions\RateLimitException; try { $invoice = $api->invoices()->create([...]); } catch (ValidationException $e) { // Erreurs de validation foreach ($e->getErrors() as $field => $messages) { echo "$field: " . implode(', ', $messages); } } catch (AuthenticationException $e) { // API Key invalide echo "Authentification echouee: {$e->getMessage()}"; } catch (RateLimitException $e) { // Limite de requetes atteinte $retryAfter = $e->getRetryAfter(); echo "Reessayez dans {$retryAfter} secondes"; } catch (ScellException $e) { // Autre erreur API echo "Erreur: {$e->getMessage()}"; echo "Code: {$e->getScellCode()}"; }
Types et Enums
Le SDK utilise des enums PHP 8.2+ pour les valeurs predefinies:
use Scell\Sdk\Enums\Direction; use Scell\Sdk\Enums\OutputFormat; use Scell\Sdk\Enums\InvoiceStatus; use Scell\Sdk\Enums\SignatureStatus; use Scell\Sdk\Enums\AuthMethod; use Scell\Sdk\Enums\WebhookEvent; use Scell\Sdk\Enums\Environment; use Scell\Sdk\Enums\RejectionCode; use Scell\Sdk\Enums\DisputeType; // Direction de facture Direction::Outgoing; // Vente Direction::Incoming; // Achat // Format de sortie OutputFormat::FacturX; // Factur-X PDF/A-3 OutputFormat::UBL; // UBL 2.1 OutputFormat::CII; // UN/CEFACT CII // Methode d'authentification AuthMethod::Email; // OTP par email AuthMethod::Sms; // OTP par SMS AuthMethod::Both; // Email + SMS // Codes de rejet (factures entrantes) RejectionCode::IncorrectAmount; // Montant incorrect RejectionCode::Duplicate; // Facture en double RejectionCode::UnknownOrder; // Commande inconnue RejectionCode::IncorrectVat; // TVA incorrecte RejectionCode::Other; // Autre // Types de litige (factures entrantes) DisputeType::AmountDispute; // Litige sur le montant DisputeType::QualityDispute; // Litige sur la qualite DisputeType::DeliveryDispute; // Litige sur la livraison DisputeType::Other; // Autre // Statut de facture InvoiceStatus::Paid; // Facture payee // Evenements webhook WebhookEvent::InvoiceValidated; WebhookEvent::InvoiceIncomingReceived; WebhookEvent::InvoiceIncomingAccepted; WebhookEvent::InvoiceIncomingPaid; WebhookEvent::SignatureCompleted; WebhookEvent::BalanceLow;
Configuration avancee
use Scell\Sdk\Config; use Scell\Sdk\ScellApiClient; $config = new Config( baseUrl: 'https://api.scell.io/api/v1', timeout: 60, connectTimeout: 15, retryAttempts: 5, retryDelay: 200, verifySsl: true, webhookSecret: 'whsec_...', ); $api = ScellApiClient::withApiKey('tk_live_...', $config);
Tests
# Run tests composer test # Run tests with coverage composer test-coverage # Run static analysis composer analyse # Run all checks composer check
API Reference
ScellClient (Bearer token)
| Resource | Description |
|---|---|
invoices() |
Gestion des factures electroniques |
signatures() |
Gestion des signatures electroniques |
companies() |
Gestion des entreprises |
balance() |
Consultation du solde |
webhooks() |
Gestion des webhooks |
ScellApiClient (API Key)
| Resource | Description |
|---|---|
invoices() |
Factures (builder, download, audit trail) |
signatures() |
Signatures (builder, download, audit trail) |
subTenants() |
Gestion des sub-tenants (CRUD, recherche) |
tenantInvoices() |
Factures des sub-tenants (create, submit, update) |
directInvoices() |
Factures directes (create, bulk operations) |
incomingInvoices() |
Factures entrantes (accept, reject, markPaid) |
creditNotes() |
Avoirs (create, send, download) |
fiscal() |
Conformite fiscale ISCA (integrite, clotures, FEC) |
stats() |
Statistiques (overview, monthly, par sub-tenant) |
billing() |
Facturation plateforme (invoices, usage, top-up) |
ScellTenantClient (Multi-Tenant Partner)
use Scell\Sdk\ScellTenantClient; // Create client with tenant key $tenant = ScellTenantClient::create('tk_live_...'); // Sandbox mode $tenant = ScellTenantClient::sandbox('tk_test_...'); // Profile management $profile = $tenant->me(); $tenant->update(['company_name' => 'New Name']); $balance = $tenant->balance(); $stats = $tenant->stats(); $result = $tenant->regenerateKey(); // Sub-Tenants $subTenants = $tenant->subTenants()->list(); $sub = $tenant->subTenants()->create([...]); // Direct Invoices (without sub-tenant scope) $invoices = $tenant->directInvoices()->list(); $invoice = $tenant->directInvoices()->create([...]); $tenant->directInvoices()->bulkCreate([...]); $tenant->directInvoices()->bulkSubmit([...]); // Direct Credit Notes $notes = $tenant->directCreditNotes()->list(); $note = $tenant->directCreditNotes()->create([...]); // Per sub-tenant invoices $subInvoices = $tenant->invoices()->listForSubTenant($subId); $invoice = $tenant->invoices()->createForSubTenant($subId, [...]); // Incoming invoices $incoming = $tenant->incomingInvoices()->listForSubTenant($subId); $tenant->incomingInvoices()->accept($invoiceId); // Fiscal compliance (ISCA) $compliance = $tenant->fiscal()->compliance(); $integrity = $tenant->fiscal()->integrity(); $attestation = $tenant->fiscal()->attestation(2025); // Billing $billingInvoices = $tenant->billing()->invoices(); $usage = $tenant->billing()->usage(); // Detailed stats $overview = $tenant->detailedStats()->overview();
ScellTenantClient API Reference
| Resource | Methods |
|---|---|
| Direct methods | me(), update(data), balance(), stats(), regenerateKey() |
subTenants() |
list(), create(data), get(id), update(id, data), delete(id), findByExternalId(externalId) |
directInvoices() |
list(filters), create(data), bulkCreate(invoices), bulkSubmit(ids), bulkStatus(ids) |
directCreditNotes() |
list(filters), create(data), get(id), send(id), update(id, data), download(id), remainingCreditable(invoiceId) |
invoices() |
listForSubTenant(subId, filters), createForSubTenant(subId, data), get(id), update(id, data), delete(id), submit(id), status(id), remainingCreditable(id) |
creditNotes() |
listForSubTenant(subId, filters), createForSubTenant(subId, data), get(id), update(id, data), delete(id), send(id), download(id), remainingCreditable(invoiceId) |
incomingInvoices() |
listForSubTenant(subId, filters), create(subId, data), get(id), accept(id, data), reject(id, reason, code), markPaid(id, ref, data) |
fiscal() |
compliance(), integrity(params), integrityHistory(params), integrityForDate(date), closings(params), performDailyClosing(data), fecExport(params), attestation(year), attestationDownload(year), entries(params), killSwitchStatus(), killSwitchActivate(data), killSwitchDeactivate(), anchors(params), rules(params), ruleDetail(key), ruleHistory(key, params), createRule(data), updateRule(id, data), exportRules(params), replayRules(data), forensicExport(params) |
billing() |
invoices(params), showInvoice(id), downloadInvoice(id), usage(params), topUp(data), confirmTopUp(data), transactions(params) |
detailedStats() |
overview(params), monthly(params), subTenantOverview(subId, params) |
Webhook Events
| Event | Description |
|---|---|
invoice.created |
Facture creee |
invoice.validated |
Facture validee et conforme |
invoice.transmitted |
Facture transmise au PDP |
invoice.accepted |
Facture acceptee par le destinataire |
invoice.rejected |
Facture rejetee |
invoice.error |
Erreur de traitement de la facture |
invoice.incoming.received |
Facture entrante recue |
invoice.incoming.accepted |
Facture entrante acceptee |
invoice.incoming.rejected |
Facture entrante rejetee |
invoice.incoming.disputed |
Facture entrante contestee |
invoice.incoming.paid |
Facture entrante payee |
signature.created |
Signature creee |
signature.waiting |
Signature en attente des signataires |
signature.signer_completed |
Un signataire a signe |
signature.signed |
Tous les signataires ont signe |
signature.completed |
Tous les signataires ont signe |
signature.refused |
Signature refusee |
signature.expired |
Signature expiree |
signature.error |
Erreur de traitement de la signature |
balance.low |
Solde bas (seuil configurable) |
Requirements
- PHP 8.2+
- Guzzle 7.0+
- Laravel 11/12 (optionnel)
Contributing
Les contributions sont bienvenues. Merci de:
- Fork le repository
- Creer une branche (
git checkout -b feature/amazing-feature) - Commit les changements (
git commit -m 'Add amazing feature') - Push sur la branche (
git push origin feature/amazing-feature) - Ouvrir une Pull Request
Code Standards
- PSR-12 pour le style de code
- PHPStan niveau 8 minimum
- Tests pour toute nouvelle fonctionnalite
Security
Si vous decouvrez une vulnerabilite, merci d'envoyer un email a security@scell.io plutot que d'ouvrir une issue publique.
Changelog
Voir CHANGELOG.md pour l'historique des versions.
License
MIT License. Voir LICENSE pour plus d'informations.
Support
- Documentation: docs.scell.io
- Email: support@scell.io
- Issues: GitHub Issues