BCard - Documentation technique

PaymentApiController extends AbstractController
in package

Contrôleur d'API de consultation des paiements.

Il expose l'historique des paiements rattachés à l'utilisateur authentifié : liste paginée et filtrable par statut, détail d'un paiement (avec la commande associée et les références Djomy), statistiques agrégées sur une période glissante et vérification du statut d'un paiement Djomy (la seule action pouvant valider un paiement, via MobilePaymentService). La création des paiements relève des tunnels d'abonnement et de commande, leur confirmation du webhook Djomy.

Préfixe de route : /api/payments. Toutes les actions exigent IS_AUTHENTICATED_FULLY (jeton JWT bearerAuth).

Attributes
#[Route]
'/api/payments'
$name: 'api_payments_'
#[Tag]
$name: 'Payments'
$description: 'Gestion des paiements'

Table of Contents

Properties

$entityManager  : EntityManagerInterface
$mobilePaymentService  : MobilePaymentService
$serializer  : SerializerInterface

Methods

__construct()  : mixed
list()  : JsonResponse
Retourne la liste paginée des paiements de l'utilisateur authentifié.
show()  : JsonResponse
Retourne le détail d'un paiement.
stats()  : JsonResponse
Retourne des statistiques agrégées sur les paiements de l'utilisateur.
status()  : JsonResponse
Relit le statut d'un paiement Djomy et le valide si Djomy confirme le succès.

Properties

Methods

__construct()

public __construct(EntityManagerInterface $entityManager, SerializerInterface $serializer, MobilePaymentService $mobilePaymentService) : mixed
Parameters
$entityManager : EntityManagerInterface

Gestionnaire d'entités Doctrine (injecté, non utilisé par les actions actuelles).

$serializer : SerializerInterface

Sérialiseur Symfony (injecté ; les charges utiles sont construites à la main).

$mobilePaymentService : MobilePaymentService

Relit le statut d'un paiement Djomy et le valide si besoin.

list()

Retourne la liste paginée des paiements de l'utilisateur authentifié.

public list(Request $request, PaymentRepository $paymentRepository) : JsonResponse

Les résultats sont restreints à l'utilisateur courant et triés par created_at décroissant. Le paramètre page est ramené à 1 au minimum et limit est borné à l'intervalle [1, 50] (valeur par défaut 10) ; le filtre status n'est appliqué que s'il est fourni et non vide, sans validation de la valeur transmise. Le nombre total d'éléments est recalculé avec les mêmes critères pour produire le bloc de pagination. Pour chaque paiement, la commande liée est aplatie en un sous-objet, ou vaut null si aucune commande n'est rattachée.

Route : /api/payments (GET), nom api_payments_list. Requiert IS_AUTHENTICATED_FULLY.

Paramètres de requête : status (optionnel), page (optionnel, défaut 1), limit (optionnel, défaut 10, plafonné à 50).

Réponses : 200 liste renvoyée (éventuellement vide), 401 requête non authentifiée.

Parameters
$request : Request

Requête HTTP portant les paramètres de filtrage et de pagination.

$paymentRepository : PaymentRepository

Dépôt utilisé pour la recherche et le comptage.

Attributes
#[Get]
$path: '/api/payments'
$description: 'Récupère la liste des paiements de l\'utilisateur connecté'
$summary: 'Liste les paiements de l\'utilisateur'
$security: [['bearerAuth' => []]]
$tags: ['Payments']
$parameters: [new OA\Parameter(name: 'status', description: 'Filtrer par statut de paiement', in: 'query', required: false, schema: new OA\Schema(type: 'string', enum: ['PENDING', 'COMPLETED', 'ACCEPTED', 'REJECTED'])), new OA\Parameter(name: 'page', description: 'Numéro de page', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 1)), new OA\Parameter(name: 'limit', description: 'Nombre d\'éléments par page', in: 'query', required: false, schema: new OA\Schema(type: 'integer', default: 10))]
$responses: [new OA\Response(response: 200, description: 'Liste des paiements récupérée avec succès', content: new OA\JsonContent(properties: [new OA\Property(property: 'payments', type: 'array', items: new OA\Items(properties: [new OA\Property(property: 'id', type: 'integer', example: 1), new OA\Property(property: 'amount', type: 'string', example: '99.99'), new OA\Property(property: 'currency', type: 'string', example: 'GNF'), new OA\Property(property: 'status', type: 'string', example: 'COMPLETED'), new OA\Property(property: 'payment_method', type: 'string', example: 'DJOMY'), new OA\Property(property: 'provider', type: 'string', nullable: true, example: 'djomy'), new OA\Property(property: 'provider_reference', type: 'string', nullable: true, example: 'BCARD-PAY-42'), new OA\Property(property: 'created_at', type: 'string', format: 'date-time'), new OA\Property(property: 'order', properties: [new OA\Property(property: 'id', type: 'integer'), new OA\Property(property: 'total', type: 'string'), new OA\Property(property: 'status', type: 'string')], type: 'object')])), new OA\Property(property: 'pagination', properties: [new OA\Property(property: 'current_page', type: 'integer'), new OA\Property(property: 'total_pages', type: 'integer'), new OA\Property(property: 'total_items', type: 'integer'), new OA\Property(property: 'items_per_page', type: 'integer')], type: 'object')])), new OA\Response(response: 401, description: 'Non authentifié')]
#[IsGranted]
'IS_AUTHENTICATED_FULLY'
#[Route]
''
$name: 'list'
$methods: ['GET']
Return values
JsonResponse —

Objet JSON {payments: list<array<string, mixed>>, pagination: array<string, int>}.

show()

Retourne le détail d'un paiement.

public show(int $id, PaymentRepository $paymentRepository) : JsonResponse

Le paiement est chargé par sa clé primaire, puis un contrôle de propriété est effectué : seul le titulaire du paiement, ou un porteur de ROLE_ADMIN, peut le consulter. Le bloc order n'est construit que si une commande est rattachée. {id} est contraint à des chiffres pour ne pas capter /stats.

Route : /api/payments/{id} (GET), nom api_payments_show. Requiert IS_AUTHENTICATED_FULLY.

Réponses : 200 paiement renvoyé, 403 paiement appartenant à un autre utilisateur (hors administrateur), 404 paiement inexistant, 401 requête non authentifiée.

Parameters
$id : int

Identifiant du paiement, issu du chemin.

$paymentRepository : PaymentRepository

Dépôt utilisé pour retrouver le paiement.

Attributes
#[Get]
$path: '/api/payments/{id}'
$summary: 'Récupère un paiement par son ID'
$description: 'Récupère les détails d\'un paiement spécifique'
$tags: ['Payments']
$security: [['bearerAuth' => []]]
$parameters: [new OA\Parameter(name: 'id', description: 'ID du paiement', in: 'path', required: true, schema: new OA\Schema(type: 'integer'))]
$responses: [new OA\Response(response: 200, description: 'Détails du paiement', content: new OA\JsonContent(properties: [new OA\Property(property: 'id', type: 'integer', example: 1), new OA\Property(property: 'amount', type: 'string', example: '99.99'), new OA\Property(property: 'currency', type: 'string', example: 'GNF'), new OA\Property(property: 'status', type: 'string', example: 'COMPLETED'), new OA\Property(property: 'payment_method', type: 'string', example: 'DJOMY'), new OA\Property(property: 'provider', type: 'string', nullable: true, example: 'djomy'), new OA\Property(property: 'provider_reference', type: 'string', nullable: true, example: 'BCARD-PAY-42'), new OA\Property(property: 'created_at', type: 'string', format: 'date-time'), new OA\Property(property: 'order', type: 'object', properties: [new OA\Property(property: 'id', type: 'integer'), new OA\Property(property: 'firstname', type: 'string'), new OA\Property(property: 'lastname', type: 'string'), new OA\Property(property: 'email', type: 'string'), new OA\Property(property: 'total', type: 'string'), new OA\Property(property: 'status', type: 'string'), new OA\Property(property: 'created_at', type: 'string', format: 'date-time')])])), new OA\Response(response: 404, description: 'Paiement non trouvé'), new OA\Response(response: 403, description: 'Accès refusé')]
#[IsGranted]
'IS_AUTHENTICATED_FULLY'
#[Route]
'/{id}'
$name: 'show'
$requirements: ['id' => '\d+']
$methods: ['GET']
Return values
JsonResponse —

Objet JSON {id, amount, currency, status, payment_method, provider, provider_reference, created_at, order} ou message d'erreur.

stats()

Retourne des statistiques agrégées sur les paiements de l'utilisateur.

public stats(Request $request, PaymentRepository $paymentRepository) : JsonResponse

La borne basse de la période est calculée à partir de l'instant courant : -1 week, -1 year, ou -1 month par défaut (toute valeur inconnue de period retombe sur le mois). Tous les paiements de l'utilisateur créés depuis cette borne sont chargés via un QueryBuilder, puis agrégés en PHP : montant cumulé, comptages par statut (COMPLETED, PENDING, et REJECTED compté dans failed_payments) et montant moyen. Les montants sont formatés à deux décimales avec un point comme séparateur, sans séparateur de milliers. La valeur period renvoyée est celle reçue, même si elle n'a pas été reconnue.

Route : /api/payments/stats (GET), nom api_payments_stats. Requiert IS_AUTHENTICATED_FULLY.

Paramètres de requête : period (optionnel, week|month|year, défaut month).

Réponses : 200 systématiquement, 401 requête non authentifiée.

Parameters
$request : Request

Requête HTTP portant le paramètre period.

$paymentRepository : PaymentRepository

Dépôt utilisé pour construire la requête de période.

Attributes
#[Get]
$path: '/api/payments/stats'
$summary: 'Statistiques des paiements'
$description: 'Récupère les statistiques des paiements de l\'utilisateur'
$tags: ['Payments']
$security: [['bearerAuth' => []]]
$parameters: [new OA\Parameter(name: 'period', description: 'Période pour les statistiques', in: 'query', required: false, schema: new OA\Schema(type: 'string', enum: ['week', 'month', 'year'], default: 'month'))]
$responses: [new OA\Response(response: 200, description: 'Statistiques des paiements', content: new OA\JsonContent(properties: [new OA\Property(property: 'total_payments', type: 'integer', example: 25), new OA\Property(property: 'total_amount', type: 'string', example: '2499.75'), new OA\Property(property: 'completed_payments', type: 'integer', example: 23), new OA\Property(property: 'pending_payments', type: 'integer', example: 1), new OA\Property(property: 'failed_payments', type: 'integer', example: 1), new OA\Property(property: 'average_amount', type: 'string', example: '99.99'), new OA\Property(property: 'period', type: 'string', example: 'month')])), new OA\Response(response: 401, description: 'Non authentifié')]
#[IsGranted]
'IS_AUTHENTICATED_FULLY'
#[Route]
'/stats'
$name: 'stats'
$methods: ['GET']
Return values
JsonResponse —

Objet JSON {total_payments, total_amount, completed_payments, pending_payments, failed_payments, average_amount, period}.

status()

Relit le statut d'un paiement Djomy et le valide si Djomy confirme le succès.

public status(int $id, PaymentRepository $paymentRepository) : JsonResponse

Le paiement doit appartenir à l'utilisateur authentifié (payment.user), sinon 404, y compris pour un administrateur : l'endpoint peut valider un paiement et n'est donc pas ouvert aux paiements d'autrui. La logique est celle de MobilePaymentService::checkStatus() : paiement COMPLETED renvoyé tel quel ; paiement Djomy PENDING avec transaction relu chez Djomy, validé par PaymentFulfillmentService::fulfill() (source api_status) si le statut est SUCCESS et que la référence marchande désigne ce paiement ; FAILED ou CANCELLED donne FAILED sans rien modifier ; sinon PENDING. Une erreur Djomy donne PENDING avec check_error à true, jamais un 500.

Route : /api/payments/{id}/status (GET), nom api_payments_status. Requiert IS_AUTHENTICATED_FULLY.

Réponses : 200 {success, data: {payment_id, status, subscription_status, order_status[, check_error]}}, 401 non authentifié, 404 paiement inexistant ou appartenant à un autre utilisateur.

Parameters
$id : int

Identifiant du paiement, issu du chemin.

$paymentRepository : PaymentRepository

Dépôt utilisé pour retrouver le paiement de l'utilisateur.

Attributes
#[Get]
$path: '/api/payments/{id}/status'
$summary: 'Vérifie le statut d\'un paiement Djomy'
$description: 'Relit le statut chez Djomy et valide le paiement (abonnement, commande, carte) si Djomy confirme le succès'
$tags: ['Payments']
$security: [['bearerAuth' => []]]
$parameters: [new OA\Parameter(name: 'id', description: 'ID du paiement', in: 'path', required: true, schema: new OA\Schema(type: 'integer'))]
$responses: [new OA\Response(response: 200, description: 'Statut du paiement', content: new OA\JsonContent(properties: [new OA\Property(property: 'success', type: 'boolean', example: true), new OA\Property(property: 'data', properties: [new OA\Property(property: 'payment_id', type: 'integer', example: 42), new OA\Property(property: 'status', type: 'string', enum: ['COMPLETED', 'PENDING', 'FAILED'], example: 'PENDING'), new OA\Property(property: 'subscription_status', type: 'string', nullable: true, example: 'PENDING'), new OA\Property(property: 'order_status', type: 'string', nullable: true, example: null), new OA\Property(property: 'check_error', type: 'boolean', description: 'Présent (true) si Djomy n\'a pas pu être interrogé', example: true)], type: 'object')])), new OA\Response(response: 401, description: 'Non authentifié'), new OA\Response(response: 404, description: 'Paiement introuvable')]
#[IsGranted]
'IS_AUTHENTICATED_FULLY'
#[Route]
'/{id}/status'
$name: 'status'
$requirements: ['id' => '\d+']
$methods: ['GET']
Return values
JsonResponse —

Statut du paiement, ou objet d'erreur 404.


        
On this page

Search results