8 Commits

Author SHA1 Message Date
Serreau Jovann
cda80990c7 Remove pending orders sync from StripeSyncCommand and add pessimistic lock to webhook payment handler
- Remove syncPendingOrders and its helpers (handleSucceeded, handleCancelled, handleFailed) from StripeSyncCommand
- Clean up unused dependencies (BilletOrderService, MailerService, AuditService, BilletBuyer)
- Add PESSIMISTIC_WRITE lock in handlePaymentIntentSucceeded to prevent duplicate ticket generation when Stripe sends concurrent webhook calls
- Update tests to match simplified command

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 10:19:40 +02:00
Serreau Jovann
2ffb407323 Fix failing tests: AttestationController payload keys and StripeSyncCommand event mock
- AttestationControllerTest: add required template keys (ref, organizer,
  generatedAt, etc.) to test payloads so check_ventes.html.twig renders
- StripeSyncCommandTest: add getAccount() mock to event in
  testPendingOrderFailedWithoutEmail so order is not skipped

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:34:37 +02:00
Serreau Jovann
534f67dfbe Fix testPendingOrderFailedWithoutEmail: add missing audit mock expectation
The audit->log() call in handleFailed was not configured on the mock,
causing an exception caught by the try/catch which prevented setStatus
from being called.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:23:34 +02:00
Serreau Jovann
03342e8303 Fix StripeSyncCommandTest: use Stripe\PaymentIntent::constructFrom instead of stdClass
PHPUnit strict mock validation rejects stdClass as return value for
retrievePaymentIntent which declares Stripe\PaymentIntent return type.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 19:16:32 +02:00
Serreau Jovann
02519dcfa8 Add pending orders reconciliation to stripe:sync command
- Add retrievePaymentIntent() to StripeService
- StripeSyncCommand now checks pending orders against Stripe API:
  - succeeded: generates tickets, sends emails, notifies organizer
  - canceled: marks order as cancelled + audit log
  - requires_payment_method: marks as cancelled + audit + failure email
  - other statuses: logs as still pending
- Add 13 tests covering accounts sync + all pending order scenarios

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 14:14:29 +02:00
Serreau Jovann
c207fd31b1 Add app:stripe:sync command to sync Stripe status for all organizers
Fetches charges_enabled and payouts_enabled from Stripe API for each
organizer with a connected account and updates the local database.
Also adds retrieveAccountStatus() to StripeService for testability.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 09:56:11 +01:00
Serreau Jovann
93e5ae67c0 Refactor Stripe integration: single Connect webhook, account pages, cleanup
Stripe webhook:
- Single webhook endpoint /stripe/webhook for Connect + payment events
- v2 Connect events configured manually in Stripe Dashboard (not via API)
- account.updated syncs charges_enabled/payouts_enabled via API retrieve
- Remove StripeSyncCommand and saveWebhookSecret (secret managed via Ansible vault)

Account page (/mon-compte):
- Buyer tabs: Billets, Achats, Factures, Parametres
- Organizer tabs: Evenements/Brocantes, Sous-comptes, Virements + buyer tabs
- Stripe Connect status banner: setup required, pending verification, active, refused
- Stripe Connect onboarding: create account, complete verification (GET links)
- Dashboard Stripe: opens in new tab via createLoginLink (Express dashboard)
- Cancel/close Stripe account: deletes via API + resets local fields
- Stripe required message on events/subaccounts/payouts tabs when not active
- Settings: organizer fields locked (name, address), email/phone editable
- Return/refresh routes for Stripe Connect onboarding flow
- Error handling with flash messages on all Stripe operations
- Auto-sync Stripe status on /mon-compte visit

StripeService cleanup:
- Remove syncWebhook, saveWebhookSecret, getWebhookUrl, projectDir
- Add deleteAccount method
- Keep: verifyWebhookSignature, createAccountConnect, createAccountLink, createLoginLink

Security:
- Add connect.stripe.com and dashboard.stripe.com to nelmio whitelist
- Add STRIPE_SK, STRIPE_WEBHOOK_SECRET, OUTSIDE_URL to .env.test

Tests: 19 AccountControllerTest, 4 StripeWebhookControllerTest, 1 StripeServiceTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 22:41:31 +01:00
Serreau Jovann
65887fb3da Add Stripe integration: webhook controller, service, sync command, Connect account
- Create StripeService: webhook sync, signature verification, save secret to .env.local
- Create StripeWebhookController with signature verification (400 on invalid)
- Create stripe:sync command to auto-create webhook endpoint via Stripe API
- Webhook listens to all events (configurable later)
- Save webhook secret automatically to .env.local on creation
- Add stripeAccountId field to User entity for Stripe Connect + migration
- Tests: StripeServiceTest (5), StripeWebhookControllerTest (2), StripeSyncCommandTest (1), UserTest updated

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 20:37:16 +01:00