Incorporação e verificação das carteirinhas
O formulário de adesão no seu site
Seção intitulada “O formulário de adesão no seu site”Cada associação que ativou a adesão pública tem uma página https://app.vimine.network/enroll/<slug>
que pode ser colocada num iframe no site da associação:
<iframe src="https://app.vimine.network/enroll/your-slug" style="width:100%;min-height:900px;border:0"></iframe>A associação precisa incluir o domínio do site entre os seus domínios de incorporação, nas configurações. A página de login e de consentimento do Entrar com Vimine, por outro lado, não pode ser colocada num iframe: ela é sempre uma página inteira em vimine.network.
?locale=en abre o formulário em inglês (o elemento <vimine-enroll> o passa sozinho, a partir do idioma da página).
A aparência do formulário
Seção intitulada “A aparência do formulário”O formulário pode assumir as cores do seu site. Uma página num iframe não enxerga o CSS de quem a hospeda, então o estilo viaja no endereço:
| Parâmetro | Valores | |
|---|---|---|
scheme |
light, dark |
o esquema da página; sem ele, o do fundo ou o do visitante |
accent |
uma cor hexadecimal (1e3a5f) |
botões, links, campos em foco e o nome da associação |
background |
uma cor hexadecimal, ou transparent |
o fundo atrás dos cartões; transparent deixa a sua página aparecer |
font |
inter, roboto, open-sans, montserrat, nunito, lora, merriweather, roboto-slab, system |
a fonte da página inteira, campos incluídos, entre as que o próprio Vimine serve (system: a do dispositivo) |
<iframe src="https://app.vimine.network/enroll/your-slug?scheme=light&accent=1e3a5f&background=transparent" style="width:100%;min-height:900px;border:0"></iframe>Outros valores são ignorados. Com <vimine-enroll> não há endereço para escrever: defina --vimine-scheme, --vimine-accent,
--vimine-background e --vimine-typeface no seu CSS (elementos). Com transparent, escolha o esquema que se lê bem na
sua página: os cartões do formulário têm o seu próprio preenchimento, o texto fora deles fica sobre o seu.
Quem já tem uma conta Vimine
Seção intitulada “Quem já tem uma conta Vimine”Uma só identidade serve para todas as associações: quem já tem uma conta não precisa preencher o formulário de novo.
Aberta diretamente, a página …/enroll/<slug> reconhece a sessão e mostra uma só tela — o tipo de carteirinha, o
statuto e o aviso de privacidade desta associação, e só o que esta associação pede a mais (o endereço, quando ela
declarou que o coleta). O statuto e o aviso são aceitos todas as vezes: nada passa de uma associação para outra.
Dentro de um iframe a sessão não pode ser lida: um navegador mantém uma página emoldurada separada do mesmo site
aberto diretamente. Por isso o formulário no iframe oferece Já tem uma conta Vimine? Continue no Vimine, que abre a
página numa nova aba. Se você escreve o iframe à mão e usa sandbox, inclua allow-popups e
allow-popups-to-escape-sandbox, senão aquela aba continua dentro do sandbox; o <vimine-enroll> já faz isso.
O perfil público
Seção intitulada “O perfil público”GET /v1/aps/{slug} devolve o perfil público da associação — identidade visual, tipos de carteirinha com as taxas,
statuto em vigor — se você quiser construir uma experiência sua:
import { publicApi } from '@vimine/sdk';
const { aps, membership_types, statuto } = await publicApi().association('your-slug');Sem credenciais. A partir de uma página em que o associado fez Entrar com Vimine, você pode então receber o pedido:
const { aps, membership_types, statuto, privacy_notice } = await publicApi().association('your-slug');
await vimine.membership.request({ membership_type, accept_statuto: { version: statuto.version }, // o aviso de privacidade da associação, que a sua página mostrou privacy_notice: privacy_notice && { version: privacy_notice.version, sha256: privacy_notice.sha256, locale: privacy_notice.locale }, // o endereço, quando a associação o coleta (aps.member_address: 'optional' | 'required') address: { line: 'Via Roma 1', postal_code: '20100', city: 'Milano', province: 'MI' }});O que uma associação pede a quem solicita a adesão não depende da porta por onde o pedido chega:
- o aviso de privacidade. Enquanto a associação tiver um em vigor que a pessoa ainda não viu,
privacy_noticeé obrigatório: sem ele,422 validation_failedno campoprivacy_notice; com uma versão que não está mais em vigor,422 privacy_notice_outdated.vimine.legal.acceptances()diz o que ainda falta confirmar; o texto está emGET /v1/aps/{slug}/privacy-notice. A ciência fica guardada como um registro de prova ligado a esta carteirinha. - o endereço.
aps.member_addressdiz se a associação o coleta: comrequired, um pedido semaddressresponde422 validation_failedno campoaddress; comnone, ele é ignorado. - quem é a pessoa. Quando o perfil ainda não está identificado — nem um código fiscal, nem data, local e país de
nascimento — o pedido responde
422 identification_required: complete o perfil comvimine.me.update(...)e repita (veja Associados sem código fiscal).
Verificação das carteirinhas
Seção intitulada “Verificação das carteirinhas”A carteirinha digital é um token assinado (vmt_…) que o associado mostra como código QR. Ela pode ser verificada
de duas formas.
On-line
Seção intitulada “On-line”Sem credenciais, sem dados pessoais na resposta:
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: a carteirinha é autêntica e está ativa, mas a organização definiu um intervalo entre a admissão e o
momento em que a carteirinha pode ser usada. valid_from diz quando ela começa a valer; até lá, na entrada, é uma
carteirinha que não vale. O mesmo instante está no token (nbf), então um leitor off-line chega sozinho à mesma
resposta.
import { publicApi } from '@vimine/sdk';
const { status } = await publicApi().verifyCard(tokenReadFromQr);Off-line
Seção intitulada “Off-line”O token é assinado com Ed25519; as chaves públicas estão em
https://api.vimine.network/.well-known/vimine-card-keys.json (também GET /v1/card-keys, ou
publicApi().cardKeys()). Um leitor verifica três coisas com a chave em cache: a assinatura, a janela de validade (nbf/exp, no máximo 90
dias, depois o token muda) e que o status no payload seja ativo — s === "active". Depois ele sincroniza de novo
on-line quando a rede voltar. Um kid desconhecido
quer dizer que a chave mudou: recarregue as chaves.
O token muda a cada mudança de status, a cada renovação e, de qualquer forma, a cada 90 dias: uma captura de tela antiga não abre nada para sempre.
Uma carteirinha só existe para uma adesão ativa: enquanto o pedido está pendente (admissão ou taxa), e quando a
carteirinha está suspensa ou revogada, a API não emite nenhum token — card é null em GET /v1/me/membership, e
GET /v1/me/membership/card, a imagem, o e-mail e o link do Google Wallet respondem 409 not_active. Verificar s
continua obrigatório: isso recusa os tokens emitidos antes desta regra e qualquer token que não declare um status
ativo. Respeite também o nbf: uma organização pode decidir que uma carteirinha se torna utilizável algumas horas
depois da admissão, e esse instante viaja ali.
Código fiscal
Seção intitulada “Código fiscal”O código fiscal é opcional: quem não tem um se associa com a data, o local e o país de nascimento (veja
Associados sem código fiscal). Quando existe, POST /v1/validate/fiscal-code
(ou publicApi().validateFiscalCode(...)) verifica a estrutura e o caractere de controle de um codice fiscale italiano
e, se você também passar os dados pessoais, a coerência deles com o código — e diz o que o próprio código traz:
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 é invalid (estrutura ou caractere de controle), mismatch (um código bem formado que não confere com os dados
enviados) ou null; hints traz names_swapped quando o código confere trocando sobrenome e nome. Para uma
pessoa nascida no exterior, envie country (ISO 3166-1 alpha-2): o código dela só traz o país, e place — a cidade —
não é comparado.