Formulaire public : paiement de la cotisation via l'API SumUp (remplace Yapla)
Remplace le simple lien Yapla statique par une vraie intégration API SumUp : checkout hébergé créé à la soumission du formulaire, statut de paiement (PENDING/PAID/FAILED/EXPIRED) tenu à jour par un webhook SumUp et visible sur la fiche du bénévole. La cotisation n'est plus un montant unique : la coordination configure autant de types de paiement qu'elle veut (libellé + montant, ex. « Cotisation classique », « Mécénat »), et le bénévole en choisit un à l'inscription — le libellé et le montant choisis sont figés sur le bénévole, indépendamment d'une modification ultérieure de la config. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0be5daa89c
commit
0bd38a6465
+24
-13
@@ -92,19 +92,19 @@ async function checkPublicForm() {
|
||||
const beforeCount = (await api.volunteers.list(e)).length;
|
||||
|
||||
await api.forms.setFields(e, {
|
||||
fields: ['EMAIL', 'POSITION_WISHES', 'ARTIST_WISHES', 'COMMENT'],
|
||||
fields: ['EMAIL', 'POSITION_WISHES', 'ARTIST_WISHES', 'COMMENT', 'WILLING_TO_PAY_FEE'],
|
||||
});
|
||||
const config = await api.forms.getPublicConfig(e);
|
||||
if (!config.is_open) throw new Error('formulaire public : devrait être ouvert par défaut');
|
||||
if (config.positions.length !== positions.length) {
|
||||
throw new Error('formulaire public : postes manquants dans la config publique');
|
||||
}
|
||||
if (config.has_logo !== false || config.description !== null || config.yapla_url !== null) {
|
||||
throw new Error('formulaire public : logo/description/lien Yapla devraient être vides par défaut');
|
||||
if (config.has_logo !== false || config.description !== null || config.sumup_enabled !== false) {
|
||||
throw new Error('formulaire public : logo/description/SumUp devraient être vides par défaut');
|
||||
}
|
||||
// Le recadrage carré (canvas) et l'upload du logo (FileReader) sont des
|
||||
// API navigateur — non testables sous Node (voir scripts/smoke.tsx tel
|
||||
// qu'exécuté ici) ; seul le texte d'introduction et le lien Yapla sont
|
||||
// qu'exécuté ici) ; seul le texte d'introduction et la config SumUp sont
|
||||
// vérifiables ici.
|
||||
await api.forms.setOpen(e, { description: 'Bienvenue au festival de test !' });
|
||||
const configWithDescription = await api.forms.getPublicConfig(e);
|
||||
@@ -112,16 +112,24 @@ async function checkPublicForm() {
|
||||
throw new Error("formulaire public : le texte d'introduction ne revient pas correctement");
|
||||
}
|
||||
|
||||
let invalidYaplaUrlRejectedWith = 'non';
|
||||
let invalidSumupAmountRejectedWith = 'non';
|
||||
try {
|
||||
await api.forms.setOpen(e, { yapla_url: 'yapla.com/exemple' });
|
||||
await api.forms.paymentOptions.create(e, { label: 'Test invalide', amount: 0 });
|
||||
} catch (err) {
|
||||
invalidYaplaUrlRejectedWith = err instanceof ApiError ? err.code : String(err);
|
||||
invalidSumupAmountRejectedWith = err instanceof ApiError ? err.code : String(err);
|
||||
}
|
||||
await api.forms.setOpen(e, { yapla_url: 'https://www.yapla.com/fr/exemple' });
|
||||
const configWithYapla = await api.forms.getPublicConfig(e);
|
||||
if (configWithYapla.yapla_url !== 'https://www.yapla.com/fr/exemple') {
|
||||
throw new Error('formulaire public : le lien Yapla ne revient pas correctement');
|
||||
await api.forms.setOpen(e, {
|
||||
sumup_merchant_code: 'MXXXXXXX',
|
||||
sumup_api_key: 'sup_sk_test',
|
||||
});
|
||||
const classique = await api.forms.paymentOptions.create(e, {
|
||||
label: 'Cotisation classique',
|
||||
amount: 15,
|
||||
});
|
||||
await api.forms.paymentOptions.create(e, { label: 'Mécénat', amount: 50 });
|
||||
const configWithSumup = await api.forms.getPublicConfig(e);
|
||||
if (!configWithSumup.sumup_enabled || configWithSumup.payment_options.length !== 2) {
|
||||
throw new Error('formulaire public : la configuration SumUp ne revient pas correctement');
|
||||
}
|
||||
|
||||
const sameDay = artists.filter((a) => a.performance_date === artists[0]?.performance_date);
|
||||
@@ -161,6 +169,7 @@ async function checkPublicForm() {
|
||||
comment: 'Créé par le smoke test',
|
||||
position_wish_ids: positions.slice(0, 2).map((p) => p.id),
|
||||
artist_wish_ids: artists[0] ? [artists[0].id] : [],
|
||||
payment_option_id: classique.id,
|
||||
});
|
||||
const created = await api.volunteers.get(e, result.volunteer_id);
|
||||
const afterCount = (await api.volunteers.list(e)).length;
|
||||
@@ -170,12 +179,14 @@ async function checkPublicForm() {
|
||||
{
|
||||
formOpenByDefault: config.is_open,
|
||||
descriptionRoundTrips: configWithDescription.description,
|
||||
invalidYaplaUrlRejectedWith,
|
||||
yaplaUrlRoundTrips: configWithYapla.yapla_url,
|
||||
invalidSumupAmountRejectedWith,
|
||||
sumupEnabledRoundTrips: configWithSumup.sumup_enabled,
|
||||
tooManyPositionsRejectedWith,
|
||||
tooManyArtistsRejectedWith,
|
||||
createdVolunteerName: `${created.first_name} ${created.last_name}`,
|
||||
createdVolunteerAppearsInList: afterCount === beforeCount + 1,
|
||||
sumupCheckoutUrlReturned: result.sumup_checkout_url !== null,
|
||||
createdVolunteerFeeLabel: created.fee_payment_label,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
|
||||
Reference in New Issue
Block a user