Ir al contenido

VimineServer

Ver como Markdown
import { VimineServer } from '@vimine/sdk/server';
const vimineServer = new VimineServer({ clientId: 'vmc_…', clientSecret: process.env.VIMINE_SECRET });

Para los sistemas propios de la asociación: un cliente confidencial que se autentica con client_credentials, consulta el estado de los carnés y gestiona su sandbox. Node ≥ 18. El secreto nunca debe llegar a un navegador.

Opción Tipo Por defecto
clientId string — obligatorio
clientSecret string — obligatorio; vms_… o vms_test_…
scopes Scope[] todos los registrados un subconjunto que solicitar
apiUrl string https://api.vimine.network
fetch typeof fetch globalThis.fetch

Un token de acceso de cliente (client_credentials, HTTP Basic), en caché hasta 30 segundos antes de que caduque (1 hora); una sola petición aunque haya llamadas concurrentes.

Una llamada autenticada con Authorization: Bearer; JSON de entrada y de salida; errores como VimineError. Un 401 (credenciales regeneradas o revocadas) se repite una vez con un token nuevo.

Estado de una inscripción de la asociación, sin datos personales (memberships:read):

const s = await vimineServer.memberships.status('membership-uuid');
// { id, status: 'active', verdict: 'valid', valid_until: '2027-03-31T22:59:59.000Z', membership_type: { cod: 'ORD' } }

Crea una cuenta de Vimine para una persona (identity:signup): recibe el correo para confirmar su dirección y elegir una contraseña. Responde siempre { status: 'accepted' } — no se te revela si la dirección ya tenía una cuenta (se le avisa a su titular, por correo). opts.idempotencyKey (se genera si falta).

await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi', phone: '+39 …' });

Envía una solicitud de inscripción para una persona (enroll:write): una dirección nueva recibe una cuenta y una solicitud pendiente; el titular de una cuenta existente recibe en cambio un enlace de confirmación (no se escribe nada hasta que lo usa). accept_statuto (la versión en vigor) es obligatorio; también lo es privacy_notice cuando la asociación publica una política de privacidad para sus socios (association(slug).privacy_notice): la persona la lee en tu sitio y tú pasas la versión mostrada. Consulta Integraciones de servidor.

La persona se identifica con codicefiscale o con dob + birthplace + birth_country — nunca sin ninguno de los dos (422, una entrada required por cada dato de nacimiento que falte). Un código que no coincide con los datos de nacimiento es una entrada codicefiscale_mismatch en err.errors, con mismatches, hints y confirmable: cuando confirmable es true y la persona lo confirma, repite con codicefiscale_confirmed: true. address (MemberAddress) cuando la asociación recoge la dirección de sus socios (aps.member_address). Consulta Socios sin código fiscal.

// con código fiscal
await vimineServer.enroll({ ...person, codicefiscale: 'RSSMRA80A01H501U', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }, { idempotencyKey: 'order-42' });
// sin él: fecha, lugar y país de nacimiento
await vimineServer.enroll({ ...person, dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } });

Registra un check-in en la entrada a partir del token leído en el QR (checkins:write). Un carné responde { kind: 'card', verdict, status, membership_id, valid_until, valid_from, identity_check, checked_in_at } — identity_check: 'pending' es una nota que hay que mostrar a quien atiende la entrada, no forma parte de verdict y no restringe nada (guía); el QR de una inscripción a un evento responde { kind: 'registration', verdict, registration_id, event, first, membership_verdict, … } (consulta Eventos e inscripciones).

events.list(params?) · events.get(slug) — los eventos publicados de la asociación, incluidos los que son solo para socios (cualquier token de cliente).

registrations.listForEvent(slug, { status?, limit?, cursor? }) las inscripciones de un evento: id, estado, tipo, condición de socio, check-in — sin datos personales (registrations:read, planes con listas por API)
registrations.guest(slug, { email, first_name, last_name, registration_type, note? }, opts?) inscribe a un invitado sin cuenta en un evento público; siempre { status: 'accepted' }; Idempotency-Key generada (consulta invitados)

Las inscripciones de la asociación (memberships:read, planes con listas): { items: [{ id, status, verdict, membership_type, issued_at, valid_until, updated_at }], next_cursor }; params: status, updated_since, limit, cursor.

Solo para clientes de prueba: los socios sintéticos del sandbox y el restablecimiento (contraseña común nueva, devuelta una sola vez). Un cliente de producción recibe 403.

Los endpoints públicos, sin credenciales: consulta publicApi.

express.js
import express from 'express';
import { VimineServer, VimineError } from '@vimine/sdk/server';
const vimineServer = new VimineServer({ clientId: process.env.VIMINE_CLIENT_ID, clientSecret: process.env.VIMINE_SECRET });
const app = express();
app.get('/cards/:id/status', async (req, res) => {
try {
const { status, verdict, valid_until } = await vimineServer.memberships.status(req.params.id);
res.json({ status, verdict, valid_until });
} catch (err) {
if (err instanceof VimineError && err.code === 'not_found') return res.status(404).end();
throw err;
}
});