Intégration et vérification des cartes
Le formulaire d’adhésion sur votre site
Section intitulée « Le formulaire d’adhésion sur votre site »Chaque association qui a activé l’adhésion publique a une page https://app.vimine.network/enroll/<slug>
qui peut être placée dans une iframe sur le site de l’association :
<iframe src="https://app.vimine.network/enroll/your-slug" style="width:100%;min-height:900px;border:0"></iframe>L’association doit indiquer le domaine du site parmi ses domaines d’intégration dans ses réglages. La page de connexion et de consentement de Se connecter avec Vimine, en revanche, ne peut pas être placée dans une iframe : elle s’affiche toujours en pleine page sur vimine.network.
?locale=en ouvre le formulaire en anglais (l’élément <vimine-enroll> le transmet de lui-même, à partir de la
langue de la page).
L’apparence du formulaire
Section intitulée « L’apparence du formulaire »Le formulaire peut prendre les couleurs de votre site. Une page dans une iframe ne voit pas le CSS de la page qui l’accueille : le style voyage donc dans l’adresse.
| Paramètre | Valeurs | |
|---|---|---|
scheme |
light, dark |
le thème de la page ; sans lui, celui de l’arrière-plan ou du visiteur |
accent |
une couleur hexadécimale (1e3a5f) |
boutons, liens, champs actifs et nom de l’association |
background |
une couleur hexadécimale, ou transparent |
le fond derrière les encadrés ; transparent laisse voir votre page |
font |
inter, roboto, open-sans, montserrat, nunito, lora, merriweather, roboto-slab, system |
la police de toute la page, champs compris, parmi celles que Vimine sert lui-même (system : celle de l’appareil) |
<iframe src="https://app.vimine.network/enroll/your-slug?scheme=light&accent=1e3a5f&background=transparent" style="width:100%;min-height:900px;border:0"></iframe>Les autres valeurs sont ignorées. Avec <vimine-enroll>, il n’y a pas d’adresse à écrire : définissez
--vimine-scheme, --vimine-accent, --vimine-background et --vimine-typeface dans votre CSS
(éléments). Avec transparent, choisissez le thème qui se lit sur votre page : les encadrés du
formulaire ont leur propre fond, le texte en dehors repose sur le vôtre.
Une personne qui a déjà un compte Vimine
Section intitulée « Une personne qui a déjà un compte Vimine »Une seule identité sert pour toutes les associations : une personne qui a déjà un compte n’a pas à remplir le
formulaire de nouveau. Ouverte directement, la page …/enroll/<slug> reconnaît la session et affiche un seul
écran — le type d’adhésion, le statuto et la notice d’information sur la vie privée de cette association, et
seulement ce que cette association demande en plus (l’adresse, si elle a déclaré la recueillir). Le statuto et la
notice sont acceptés à chaque fois : rien ne passe d’une association à une autre.
Dans une iframe, la session ne peut pas être lue : un navigateur tient une page encadrée à l’écart du même site ouvert
directement. Le formulaire encadré propose donc Vous avez déjà un compte Vimine ? Continuer sur Vimine, qui ouvre la
page dans un nouvel onglet. Si vous écrivez l’iframe à la main et utilisez sandbox, incluez allow-popups et
allow-popups-to-escape-sandbox, sinon cet onglet reste dans le bac à sable ; <vimine-enroll> le fait déjà.
Le profil public
Section intitulée « Le profil public »GET /v1/aps/{slug} renvoie le profil public de l’association — identité visuelle, types d’adhésion avec leurs
cotisations, statuto en vigueur — si vous voulez construire votre propre parcours :
import { publicApi } from '@vimine/sdk';
const { aps, membership_types, statuto } = await publicApi().association('your-slug');Aucun identifiant. Depuis une page où le membre a fait Se connecter avec Vimine, vous pouvez ensuite recueillir la demande :
const { aps, membership_types, statuto, privacy_notice } = await publicApi().association('your-slug');
await vimine.membership.request({ membership_type, accept_statuto: { version: statuto.version }, // la notice d’information de l’association, que votre page a affichée privacy_notice: privacy_notice && { version: privacy_notice.version, sha256: privacy_notice.sha256, locale: privacy_notice.locale }, // l’adresse, si l’association en recueille une (aps.member_address: 'optional' | 'required') address: { line: 'Via Roma 1', postal_code: '20100', city: 'Milano', province: 'MI' }});Ce qu’une association demande à une personne qui adhère ne dépend pas de la porte par laquelle arrive la demande :
- la notice d’information. Tant que l’association en a une en vigueur que la personne n’a pas encore vue,
privacy_noticeest obligatoire : sans elle,422 validation_failedsur le champprivacy_notice; avec une version qui n’est plus en vigueur,422 privacy_notice_outdated.vimine.legal.acceptances()dit ce qui reste à confirmer ; le texte estGET /v1/aps/{slug}/privacy-notice. La prise de connaissance est conservée comme une ligne de preuve liée à cette adhésion. - l’adresse.
aps.member_addressdit si l’association la recueille : avecrequired, une demande sansaddressrépond422 validation_failedsur le champaddress; avecnone, elle est ignorée. - qui est la personne. Quand le profil n’est pas encore identifié — ni code fiscal, ni date, lieu et pays de
naissance — la demande répond
422 identification_required: complétez le profil avecvimine.me.update(...)et répétez (voir Membres sans code fiscal).
Vérification des cartes
Section intitulée « Vérification des cartes »La carte numérique est un jeton signé (vmt_…) que le membre montre sous forme de code QR. Elle peut être vérifiée
de deux façons.
En ligne
Section intitulée « En ligne »Sans identifiants, sans données personnelles dans la réponse :
GET https://api.vimine.network/v1/verify/vmt_…→ { "status": "active", "valid_until": "2027-03-31T22:59:59.000Z" } ou→ { "status": "inactive", "reason": "expired" } ou→ { "status": "inactive", "reason": "not_yet_valid", "valid_from": "2026-09-19T19:00:00.000Z" }not_yet_valid : la carte est authentique et l’adhésion est active, mais l’organisation a fixé un délai entre
l’admission et le moment où la carte peut être utilisée. valid_from dit quand elle commence à faire foi ; jusque-là,
à l’entrée, c’est une carte qui ne compte pas. Le même instant figure dans le jeton (nbf), si bien qu’un scanner hors
ligne arrive seul à la même réponse.
import { publicApi } from '@vimine/sdk';
const { status } = await publicApi().verifyCard(tokenReadFromQr);Hors ligne
Section intitulée « Hors ligne »Le jeton est signé en Ed25519 ; les clés publiques sont sur
https://api.vimine.network/.well-known/vimine-card-keys.json (aussi GET /v1/card-keys, ou
publicApi().cardKeys()). Un scanner vérifie trois choses avec la clé en cache : la signature, la fenêtre de
validité (nbf/exp, 90 jours au plus, puis le jeton change) et que l’état dans le payload est actif —
s === "active". Puis il se resynchronise en ligne quand le réseau revient. Un kid inconnu
signifie que la clé a changé : rechargez les clés.
Le jeton change à chaque changement d’état, à chaque renouvellement et, de toute façon, tous les 90 jours : une vieille capture d’écran n’ouvre rien pour toujours.
Une carte n’existe que pour une adhésion active : tant que la demande est en attente (admission ou cotisation), et
quand l’adhésion est suspendue ou révoquée, l’API n’émet aucun jeton — card vaut null dans
GET /v1/me/membership, et GET /v1/me/membership/card, l’image, l’e-mail et le lien Google Wallet répondent
409 not_active. Vérifier s reste obligatoire : cela rejette les jetons émis avant cette règle et tout jeton qui ne
déclare pas un état actif. Respectez aussi nbf : une organisation peut décider qu’une carte devient utilisable
quelques heures après l’admission, et c’est là que cet instant voyage.
Code fiscal
Section intitulée « Code fiscal »Le code fiscal est facultatif : une personne qui n’en a pas adhère avec sa date, son lieu et son pays de naissance
(voir Membres sans code fiscal). Quand il y en a un, POST /v1/validate/fiscal-code
(ou publicApi().validateFiscalCode(...)) vérifie la structure et le caractère de contrôle d’un codice fiscale italien
et, si vous passez aussi les données personnelles, leur cohérence avec le code — et dit ce que le code lui-même
contient :
const r = await publicApi().validateFiscalCode({ code: 'RSSMRA80A01H501U', first_name: 'Mario', last_name: 'Rossi', date: '1980-01-01', place: 'Roma', country: 'IT' });// { valid: true, error: null, mismatches: [], hints: [], birth_date: '1980-01-01', birth_country: 'IT' }// ou// { valid: false, error: 'mismatch', mismatches: ['date'], hints: [], birth_date: '1980-01-01', birth_country: 'IT' }error vaut invalid (structure ou caractère de contrôle), mismatch (un code bien formé qui est en désaccord avec
les données envoyées) ou null ; hints contient names_swapped quand le code correspond une fois le nom et le
prénom intervertis. Pour une personne née à l’étranger, envoyez country (ISO 3166-1 alpha-2) : son code ne contient
que l’État, et place — la ville — n’est pas comparé.