-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathopenapi.json
More file actions
7767 lines (7767 loc) · 341 KB
/
Copy pathopenapi.json
File metadata and controls
7767 lines (7767 loc) · 341 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
{
"openapi": "3.0.3",
"info": {
"title": "PI - API BUSINESS - OpenAPI 3.0",
"x-logo": {
"url": "https://developers.pi-bceao.com/assets/images/logo/Logo_SPI_1.png"
},
"description": "# Généralités\n\nL'API Business est une API exposée par les participants (PSP) de la Plateforme d'Interopérabilité PI à leurs clients business.\n\nElle permet au participant de fournir des services d’automatisation des opérations de paiement à son client :\n\n- Créer des alias de compte \n- Recevoir des paiements\n- Retourner des paiements\n\n- Envoyer des paiements\n- Effectuer des paiements en masse\n- Envoyer des demandes d'annulation\n\n- Envoyer des demandes de paiements\n- Envoyer des demandes de paiements en masse\n\n- Consulter la liste des opérations \n- Consulter les détails d'une opération\n- Effectuer des transferts entre ses comptes\n\n\nCette spécification a pour but d'encadrer les solutions à valeurs ajoutées offertes par les participants à leurs clients business.\nElle permettra ainsi de faciliter l'interopérabilité et d'éviter le cloisonnement des solutions techniques mises en œuvre.\n\n## Gestion des versions\n\nLa stratégie de développement de l'API est de maintenir la rétrocompatibilité entre l'API et ses ressources et services dans la mesure du possible.\nLes APIs utilisent la spécification __SemVer__ (La gestion sémantique de versions); en ce sens, les modifications compatibles ne doivent pas générer une nouvelle version majeure.\n\nLa version de l’API utilise ainsi le format` MAJEUR.MINEUR.CORRECTIF`\n* le numéro de version `MAJEUR` quand il y a des changements non rétrocompatibles,\n* le numéro de version `MINEUR` quand il y a des ajouts de fonctionnalités rétrocompatibles,\n* le numéro de version de `CORRECTIF` quand il y a des corrections d’anomalies rétrocompatibles.\n\nChaque fois qu'un changement dans ce document définissant les caractéristiques de l'API est mis à jour et affecte d'une manière ou d'une autre un service d'API, une nouvelle version de l’API sera publiée.\nLa version initiale de chaque API est `1.0.0`.\n\n### __1) Versions de correction__\nL’identifiant de version de correction est incrémenté si des corrections rétrocompatibles sont introduites. Une correction est définie comme un changement interne qui corrige un comportement incorrect.\n\n### __2) Versions mineures__\nCertaines modifications n'affectent pas la version de la ressource API; par exemple, si l'ordre des paramètres dans une requête change.\n\nLa liste suivante décrit quelques modifications considérées comme rétrocompatibles. Les participants doivent implémenter leur système de manière à ce que les services d'API prennent automatiquement en charge ces modifications sans interrompre le fonctionnement du système:\n* paramètres de requêtes facultatifs\n* ajout de nouveaux codes d'erreur\n\nCes types de modifications affectent la version mineure du service d'API.\n\n### __3) Versions majeures__\nLa liste suivante décrit les modifications considérées comme rétro-incompatibles si la modification affecte un service d'API connecté à une ressource. Les intégrateurs d'API n'ont pas besoin d'implémenter de manière à prendre automatiquement en charge ces modifications.\nEn effet, pour des changements importants, un plan de migration sera défini et dépendra de la nature de ces changements.\nLes situations suivantes peuvent entraîner la publication d’une version majeure:\n* Paramètres obligatoires supprimés ou ajoutés à une requête\n* Paramètres facultatifs changés en obligatoires dans une requête\n* Paramètres renommés\n* Types de données modifiés\n* La logique métier d’un service modifiée\n* Les URI de ressource/service d'API modifiées\n\nCes types de modifications affectent la version principale du service d'API. Veuillez noter que la liste n'est pas exhaustive ; il peut également y avoir d'autres modifications susceptibles d'affecter la version principale du service d'API.\n### __4) Informations de version__\nLa gestion des versions s’effectuera via le chemin URI qui consiste à inclure le numéro de version dans le chemin URI et permet de gérer facilement plusieurs versions parallèles de l’API.\nLe numéro de version majeure sera inclus dans l’URL de l’API comme suit: __https://www.example.com/api/v1/products__\n\n## Gestion des erreurs\n\nL'API BUSINESS renvoie des codes d'états HTTP pour indiquer le succès ou l'échec à l'issue du traitement d'une requête\n\n - Les codes `2xx` indiquent un succès.\n\n - Les codes `4xx` indiquent un échec causé par les informations envoyées par le client ou l'état actuel des entités.\n\n - Les codes `5xx` généralement liés aux serveurs ou à l'application\n\n - Les réponses d'erreur incluent dans le corps les détails de l'erreur.\n\n - Le champ `type` identifie le type d'erreur rencontrée.\n\nEn ce qui concerne les réponses notifiant une erreur, PI utilise le format décrit dans la `RFC 7807` qui décrit comment les API peuvent renvoyer des informations d'erreur de manière standardisée. Une telle réponse contient les éléments suivants :\n<table>\n <tr>\n <td><b>type</b></td>\n <td>Le champ \"type\" est une URI unique qui identifie le type de problème. L’URI peut être relative.</td>\n </tr>\n <tr>\n <td><b>title</b></td>\n <td>Le champ \"title\" fournit une description courte pour comprendre le problème. Il est identique pour le même type de problème.</td>\n </tr>\n <tr>\n <td><b>detail</b></td>\n <td>Le champ \"detail\" donne des explications sur le problème.</td>\n </tr>\n <tr>\n <td><b>instance</b></td>\n <td>Il indique une référence URI de ressource concernée par le problème. Il est optionnel.</td>\n </tr>\n <tr>\n <td><b>status</b></td>\n <td>Le champ \"status\" renvoie le code de statut HTTP qui a déclenché cette réponse. Ce champ est optionnel.</td>\n </tr>\n</table>\n\nPour donner des informations détaillées sur le problème, des extensions sont permises. Les extensions sont des champs additionnels qui peuvent figurer dans la réponse.\n\nCi-dessous un exemple de réponse en JSON:\n\n<img src=\"./images/exemple-erreur-json.png\" />\n\nIci, le problème `format-invalide` __(identifié par son type URI)__ indique la raison de l’erreur `400` retournée par le serveur lors de la création d’un client; deux extensions sont ajoutées: `typeClient` qui indique le __champ incorrect__, et `invalid-params` qui indiquent les __paramètres invalides et la raison d’invalidité__.\nPar ailleurs, l'URI de type d'un problème devrait référencer une page HTML expliquant comment résoudre le problème. Cependant des types prédéfinis existent: c’est le cas du type `about:blank` qui indique que __le problème n'a pas de sémantique supplémentaire au-delà de celle du code de statut HTTP__. Lorsque `about:blank` est utilisé, le champ `title` est le même que le libellé du statut HTTP comme montré dans l’exemple suivant:\n\nLes erreurs suivantes peuvent être renvoyées par n'importe quel endpoint de l'API:\n\n### `BadRequest`\n\n * Signification: Requête invalide.\n * __HTTP Status Code__: [400 Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1).\n\n### `Unauthorized`\n\n * Signification: Requête non authentifiée. Les informations d'authentification sont manquantes ou invalides.\n * __HTTP Status Code__: [401 Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1).\n\n### `Forbidden`\n\n * Signification: Requête authentifiée qui enfreint une règle d'autorisation.\n * __HTTP Status Code__: [403 Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3).\n\n### `NotFound`\n\n * Signification: Entité non trouvée.\n * __HTTP Status Code__: [404 Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4).\n\n### `Gone`\n\n * Signification: Indique que l'entité a existé mais qu'elle a été définitivement supprimée.\n * __HTTP Status Code__: [410 Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9).\n\n### `InternalServerError`\n\n * Signification: Erreur interne du serveur\n * __HTTP Status Code__: [500 Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1).\n\n### `BadGateway`\n\n * Signification: Le serveur a reçu une réponse invalide du serveur en amont.\n * __HTTP Status Code__: [502 Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3).\n\n### `ServiceUnavailable`\n\n * Signification: Le service n'est pas disponible actuellement. Le service demandé peut être en cours de maintenance ou en dehors de la fenêtre d'exploitation.\n * __HTTP Status Code__: [503 Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4).\n\n### `GatewayTimeout`\n\n * Signification: Indique que le service a mis plus de temps que prévu à revenir.\n * __HTTP Status Code__: [504 Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5).\n\n\n## Pagination et filtres\n\nLes endpoints qui retournent des listes de ressources utilisent un format de réponse standardisé pour assurer une expérience cohérente et faciliter la pagination et le filtrage.\n\n### Structure de la réponse\n\nToutes les listes suivent une structure commune avec deux sections principales :\n\n```json\n{\n \"data\": [...], // Tableau contenant les éléments de la page actuelle\n \"meta\": {...} // Métadonnées sur la pagination et le nombre total d'éléments\n}\n```\n\n#### Section `data`\nContient le tableau des éléments de la page actuelle. Le nombre d'éléments est limité par le paramètre `size`.\n\n#### Section `meta`\nContient les informations de pagination et de contexte :\n\n```json\n{\n \"meta\": {\n \"total\": 100, // Nombre total d'éléments (optionnel, si calculé)\n \"page\": 2, // Page actuelle (peut être un entier ou un token)\n \"size\": 20, // Nombre d'éléments par page\n \"next\": 3, // Token ou numéro de la page suivante (optionnel)\n \"prev\": 1 // Token ou numéro de la page précédente (optionnel)\n }\n}\n```\n\n**Remarques importantes** :\n- Les champs `page`, `next` et `prev` peuvent être des **nombres entiers** ou des **chaînes de caractères** (tokens)\n- Le champ `total` est optionnel car son calcul peut être coûteux pour de grandes collections\n- Les champs `next` et `prev` sont optionnels et absents s'il n'y a pas de page suivante ou précédente\n\n### Paramètres de pagination\n\nLes paramètres de requête suivants permettent de contrôler la pagination :\n\n#### Paramètres standards\n\n- **`page`** : Identifie la page à récupérer\n - Type : `integer` ou `string` (token)\n - Par défaut : `1` (première page)\n - Exemples :\n - Pagination par numéro : `GET /comptes?page=2&size=20`\n - Pagination par token : `GET /comptes?page=eyJrZXkiOiIxMjM0NTY3ODkifQ==&size=20`\n\n- **`size`** : Nombre d'éléments par page\n - Type : `integer`\n - Valeur minimale : `1`\n - Valeur maximale : `100` (peut varier selon l'endpoint)\n - Par défaut : `20`\n - Exemple : `GET /comptes?page=1&size=50`\n\n#### Types de pagination\n\n**Pagination par offset (numérique)** :\n```\nGET /comptes?page=2&size=20\n```\nRetourne les éléments 21 à 40 (page 2 × 20 éléments par page).\n\n**Pagination par curseur (token)** :\n```\nGET /comptes?page=eyJrZXkiOiIxMjM0NTY3ODkifQ==&size=20\n```\nUtilise un token opaque pour garantir la cohérence lors de modifications fréquentes des données.\n\n### Filtrage des résultats\n\nLes endpoints de liste supportent le filtrage via des paramètres de requête avec la syntaxe `propriete[operateur]=valeur` :\n\n**Exemples** :\n```\n# Filtrer par statut\nGET /paiements-immediats?statut=IRREVOCABLE\nGET /paiements-immediats?statut[ne]=INITIE\n\n# Filtrer par date de début\nGET /paiements-immediats?dateIrrevocabilite[gte]=2024-01-01\n\n# Filtrer les demandes de paiement de type PICO (retrait dans le cadre d'un achat)\nGET /demandes-paiements?montantAchat[exists]=true\n\n# Filtrer les demandes de paiement de type PICASH (retrait simple)\nGET /demandes-paiements?montantAchat[exists]=false&montantRetrait[exists]=true\n\n# Combiner plusieurs filtres\nGET /paiements-immediats?dateIrrevocabilite[gte]=2024-01-01&statut[ne]=INITIE\n```\n\n**Operateurs** :\n- `eq` : égal à\n- `ne` : différent de\n- `gt` : supérieur à\n- `gte` : supérieur ou égal à\n- `lt` : inférieur à\n- `lte` : inférieur ou égal à\n- `in` : dans la liste\n- `contains` : la liste ou la chaine de caractères contient la valeur\n- `notContains` : la liste ou la chaine de caractères ne contient pas la valeur\n- `beginsWith` : commence par la valeur\n- `endsWith` : finit par la valeur\n- `exists` : existe\n\n### Tri des résultats\n\nLe paramètre `sort` permet de trier les résultats. Pour indiquer l'ordre de tri :\n\n- **Sans préfixe** : tri ascendant (croissant)\n- **Préfixe `-`** : tri descendant (décroissant)\n\n**Syntaxe** : `sort=champ` ou `sort=-champ`\n\n**Exemples** :\n```\n# Trier par type croissant\nGET /comptes/123456/alias?sort=type\n\n# Trier par date décroissant\nGET /paiements-immediats?sort=-dateCreation\n```\n\n### Exemples complets\n\n**Liste simple sans pagination** :\n```\nGET /comptes/123456/alias\n```\n\n**Liste paginée avec taille personnalisée** :\n```\nGET /paiements-immediats?page=1&size=50\n```\n\n**Liste avec filtrage et tri** :\n```\nGET /paiements-immediats?statut=IRREVOCABLE&sort=-dateCreation&page=1&size=20\n```\n\n**Navigation vers la page suivante avec token** :\n```\n# Première requête\nGET /comptes?page=1&size=20\n\n# Réponse\n{\n \"data\": [...],\n \"meta\": {\n \"total\": 150,\n \"size\": 20,\n \"page\": \"1\",\n \"next\": \"eyJrZXkiOiIxMjM0NTY3ODkifQ\"\n }\n}\n\n# Requête pour la page suivante\nGET /comptes?page=eyJrZXkiOiIxMjM0NTY3ODkifQ&size=20\n```\n\n\n# Sécurité\n\n## Sécurité de l'API\n\nLes endpoints de l'API Business sont sécurisés de manière robuste, combinant à la fois:\n- le protocole Mutual TLS (MTLS) pour une authentification forte au niveau du transport\n- OAuth2 pour une gestion fine des autorisations.\nAssurant ainsi une sécurité complète de l'accès aux ressources.\n\n<SecurityDefinitions />\n",
"contact": {
"name": "support",
"email": "pisfn-sandbox@bceao.int"
},
"version": "1.0.0"
},
"servers": [
{
"url": "https://sandbox.api.pi-bceao.com/piz/v1"
}
],
"tags": [
{
"name": "Comptes",
"description": "Le module de gestion des comptes permet aux clients business de gérer leurs comptes à distance et en toute sécurité.\n\nIl offre trois fonctionnalités principales :\n\n* **Consulter le solde d'un compte** : Obtenir à tout moment les informations relatives au solde et aux détails d'un compte spécifique.\n\n* **Lister les opérations** : Afficher l'historique des opérations effectuées sur les comptes (en provenance ou à destination), avec des options de filtrage et de pagination.\n\n* **Effectuer des transferts intra-comptes** : Initier des transferts de fonds entre les comptes détenus par le même client et domiciliés dans la même institution financière.\n"
},
{
"name": "Alias",
"description": "Un alias de compte est une identification choisie par un client qui lui permet de recevoir des virements sans fournir les informations d’identification de son compte.\n\nLes alias améliorent l’expérience client en permettant au client d'effectuer des transactions de manière transparente sans avoir besoin de connaître et de saisir les détails de compte bancaire du payé.\nLa correspondance entre un alias et un compte client est stockée dans le répertoire des alias centralisé (RAC) de la plateforme PI-SPI.\n"
},
{
"name": "Notification",
"x-displayName": "Gestion des webhooks",
"description": "Les clients business peuvent configurer des webhooks pour recevoir des notifications lorsque des opérations sont effectuées sur leurs comptes.\n\nLes webhooks sont une technologie utilisée pour établir une communication instantanée entre différents systèmes et plateformes,\npermettant l'échange d'informations et de données en temps réel.\n\nDans le contexte de l'API business, les webhooks sont un moyen efficace de tenir les clients informés des mouvements financiers sur leurs comptes sans avoir à vérifier constamment la plateforme (polling).\n\nAinsi, lorsqu'un mouvement se produit sur un compte, comme un transfert ou une demande de paiement, le webhook se déclenche et envoie un message automatiquement au système du client, l'informant de l'opération effectuée.\n\nCe processus est très utile pour les clients qui ont besoin de suivre leurs comptes en temps réel, notamment les entreprises qui doivent gérer des flux financiers complexes. Il permet également d'**automatiser des actions métier** suite à la réception de notifications. Par exemple :\n- Imprimer automatiquement un reçu lorsqu'un paiement est reçu\n- Déclencher une livraison de produit ou service dès confirmation du paiement\n- Mettre à jour automatiquement le statut d'une commande\n- Envoyer des confirmations par email ou SMS au client final\n\nDe plus, les webhooks sont hautement personnalisables, permettant aux clients de configurer les notifications en fonction de leurs besoins de gestion et de suivi.\n\n## Types d'évènements\nIl existe différentes catégories d'événements :\n\n* Événements liés aux ordres de paiement\n* Événements liés aux demandes de paiement\n* Événements liés aux retours de fonds\n\n### Événements liés aux ordres de paiement\n<table>\n <tr>\n <th>Code</th>\n <th>Description de l'évènement</th>\n </tr>\n <tr>\n <td><b>PAIEMENT_RECU</b></td>\n <td>Lorsque le business reçoit un paiement ou lorsqu'une demande de paiement est acceptée</td>\n </tr>\n <tr>\n <td><b>PAIEMENT_ENVOYE</b></td>\n <td>Lorsque le business envoie un ordre de paiement et que celui-ci est irrévocable.\n </tr>\n <tr>\n <td><b>PAIEMENT_REJETE</b></td>\n <td>Lorsque le business envoie un ordre de paiement et que celui-ci est rejeté.\n </tr>\n</table>\n\n### Événements liés aux demandes de paiement\n<table>\n <tr>\n <th>Code</th>\n <th>Description de l'évènement</th>\n </tr>\n <tr>\n <td><b>RTP_RECU</b></td>\n <td>Lorsque le business reçoit une demande de paiement</td>\n </tr>\n <tr>\n <td><b>RTP_REJETE</b></td>\n <td>Lorsque le business envoie une demande de paiement et que cette demande est rejetée.\n </tr>\n</table>\n\n### Événements liés aux retours de fonds et demandes d'annulation\n<table>\n <tr>\n <th>Code</th>\n <th>Description de l'évènement</th>\n </tr>\n <tr>\n <td><b>ANNULATION_DEMANDE</b></td>\n <td>Lorsque le business reçoit une demande d'annulation de paiement</td>\n </tr>\n <tr>\n <td><b>RETOUR_ENVOYE</b></td>\n <td>Lorsque le business envoie un retour de fonds et que celui-ci est irrévocable.\n </tr>\n <tr>\n <td><b>RETOUR_REJETE</b></td>\n <td>Lorsque le business envoie un retour de fonds et que celui-ci est rejeté.\n </tr>\n <tr>\n <td><b>RETOUR_RECU</b></td>\n <td>Lorsque le business reçoit un retour de fonds ou lorsqu'une demande d'annulation de paiement a été acceptée</td>\n </tr>\n <tr>\n <td><b>ANNULATION_REJETE</b></td>\n <td>Lorsque le business envoie une demande d'annulation de paiement et que celle-ci est rejetée.</td>\n </tr>\n</table>\n\n## Sécurité des webhooks\n\n### Cryptage des données\nToutes les communications doivent se faire en utilisant une connexion SSL.\n\n### Authentification\nLe lien de rappel doit être protégé par un système d'authentification.\nmTLS doit être utilisé pour gérer l'authentification du participant appelant.\nLe certificat mTLS utilisé doit être délivré par une autorité de certification de la BCEAO.\n\n### Signature des données\nPour éviter les modifications indésirables, les événements doivent être signés.\nCela peut se faire via l'utilisation d'un code d'authentification de message basé sur le hachage (HMAC),\nqui consiste en un algorithme de hachage et un code secret ou une clé que les deux parties partagent.\n"
},
{
"name": "DemandesDePaiement",
"x-displayName": "Demandes de paiement",
"description": "Une demande de paiement est une demande adressée à une personne ou à une entité pour solliciter le règlement d'un achat, d'un service rendu, d'une dette ou de toute autre obligation financière.\n\nLa demande de paiement indique au payeur identifié par son alias les modalités de réglement.\n\nLes options de paiement du payeur sont données par `dateLimitePaiement` et `dateLimiteReponse`:\n- la demande de paiement ne peut être acceptée ou rejetée apres _dateLimiteReponse_ \n- Lorsque _dateLimiteReponse_ n'est pas renseigné, la valeur par défaut est la date de la demande + 90 jours (3 mois)\n- le date d'échéance du paiement doit être indiquée avec _dateLimitePaiement_\n- Lorsqu'une remise est appliquée, elle reste valide jusqu'à _dateLimitePaiement_\n\nLorsqu'un client reçoit une demande de paiement, il peut choisir de:\n 1. `Accepter et Payer tout de suite`\n 2. `Accepter et Payer plus tard` (Programmer le paiement)\n 3. `Refuser`\n 4. `Ignorer`\n\nLorsque _dateLimiteReponse_ est inférieure à 24h, le paiement ne peut pas être programmé par le payeur.\n\nPour les demandes de paiement immédiats sur site, les champs _dateLimitePaiement_ et _dateLimiteReponse_ ne sont pas envoyés.\nLa demande expire au plus tard 24h après sa création.\n\nPour les demandes de paiement e-commerce et les demandes de paiement de facture, la _dateLimitePaiement_ doit être renseignée. \nPour limiter l'exposition des clients aux cas de fraude, la _dateLimitePaiement_ doit être inférieure à 3 minutes pour les demandes de paiement e-commerce.\n"
},
{
"name": "DemandesDePaiementEnMasse",
"x-displayName": "Demandes de paiement en masse",
"description": "La demande de paiement en masse permet d'envoyer plusieurs demandes de paiement en une seule action.\n"
},
{
"name": "PaiementImmediat",
"x-displayName": "Paiements",
"description": "Cette fonctionnalité permet au business d'effectuer des paiements à destination \n- des clients de type **P** (Personne physique / Particulier), \n- des clients de type **C** (Personne physique commerçante / Commerçant), \n- des clients de type **B** (Entreprise / Business), \n- des clients de type **G** (Entité gouvernementale)\n\n### Seuils de paiement\n\nLes montants maximaux des paiements dépendent du type de client émetteur et du type de client destinataire.\nTous les montants sont exprimés en **francs CFA (XOF)**.\n\n#### Montants maximaux par type de transaction\n\n| Type de transaction | Émetteur | Destinataire | Montant maximum |\n|---------------------|----------|--------------|-----------------|\n| **P2P** | Particulier | Particulier | 5 000 000 XOF |\n| **P2C** | Particulier | Commerçant | 5 000 000 XOF |\n| **P2B** | Particulier | Entreprise | 5 000 000 XOF |\n| **P2G** | Particulier | Gouvernement | 5 000 000 XOF |\n| **C2P** | Commerçant | Particulier | 5 000 000 XOF |\n| **C2C** | Commerçant | Commerçant | 5 000 000 XOF |\n| **C2B** | Commerçant | Entreprise | 5 000 000 XOF |\n| **C2G** | Commerçant | Gouvernement | 5 000 000 XOF |\n| **B2P** | Entreprise | Particulier | 10 000 000 XOF |\n| **B2C** | Entreprise | Commerçant | 10 000 000 XOF |\n| **B2B** | Entreprise | Entreprise | 100 000 000 XOF |\n| **B2G** | Entreprise | Gouvernement | 100 000 000 XOF |\n| **G2P** | Gouvernement | Particulier | 10 000 000 XOF |\n| **G2C** | Gouvernement | Commerçant | 10 000 000 XOF |\n| **G2B** | Gouvernement | Entreprise | 100 000 000 XOF |\n| **G2G** | Gouvernement | Gouvernement | 100 000 000 XOF |\n\nEn tant qu'entreprise, vous pouvez :\n\n**Envoyer des paiements :**\n- Jusqu'à **10 000 000 XOF** vers les Particuliers (P) et Commerçants (C)\n- Jusqu'à **100 000 000 XOF** vers les Entreprises (B) et entités Gouvernementales (G)\n\n**Recevoir des paiements :**\n- Jusqu'à **5 000 000 XOF** de la part des Particuliers (P) et Commerçants (C)\n- Jusqu'à **100 000 000 XOF** de la part des Entreprises (B) et entités Gouvernementales (G)\n"
},
{
"name": "PaiementEnMasse",
"x-displayName": "Paiements en masse",
"description": "Un paiement en masse est un ensemble de paiements qui sont liés entre eux par un identifiant unique (instructionId).\nLe paiement en masse peut être relancé en cas d'échec de paiement.\n\n**Taille maximale d'une transaction**:\nLa taille maximale d'une transaction a été estimée en considérant **la longueur maximale de chaque champ** (`txId`, `payeAlias`, `montant`, `motif`, `refDocNumero`, `refDocType`). \n- Taille maximale par transaction : ~310 octets\n - `txId` : 35 caractères\n - `payeAlias` : 36 caractères\n - `montant` : 10 caractères pour 1 milliard\n - `motif` : 140 caractères\n - `refDocNumero` : 35 caractères\n - `refDocType` : 4 caractères\n - JSON overhead : ~50 octets\n\n**Exemples**:\n| Nombre de transactions | Taille JSON approximative |\n|------------------------|--------------------------|\n| 1 000 | ~0,31 MB |\n| 5 000 | ~1,55 MB |\n| 10 000 | ~3,1 MB |\n\n**Enjeux à prendre en compte**:\n- Performance du serveur : plus le lot est volumineux, plus le traitement peut être long.\n- Timeout HTTP : des lots très gros peuvent provoquer des erreurs côté client ou serveur.\n- Risque d’échec partiel : en cas de problème réseau ou serveur, un lot très gros est plus difficile à relancer.\n- Recommandation pratique : les lots de 500 à 5 000 transactions restent faciles à gérer. Pour des volumes supérieurs, découper le paiement en plusieurs sous-lots.\n"
},
{
"name": "RetoursdeFonds",
"x-displayName": "Retours de fonds",
"description": "L'opération de retour de fonds est initiée par le client payé pour retourner les fonds d'un paiement reçu.\nLe payé peut retourner les fonds jusqu'à 90 jours après la date de paiement.\nAprès 90 jours, le retour de fonds ne peut plus être effectué.\n"
},
{
"name": "DemandeAnnulation",
"x-displayName": "Demandes d'annulation",
"description": "La demande d'annulation est une opération initiée par le client payeur pour solliciter le retour des fonds d'un paiement envoyé.\n\nTant que le payé n'a pas retourné les fonds, le payeur peut demander l'annulation du paiement.\nPar exemple lorsque le payeur demande une deuxième fois l'annulation du paiement, une nouvelle demande d'annulation sera envoyée au payé.\n\nLe payeur peut demander l'annulation du paiement jusqu'à 90 jours après la date de paiement.\nAprès 90 jours, la demande d'annulation ne peut plus être effectuée.\n"
}
],
"x-tagGroups": [
{
"name": "Gestion des comptes",
"tags": [
"Alias",
"Comptes"
]
},
{
"name": "Notifications",
"tags": [
"Notification"
]
},
{
"name": "Demandes de paiement",
"tags": [
"DemandesDePaiement",
"DemandesDePaiementEnMasse"
]
},
{
"name": "Paiements",
"tags": [
"PaiementImmediat",
"PaiementEnMasse"
]
},
{
"name": "Retours de fonds",
"tags": [
"RetoursdeFonds",
"DemandeAnnulation"
]
}
],
"paths": {
"/comptes/{numero}": {
"parameters": [
{
"name": "numero",
"in": "path",
"description": "Le numéro de compte sur lequel porte la demande",
"required": true,
"schema": {
"type": "string"
}
}
],
"get": {
"tags": [
"Comptes"
],
"summary": "Détails d'un compte",
"description": "Cet endpoint permet au client de consulter à tout moment les informations détaillées relatives à un compte spécifique.\n\nLes informations retournées incluent :\n- Le type de compte (compte courant, épargne, etc.)\n- Le numéro du compte\n- La date d'ouverture du compte\n- Le solde actuel du compte\n- Le statut du compte (ouvert, bloqué ou clôturé)\n- L'indicateur de pré-confirmation pour les opérations\n\nCette consultation permet au client business de surveiller l'état de ses comptes en temps réel et de prendre des décisions éclairées concernant ses opérations financières.\n",
"security": [
{
"OAuth2": [
"compte.read"
]
}
],
"operationId": "compteSoldeConsulter",
"responses": {
"200": {
"description": "Succès de l'opération",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CompteSolde"
},
"examples": {
"solde-compte": {
"$ref": "#/components/examples/CompteSolde"
}
}
}
}
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"404": {
"$ref": "#/components/responses/RessourceInexistant"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
}
},
"/comptes/transactions": {
"post": {
"tags": [
"Comptes"
],
"summary": "Transfert intra-comptes",
"operationId": "compteTransfertIntraCreer",
"security": [
{
"OAuth2": [
"compte.write"
]
}
],
"description": "Le transfert intra-comptes est un transfert de fonds entre deux comptes détenus par la même entité juridique et domiciliés au sein de la même institution financière. Le compte source (débiteur/payeur) et le compte destination (créditeur/bénéficiaire) appartiennent donc au même client.\n",
"requestBody": {
"description": "Données à fournir pour effectuer un transfert intra-comptes.\n\nLe client business peut effectuer un transfert intra-comptes en utilisant les numéros de compte ou les alias de compte.\nLa création d'alias n'étant possible que sur certains types de comptes, le participant doit supporter les deux modes de transfert.\n",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CompteTransfertIntraRequest"
},
"examples": {
"transfert-intra-numero": {
"$ref": "#/components/examples/CompteTransfertRequestNumero"
},
"transfert-intra-alias": {
"$ref": "#/components/examples/CompteTransfertRequestAlias"
}
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Transfert initié avec succès.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CompteTransfertIntraReponse"
},
"examples": {
"transfert-success-reponse": {
"$ref": "#/components/examples/CompteTransfertReponseInitie"
},
"transfert-irrevocable-reponse": {
"$ref": "#/components/examples/CompteTransfertReponseIrrevocable"
}
}
}
}
},
"400": {
"$ref": "#/components/responses/FormatInvalide"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"403": {
"description": "Interdiction d'effectuer le paiement",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem7807"
},
"examples": {
"transfert-solde-insuffisant": {
"$ref": "#/components/examples/CompteTransfertReponseSoldeInsuffisant"
},
"transfert-paye-bloque": {
"$ref": "#/components/examples/CompteTransfertReponsePayeBloque"
}
}
}
}
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
},
"get": {
"tags": [
"Comptes"
],
"summary": "Lister les transferts intra-comptes",
"operationId": "compteTransfertIntraLister",
"security": [
{
"OAuth2": [
"compte.read"
]
}
],
"parameters": [
{
"name": "statut",
"in": "query",
"schema": {
"type": "string",
"title": "Statut du compte",
"description": "Filtre les opérations selon le statut de ceux-ci"
}
},
{
"name": "comptePayeur",
"in": "query",
"schema": {
"type": "string",
"title": "Compte payeur",
"description": "Filtre les opérations selon le compte payeur"
}
},
{
"name": "comptePaye",
"in": "query",
"schema": {
"type": "string",
"title": "Compte payé",
"description": "Filtre les opérations selon le compte payé"
}
},
{
"name": "dateEnvoi",
"in": "query",
"schema": {
"type": "string",
"format": "date-time",
"title": "Date d'envoi",
"description": "Filtre les opérations selon la date d'envoi"
}
},
{
"name": "dateIrrevocabilite",
"in": "query",
"schema": {
"type": "string",
"format": "date-time",
"title": "Date d'irrévocabilité",
"description": "Filtre les opérations selon la date d'irrévocabilité"
}
},
{
"name": "motif",
"in": "query",
"schema": {
"type": "string",
"title": "Motif",
"description": "Filtre les opérations selon le motif"
}
},
{
"name": "page",
"in": "query",
"schema": {
"type": "string",
"title": "Page",
"description": "Identifiant de la page"
}
},
{
"name": "size",
"in": "query",
"schema": {
"type": "string",
"title": "Taille de la page",
"description": "Nombre d'éléments à retourner"
}
},
{
"name": "sort",
"in": "query",
"schema": {
"type": "string",
"title": "Triage",
"description": "Trie les éléments selon le champ spécifié"
}
},
{
"$ref": "#/components/parameters/Champs"
}
],
"responses": {
"200": {
"description": "Succès de l'opération",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CompteOperationListe"
},
"examples": {
"transfert-liste-reponse": {
"$ref": "#/components/examples/CompteTransfertListeReponse"
}
}
}
}
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
}
},
"/comptes/{numero}/alias": {
"parameters": [
{
"name": "numero",
"in": "path",
"description": "Le numéro de compte sur lequel porte la demande",
"required": true,
"schema": {
"type": "string"
}
}
],
"post": {
"tags": [
"Alias"
],
"summary": "Créer un alias",
"security": [
{
"OAuth2": [
"alias.write"
]
}
],
"description": "Le répertoire des alias de compte permet de créer les types d'alias suivants :\n- Une adresse de paiement, codifiée par SHID: cet alias est obtenu par génération d'une clé aléatoire unique sur 36 positions par le système.\n- Un identifiant de compte marchand, codifié par MCOD: ce type d'alias est prévu pour supporter les paiements par code USSD.\n- Un numéro de téléphone mobile, codifié par MBNO.\n\nLes types d'alias qu'on peut créer dépendent du type de client. \nLes clients de type P (particuliers, personnes physiques) peuvent créer des alias de types MBNO et SHID. \nLes clients de types C, B, et G (commerçants ou entreprises individuelles, entreprises, entités gouvernementales) peuvent créer des alias de types SHID et MCOD.\n\nUn client business peut créer plusieurs alias pour un compte donné.\nUne limite de 20 alias par compte est fixée par défaut. Cette limite peut être augmentée selon les besoins du client.\n",
"operationId": "aliasCreer",
"requestBody": {
"description": "Données pour la création d'alias.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AliasCreationRequest"
},
"examples": {
"alias-SHID": {
"$ref": "#/components/examples/AliasCreationRequestSHID"
},
"alias-MCOD": {
"$ref": "#/components/examples/AliasCreationRequestMCOD"
}
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Opération effectuée avec succès",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AliasCreationReponse"
},
"examples": {
"alias-SHID": {
"$ref": "#/components/examples/AliasCreationReponseSHID"
},
"alias-MCOD": {
"$ref": "#/components/examples/AliasCreationReponseMCOD"
}
}
}
}
},
"400": {
"$ref": "#/components/responses/FormatInvalide"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"403": {
"description": "Opération interdite",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/Problem7807"
},
"examples": {
"limite-alias": {
"$ref": "#/components/examples/AliasCreationReponseDepassementLimit"
}
}
}
}
},
"404": {
"$ref": "#/components/responses/RessourceInexistant"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
},
"get": {
"tags": [
"Alias"
],
"summary": "Lister les alias",
"security": [
{
"OAuth2": [
"alias.read"
]
}
],
"description": "Ce point de terminaison permet de consulter la liste des alias d'un compte.\n",
"operationId": "aliasLister",
"responses": {
"200": {
"description": "Succès de l'opération",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AliasReponseListe"
}
}
}
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
}
},
"/comptes/{numero}/alias/{cle}": {
"parameters": [
{
"name": "numero",
"in": "path",
"description": "Le numéro de compte",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "cle",
"in": "path",
"description": "La cle de l'alias",
"required": true,
"schema": {
"type": "string"
}
}
],
"delete": {
"tags": [
"Alias"
],
"summary": "Supprimer un alias",
"security": [
{
"OAuth2": [
"alias.delete"
]
}
],
"description": "Le client peut supprimer à tout moment un alias de compte.\n",
"operationId": "aliasSupprimer",
"responses": {
"204": {
"description": "Opération effectué avec succès"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"404": {
"$ref": "#/components/responses/RessourceInexistant"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
}
},
"/webhooks": {
"post": {
"tags": [
"Notification"
],
"summary": "Créer un lien de rappel.",
"security": [
{
"OAuth2": [
"webhook.write"
]
}
],
"operationId": "webhookCreer",
"description": "Cet endpoint permet au client de configurer des webhooks (liens de rappel) pour recevoir des notifications en temps réel.\n\nLe client dispose d'une grande flexibilité dans la configuration de ses webhooks et peut choisir parmi plusieurs stratégies :\n\n**1. Callback URL général**\n- Un seul point de rappel pour toutes les notifications\n- Tous les événements de tous les comptes/alias sont envoyés à la même URL\n- Configuration simple, idéale pour centraliser toutes les notifications\n\n**2. Callback URL par alias**\n- Un point de rappel distinct pour chaque alias de compte\n- Permet de router les notifications vers des systèmes différents selon le compte concerné\n- Utile pour isoler les flux de notifications par compte ou par service\n\n**3. Callback URL par événement**\n- Un point de rappel spécifique pour chaque type d'événement (PAIEMENT_RECU, RTP_RECU, etc.)\n- Permet de traiter différemment chaque catégorie d'événement\n- Facilite la séparation des traitements métier (paiements vs demandes vs retours)\n\n**4. Callback URL par événement et alias**\n- Granularité maximale : un point de rappel pour chaque combinaison événement/alias\n- Configuration la plus fine pour des besoins très spécifiques\n- Permet de router précisément chaque notification vers le système approprié\n\nCette flexibilité permet aux clients d'adapter la configuration des webhooks à leur architecture technique et à leurs besoins métier.\n",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookCreationRequest"
},
"examples": {
"toutes-les-notifications": {
"$ref": "#/components/examples/WebhookCreationRequestUnSeul"
},
"notifications-par-alias": {
"$ref": "#/components/examples/NotificationCreationWebhookAlias"
},
"notifications-par-event": {
"$ref": "#/components/examples/NotificationCreationWebhookRTP"
},
"notifications-par-event-et-alias": {
"$ref": "#/components/examples/NotificationCreationWebhookPaiementRecu"
}
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Webhook créé avec succès",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookCreationResponse"
},
"examples": {
"notification-paiement-recu": {
"$ref": "#/components/examples/NotificationCreationWebhookReponsePaiementRecu"
}
}
}
}
},
"400": {
"$ref": "#/components/responses/FormatInvalide"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
},
"callbacks": {
"myEvent": {
"{$request.body#/callbackUrl}": {
"post": {
"description": "Callback POST envoyé par le participant vers l'URL configurée par le client.\n\n**En-têtes de sécurité** :\n- `X-Signature` : Signature HMAC pour vérifier l'authenticité de la notification\n\n**Authentification** :\n- Le callback utilise mTLS avec un certificat délivré par l'autorité de certification BCEAO\n",
"parameters": [
{
"name": "X-Signature",
"in": "header",
"required": true,
"description": "Signature HMAC-SHA256 du corps de la requête.\n\nPermet au client de vérifier que la notification provient bien du participant.\nLa signature est calculée avec une clé secrète partagée entre le participant et le client.\n",
"schema": {
"type": "string",
"example": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
},
{
"name": "Content-Type",
"in": "header",
"required": true,
"description": "Type de contenu de la requête",
"schema": {
"type": "string",
"enum": [
"application/json"
],
"example": "application/json"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookEventsList"
},
"examples": {
"PAIEMENT_RECU": {
"$ref": "#/components/examples/WebhookEventPAIEMENT_RECU"
},
"PAIEMENT_REJETE": {
"$ref": "#/components/examples/WebhookEventPAIEMENT_REJETE"
},
"PAIEMENT_ENVOYE": {
"$ref": "#/components/examples/WebhookEventPAIEMENT_ENVOYE"
},
"RTP_RECU": {
"$ref": "#/components/examples/WebhookEventRTP_RECU"
},
"RTP_REJETE": {
"$ref": "#/components/examples/WebhookEventRTP_REJETE"
},
"PAIEMENT_RECU_RTP_ACCEPTE": {
"$ref": "#/components/examples/WebhookEventRTP_ENVOYE_ACCEPTE"
},
"ANNULATION_DEMANDE": {
"$ref": "#/components/examples/WebhookEventANNULATION_DEMANDE"
},
"ANNULATION_REJETE": {
"$ref": "#/components/examples/WebhookEventANNULATION_REJETE"
},
"RETOUR_ENVOYE": {
"$ref": "#/components/examples/WebhookEventRETOUR_ENVOYE"
},
"RETOUR_REJETE": {
"$ref": "#/components/examples/WebhookEventRETOUR_REJETE"
},
"RETOUR_RECU": {
"$ref": "#/components/examples/WebhookEventRETOUR_RECU"
},
"EVENEMENTS_MULTIPLES": {
"$ref": "#/components/examples/WebhookEventsMultiples"
}
}
}
}
},
"responses": {
"200": {
"description": "Notification reçue avec succès"
}
}
}
}
}
}
},
"get": {
"tags": [
"Notification"
],
"summary": "Lister les webhooks",
"operationId": "webhookLister",
"security": [
{
"OAuth2": [
"webhook.read"
]
}
],
"description": "Endpoint pour lister les webhooks\n",
"responses": {
"200": {
"description": "Liste des webhooks configurés",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookList"
},
"examples": {
"liste-webhooks": {
"$ref": "#/components/examples/WebhookListReponse"
}
}
}
}
},
"400": {
"$ref": "#/components/responses/FormatInvalide"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
}
},
"/webhooks/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string",
"title": "Identifiant du webhook"
}
}
],
"put": {
"tags": [
"Notification"
],
"summary": "Modifier un Webhook",
"operationId": "webhookModifier",
"security": [
{
"OAuth2": [
"webhook.write"
]
}
],
"description": "Endpoint pour la modification d'un webhook.\n",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookModificationRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"description": "Le Webhook a été modifié avec succès"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
},
"delete": {
"tags": [
"Notification"
],
"summary": "Supprimer un Webhook",
"operationId": "webhookSupprimer",
"security": [
{
"OAuth2": [
"webhook.delete"
]
}
],
"description": "Endpoint pour la suppression d'un webhook.\n",
"responses": {
"204": {
"description": "Le Webhook a été supprimé."
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
},
"get": {
"tags": [
"Notification"
],
"summary": "Recuperer un webhook",
"operationId": "webhookConsulter",
"security": [
{
"OAuth2": [
"webhook.read"
]
}
],
"description": "Endpoint pour la consultation des informations d'un Webhook",
"responses": {
"200": {
"description": "Details du webhook",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/WebhookData"
}
}
}
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
}
},
"/demandes-paiements": {
"post": {
"tags": [
"DemandesDePaiement"
],
"summary": "Envoyer une demande",
"security": [
{
"OAuth2": [
"demande_paiement.write"
]
}
],
"description": "Ce point de terminaison permet d'envoyer une demande de paiement.\n\nLe business peut définir le champ `confirmation` à `true` pour demander une validation en deux étapes : le PSP retournera d'abord le résultat de la recherche d'alias (avec le nom et le pays du payeur), puis attendra une confirmation explicite avant d'envoyer la demande de paiement au payeur via l'endpoint `PUT /demandes-paiements/{txId}/confirmations`.\n\nSi le champ `confirmation` n'est pas défini ou est à `false`, le système envoie directement la demande de paiement au payeur.\n\n**Timeout de confirmation** : Si le business demande une validation en deux étapes , il dispose de **24 heures** pour confirmer ou annuler. Passé ce délai, la demande expire automatiquement.\n",
"operationId": "demandePaiementCreer",
"requestBody": {
"description": "Données pour envoyer une demande de paiement.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DemandePaiementRequest"
},
"examples": {
"paiement-avec-confirmation": {
"$ref": "#/components/examples/DemandePaiementRequestCasAvecConfirmation"
},
"paiement-sans-confirmation": {
"$ref": "#/components/examples/DemandePaiementRequestCasSansConfirmation"
},
"paiement-immediat-sur-site": {
"$ref": "#/components/examples/DemandePaiementImmediatSurSite"
},
"paiement-pico": {
"$ref": "#/components/examples/DemandePaiementPICO"
},
"paiement-picash": {
"$ref": "#/components/examples/DemandePaiementPICASH"
},
"paiement-sur-site-debit-differe": {
"$ref": "#/components/examples/DemandePaiementSurSiteDebitDiffere"
},
"paiement-immediat-en-ligne": {
"$ref": "#/components/examples/DemandePaiementImmediatEnLigne"
},
"paiement-en-ligne-debit-differe": {
"$ref": "#/components/examples/DemandePaiementEnLigneDebitDiffere"
},
"paiement-facture": {
"$ref": "#/components/examples/DemandePaiementFacture"
},
"paiement-facture-avec-remise": {
"$ref": "#/components/examples/DemandePaiementFactureAvecRemise"
}
}
}
}
},
"responses": {
"200": {
"description": "Demande de paiement traitée. Le champ `statut` indique le résultat :\n- `INITIE` : En attente de confirmation (si `confirmation: true`)\n- `ENVOYE` : Demande envoyée au payeur avec succès (si `confirmation: false`)\n- `REJETE` : Demande rejetée. Le champ `statutRaison` contient le code d'erreur :\n - `DU03` : txId dupliqué (déjà utilisé)\n - `BE23` : Alias payeur invalide\n - Autres codes ISO 20022\n",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DemandePaiementReponse"
},
"examples": {
"sans-confirmation": {
"$ref": "#/components/examples/DemandePaiementReponseCasSansConfirmation"
},
"avec-confirmation": {
"$ref": "#/components/examples/DemandePaiementReponseCasAvecConfirmation"
},
"rejete-txid-duplique": {
"$ref": "#/components/examples/DemandePaiementRejeteDU03"
},
"rejete-alias-invalide": {
"$ref": "#/components/examples/DemandePaiementRejeteBE23"
}
}
}
}
},
"400": {
"$ref": "#/components/responses/FormatInvalide"
},
"401": {
"$ref": "#/components/responses/AutorisationsManquantes"
},
"429": {
"$ref": "#/components/responses/LimiteUtilisationDepasse"
},
"503": {
"$ref": "#/components/responses/ProblemeServeur"
}
}
},
"get": {
"parameters": [
{
"name": "payeAlias",
"in": "query",
"schema": {
"type": "string",
"title": "alias du client payé"
}
},
{
"name": "payeCompte",
"in": "query",
"schema": {
"type": "string",
"title": "numéro de compte du client payé"
}
},
{
"in": "query",
"name": "dateEnvoi",
"required": false,
"schema": {
"type": "string",
"format": "date-time",
"title": "Date d'envoi"