Payout system:
- Create Payout entity (stripePayoutId, status, amount, currency, destination, arrivalDate)
- Webhook handles payout.created/updated/paid/failed/canceled with email notification
- Payout list in /mon-compte virements tab with status badges
- PDF attestation on paid payouts with email attachment
PDF attestation:
- dompdf with DejaVu Sans font, yellow-orange gradient background
- Orange centered title bar, E-Cosplay logo, emitter/beneficiary info blocks
- QR code linking to /attestation/check/{payoutId} for authenticity verification
- Public verification page: shows payout details if valid, error if altered
- Legal disclaimer and CGV reference
- Button visible only when status is paid, opens in new tab
Sub-accounts:
- Add parentOrganizer (self-referencing ManyToOne) and subAccountPermissions (JSON) to User
- Permissions: scanner (validate tickets), events (CRUD), tickets (free invitations)
- Create sub-account with random password, send email with credentials
- Edit page with name/email/permissions checkboxes
- Delete with confirmation
- hasPermission() helper method
Account improvements:
- Block entire page for unapproved organizers with validation pending message
- Display stripeStatus in Stripe Connect banners
- Remove test payout button
Webhook v2 Connect events:
- v2.core.account.created/updated/closed → update stripeStatus
- capability_status_updated → sync charges/payouts enabled from capabilities
- PayoutPdfService for reusable PDF generation
Migrations: stripeStatus, Payout table, sub-account fields, drop pdfPath
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
45 lines
2.5 KiB
Twig
45 lines
2.5 KiB
Twig
{% extends 'email/base.html.twig' %}
|
|
|
|
{% block title %}Mise a jour de votre virement{% endblock %}
|
|
|
|
{% block content %}
|
|
<h2>Bonjour {{ firstName }} !</h2>
|
|
<p>Votre virement a ete mis a jour.</p>
|
|
<table style="width:100%;border-collapse:collapse;margin:24px 0;">
|
|
<thead>
|
|
<tr>
|
|
<th style="padding:8px 12px;font-weight:700;font-size:12px;color:#a1a1aa;text-align:left;text-transform:uppercase;letter-spacing:0.05em;border-bottom:2px solid #e4e4e7;">Detail</th>
|
|
<th style="padding:8px 12px;font-weight:700;font-size:12px;color:#a1a1aa;text-align:left;text-transform:uppercase;letter-spacing:0.05em;border-bottom:2px solid #e4e4e7;">Valeur</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td style="padding:8px 12px;font-weight:700;font-size:14px;color:#18181b;border-bottom:1px solid #e4e4e7;">Reference</td>
|
|
<td style="padding:8px 12px;font-size:14px;color:#3f3f46;border-bottom:1px solid #e4e4e7;font-family:monospace;">{{ payoutId }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:8px 12px;font-weight:700;font-size:14px;color:#18181b;border-bottom:1px solid #e4e4e7;">Montant</td>
|
|
<td style="padding:8px 12px;font-size:14px;color:#3f3f46;border-bottom:1px solid #e4e4e7;font-weight:700;">{{ amount }} {{ currency|upper }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:8px 12px;font-weight:700;font-size:14px;color:#18181b;border-bottom:1px solid #e4e4e7;">Statut</td>
|
|
<td style="padding:8px 12px;font-size:14px;border-bottom:1px solid #e4e4e7;">
|
|
{% if status == 'paid' %}
|
|
<span style="background:#d1fae5;padding:2px 8px;font-weight:700;">{{ status|upper }}</span>
|
|
{% elseif status == 'failed' or status == 'canceled' %}
|
|
<span style="background:#fee2e2;padding:2px 8px;font-weight:700;">{{ status|upper }}</span>
|
|
{% else %}
|
|
<span style="background:#fef3c7;padding:2px 8px;font-weight:700;">{{ status|upper }}</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% if arrivalDate %}
|
|
<tr>
|
|
<td style="padding:8px 12px;font-weight:700;font-size:14px;color:#18181b;">Date d'arrivee</td>
|
|
<td style="padding:8px 12px;font-size:14px;color:#3f3f46;">{{ arrivalDate }}</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
{% endblock %}
|