Skip to content

Casier judiciaire - embed ​

Parcours eGouv ou MinJust : le citoyen paie dans un overlay sans quitter le portail parent.

Acteurs ​

ActeurRôle
CitoyenPaie dans l'overlay checkout
Portail eGouv (front)Charge le SDK, appelle EpaymentCheckout.open
Back eGouv ou MinJustCrée session mode=embedded, vérifie le token
Epayment APISession embed, token de complétion, webhook
SDK EpaymentCheckoutOverlay iframe et callback onComplete
Webhook application intégrateurFilet de secours (régie cible, souvent code 0001)

Prérequis ​

  • Origines embed configurées (application ou admin eGouv pour clé plateforme + tenant_id).
  • Clé plateforme ou ministry selon le tenant cible ; sk_ jamais exposée au navigateur.
  • SDK chargé depuis https://pay.<domaine>/sdk/v1.js.
  • Endpoint webhook actif sur l'application intégrateur de la régie.
  • Back implémente POST /checkout/sessions/verify-completion pour UX synchrone.

Séquence ​

Étapes métier ​

  1. Citoyen sur portail eGouv, clique « Payer ».
  2. Back eGouv : POST /checkout/sessions avec mode=embedded, tenant_id, order_id, amount, service_code.
  3. Back retourne client_secret au front (jamais sk_).
  4. Front : EpaymentCheckout.open({ clientSecret, onComplete }).
  5. Citoyen paie dans l'iframe.
  6. SDK : onComplete({ completionToken }).
  7. Front → back : acknowledge avec token.
  8. Back : POST /verify-completion avec clé serveur → unlockDossier idempotent.
  9. En parallèle : webhook vers l'application intégrateur.

Exemple back ​

typescript
const session = await epayment.post(
  '/checkout/sessions',
  {
    mode: 'embedded',
    tenant_id: 'minjust',
    service_code: 'casier_judiciaire',
    order_id: dossier.id,
    amount: dossier.amountDueMinor,
  },
  {
    headers: {
      Authorization: `Bearer ${process.env.EPAYMENT_PLATFORM_SK}`,
      'Idempotency-Key': dossier.paymentIdempotencyKey,
    },
  },
);

return { clientSecret: `${session.id}:${session.client_secret}` };

Exemple front ​

html
<script src="https://pay.example.gov/sdk/v1.js" async></script>
<script>
  EpaymentCheckout.open({
    clientSecret: fromBackend,
    onComplete: ({ completionToken }) => {
      fetch('/api/dossiers/acknowledge', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ completion_token: completionToken }),
      });
    },
  });
</script>

Chemins d'échec ​

ScénarioSignalAction
Origines embed absentesAPI 422 embed.origins_required à la créationConfigurer origines avant recette
Token expiré ou rejouécheckout.completion_token_expired (410) ou checkout.completion_token_consumed (409)S'appuyer sur webhook ; rejouer verify avec même token → 200 idempotent si déjà consumé
Overlay fermé sans paiementSession ouverte ; agence possible avec payment_refWebhook ou polling voucher complète le flux ; ne débloquer que sur completed ou verify

Critères d'acceptation ​

  • [ ] Session embed créée sans erreur embed.origins_required.
  • [ ] Overlay s'ouvre depuis l'origine parent configurée.
  • [ ] verify-completion et webhook appellent la même logique unlockDossier idempotente.
  • [ ] client_secret et sk_ absents du code front et des logs navigateur.
  • [ ] Paiement agence en embed : dossier débloqué via webhook ou voucher sans réouverture overlay.
  • [ ] Échec MM : overlay signale l'échec ; dossier non débloqué.

Références ​

Plateforme d'orchestration de paiement DPI. Les fonds ne transitent pas par Epayment.