Use cases
Refund workflow (full / partial credit note + send)
Issue, fiscally seal and send a credit note to the customer
The Scell.io refund workflow follows the French legal sequence: (1) `POST /api/v1/invoices/{id}/credit-notes` to issue the credit note (full or partial on lines), (2) immediately fiscally sealed (immutable, ISCA compliance), (3) `POST /api/v1/invoices/{credit_note_id}/send` to notify the customer by email with attached Factur-X PDF, (4) optionally trigger the bank refund via your PSP (Stripe, Mangopay) with the credit note PDF link as proof. The credit note NEVER deletes the parent invoice in the fiscal log — both coexist. The `credit_note.issued` webhook notifies your backend in real time.
Key facts
- Credit note issued → immediate fiscal sealing
- Email send endpoint with attached Factur-X PDF
- `credit_note.issued` webhook
- Credit note and invoice coexist (no overwrite)
- PSP refund (Stripe, Mangopay) decoupled
- FORBIDDEN to delete credit note / invoice (ISCA self-certification)
Code example
import { ScellClient } from '@scell/sdk';
import Stripe from 'stripe';
const scell = new ScellClient({ apiKey: process.env.SCELL_SECRET_KEY! });
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
// 1. Émettre l'avoir total
const creditNote = await scell.invoices.createCreditNote('inv_42', {
reason: 'Annulation commande client',
});
// 2. Envoyer l'avoir au client
await scell.invoices.send(creditNote.id, {
to: 'client@example.com',
subject: `Avoir ${creditNote.number}`,
});
// 3. Rembourser via Stripe
await stripe.refunds.create({
payment_intent: 'pi_xxx',
amount: Math.round(creditNote.total_ttc * 100),
metadata: { scell_credit_note_id: creditNote.id, scell_pdf_url: creditNote.pdf_url },
});