Salta ai contenuti

Eventi e iscrizioni

Apri come Markdown

Gli eventi che l’associazione pubblica dalla console sono disponibili sull’API con lo stesso principio delle tessere: copia «headless» (titolo, sommario, descrizione in markdown, immagini, luogo, date, link) e disponibilità in tempo reale per ogni tipo di iscrizione — mai chi è iscritto. Il vocabolario è quello del Terzo settore: si parla di iscrizione e, quando c’è un importo, di contributo.

visibility Chi la vede Chi si iscrive
members_only (predefinita) solo con un token del socio o del client dell’associazione i soci con tessera valida
public chiunque, anche senza accesso: GET /v1/aps/{slug}/events i soci e — se il tipo di iscrizione non richiede la tessera — gli ospiti

Un evento pubblico mostra ai visitatori del tuo sito la locandina e i tipi di iscrizione con i posti rimanenti; gli eventi riservati compaiono solo dopo l’accesso.

pagina pubblica, senza accesso
import { publicApi } from '@vimine/sdk';
const api = publicApi();
const { items } = await api.events.list('il-tuo-slug', { filter: 'upcoming' });
const evento = await api.events.get('il-tuo-slug', 'serata-jazz');
dopo Accedi con Vimine (anche gli eventi riservati ai soci)
const { items } = await vimine.events.list(); // events:read
const evento = await vimine.events.get('serata-jazz');

Ogni evento porta registration_types[]: amount (0 = gratuita), currency, remaining (posti rimasti, null = illimitati), open e — quando non è aperto — reason (sold_out, registration_not_open, registration_closed). status vale published, completed (la data è passata) o cancelled.

Senza scrivere codice: l’elemento <vimine-events> rende la lista con i pulsanti di iscrizione.

Un evento pubblico arriva anche a chi non è socio: è il momento in cui una persona decide di diventarlo. La pagina di iscrizione dell’associazione su Vimine si apre con l’evento, e la persona aderisce e prenota in un solo passaggio:

https://app.vimine.network/enroll/il-tuo-slug?event=serata-jazz
lo stesso indirizzo, dal tuo codice
import { eventEnrollUrl } from '@vimine/sdk/elements';
const url = eventEnrollUrl('https://app.vimine.network', 'il-tuo-slug', 'serata-jazz', 'it');

Che cosa succede al posto dipende da dove arriva l’adesione, e la pagina lo dice alla persona:

L’adesione Il posto
è attiva subito (tessera gratuita, nessuna approvazione) confermato, se l’iscrizione all’evento è gratuita
aspetta l’approvazione o la quota per un’iscrizione riservata ai soci: riservato finché la tessera non è attiva, e a quel punto, se è gratuita, si conferma da sola. Per un’iscrizione aperta a tutti: confermato subito, come per chi non è socio
l’iscrizione all’evento prevede un contributo riservato fino al termine che l’associazione ha fissato: si conferma quando registra il contributo
l’indirizzo e-mail non è ancora confermato nulla è riservato: il posto viene chiesto quando la persona conferma l’indirizzo dal link nella mail, e una mail le dice com’è andata

Chi è già socio usa la stessa pagina: accede e prenota con un pulsante, senza compilare nulla (&signin=1 apre subito l’accesso). Vale solo per gli eventi public pubblicati e non ancora passati: con qualunque altro slug la pagina è la normale pagina di iscrizione.

La pagina pubblica dell’evento su Vimine (/agenda/il-tuo-slug/serata-jazz) e <vimine-events> propongono già questa strada ai visitatori: Iscriviti all’associazione e prenota.

Prima di mostrare il pulsante chiedi all’API se il socio può iscriversi — la risposta spiega perché no:

const { can_register, types } = await vimine.events.eligibility('serata-jazz');
// types[i].reasons: membership_required, membership_not_active, membership_not_yet_valid, sold_out, max_per_user, registration_closed, …

Poi iscrivilo (registrations:write):

const reg = await vimine.registrations.create('serata-jazz', { registration_type: types[0].uid, note: 'Vengo con mia sorella' });
if (reg.status === 'confirmed') drawQr(reg.token); // iscrizione gratuita: posto confermato, QR pronto
if (reg.status === 'reserved') show(reg.payment_instructions); // con contributo: posto riservato fino al versamento
  • Un tipo gratuito conferma subito e restituisce token: è il contenuto del QR che il socio mostra all’ingresso (disegnalo tu, con la libreria che preferisci).
  • Un tipo con contributo riserva il posto (reserved_until) e restituisce le istruzioni di pagamento dell’associazione; la segreteria conferma quando registra il contributo — il socio riceve un’e-mail e da quel momento vimine.registrations.get(id) porta il token. Il pagamento con carta arriva con Stripe.
  • Se la tessera del socio è ancora in attesa di attivazione, l’iscrizione resta reserved e si conferma da sola quando la tessera diventa attiva.
  • 422 not_eligible porta in errors[] le stesse ragioni dell’idoneità.

Le iscrizioni del socio: vimine.registrations.list({ filter: 'upcoming' }); l’annullamento entro la finestra dell’evento (registration.cancellation_hours ore prima dell’inizio): vimine.registrations.cancel(id) — oltre, 409 window_closed.

Un visitatore senza account Vimine può iscriversi a un evento pubblico, su un tipo di iscrizione che non richiede la tessera, dal tuo server (client riservato, registrations:write):

server
await srv.registrations.guest('serata-jazz', { email, first_name, last_name, registration_type });
// → { status: 'accepted' }, sempre

Nessun account viene creato. L’ospite riceve un’e-mail con un link di conferma (valido 24 ore) che porta alla pagina dell’evento su Vimine: con un tipo gratuito il posto viene confermato lì e il QR mostrato subito; con un contributo il posto resta riservato con le istruzioni di pagamento. Se preferisci gestire tu la pagina di conferma, consuma il token del link con api.confirmRegistration(token).

Quando il posto è confermato — subito con un tipo gratuito, alla registrazione del contributo negli altri casi — l’ospite riceve una seconda e-mail con il proprio link: apre la pagina dell’evento con il QR da mostrare all’ingresso e funziona fino alla fine dell’evento (anche se l’evento viene spostato). Un ospite non ha un’area personale: il link è il suo posto, ma non il QR stesso (una mail inoltrata non è un posto). Se ospiti tu quella pagina, leggi il posto con api.viewRegistration(token) (SDK dalla 0.3.2).

La risposta è sempre 202 { status: 'accepted' }: l’API non rivela se un indirizzo è già iscritto. I problemi di idoneità (sold_out, membership_required per un tipo riservato ai soci) sono 422.

Il QR dell’iscrizione è un token firmato come quello della tessera: lo stesso scanner e la stessa chiamata lo accettano.

server (tornello, scanner, cassa)
const r = await srv.checkins.create(tokenLetto);
if (r.kind === 'registration') {
// r.verdict: valid | already_checked_in | not_confirmed | cancelled | event_cancelled | membership_invalid
// r.first: true al primo passaggio; r.membership_verdict quando il tipo richiede la tessera
}

Anche la verifica pubblica risponde a un token di iscrizione: GET /v1/verify/{token} → { status, kind: 'registration', event: { slug, starts_at } }, senza dati personali.

L’elenco delle iscrizioni di un evento — id, stato, tipo, tessera, ingresso, senza dati personali — è srv.registrations.listForEvent(slug, { status, limit, cursor }) (registrations:read, piani con gli elenchi via API). I nominativi restano nella console dell’associazione.