Pular para o conteúdo

Integrações de servidor

Ver como Markdown

Para os sistemas da própria associação — um software de gestão, uma catraca, um plugin de CMS — um cliente confidencial com client_id + client_secret. O segredo é mostrado uma vez só e nunca deve chegar a um navegador.

Node
import { VimineServer } from '@vimine/sdk/server';
const vimineServer = new VimineServer({
clientId: 'vmc_…',
clientSecret: process.env.VIMINE_SECRET,
scopes: ['memberships:read']
});
const token = await vimineServer.token(); // client_credentials — token de 1 hora, renovado sozinho

Sem o SDK: POST /v1/oauth/token com grant_type=client_credentials e HTTP Basic client_id:client_secret (ou client_id/client_secret no corpo):

Janela do terminal
curl -u "vmc_…:vms_…" -d "grant_type=client_credentials&scope=memberships:read" \
https://api.vimine.network/v1/oauth/token

Nos endpoints de leitura (/v1/memberships/{id}/status, /v1/memberships) o HTTP Basic também é aceito diretamente, sem passar por um token, para hardware e plataformas low-code — nunca a partir de um navegador.

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

Nenhum dado pessoal: só status e validade. O id é o que o associado vê na própria carteirinha (membership.id via Entrar com Vimine) ou o que o seu sistema recebeu quando a registrou.

Para verificar uma carteirinha mostrada na entrada, use em vez disso o token do QR com /v1/verify/{card_token}: ele não precisa de nenhuma autenticação.

Com identity:signup e enroll:write o seu back office pode criar contas e enviar pedidos de adesão sem que a pessoa passe pelo Vimine: ela recebe por e-mail o link para confirmar o endereço e escolher uma senha.

// Só a conta (a pessoa ainda não é associada)
await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi' });
// Conta + pedido de adesão pendente, aprovado pela secretaria no back office do Vimine
const { statuto, membership_types } = await vimineServer.public.association('your-slug');
await vimineServer.enroll({
email: 'mario.rossi@example.org',
first_name: 'Mario',
last_name: 'Rossi',
codicefiscale: 'RSSMRA80A01H501U', // opcional: sem ele, são necessários dob + birthplace + birth_country
dob: '1980-01-01', birthplace: 'Roma', birth_country: 'IT',
gender: 'M', // só estatístico: não é conferido com o código
membership_type: membership_types[0].uid, // opcional quando existe exatamente um tipo
accept_statuto: { version: statuto.version, sha256: statuto.sha256 },
privacy_notice: privacy_notice && { version: privacy_notice.version, sha256: privacy_notice.sha256 } // obrigatório quando a associação publica um
});

A resposta é sempre 202 { status: 'accepted' }, seja o que for que exista por trás do endereço: você não tem como saber se um e-mail já tem uma conta Vimine (só o dono dele é avisado, por e-mail). Em detalhe:

  • endereço novo → conta criada e, com enroll, um pedido de adesão pendente; e-mail de boas-vindas com a confirmação do endereço;
  • endereço já cadastrado → com enroll nada é gravado: o dono recebe um link “confirme o seu pedido a <associação>” válido por 24 horas, e o pedido só é criado quando ele o usa. Se ele já é associado, nada acontece;
  • os erros 422 dizem respeito só ao seu payload (validation_failed com errors[].field, statuto_outdated, invalid_type); 403 api_disabled quando a associação não aceita pedidos; 403 not_available durante o beta privado, enquanto as contas só são criadas por convite.

Uma pessoa é identificada por um código fiscal ou pela data, local e país de nascimento (dob, birthplace, birth_country) — nunca por nenhum dos dois: sem um código, cada dado de nascimento que falta é uma entrada required em errors[]. Para uma pessoa nascida no exterior, envie sempre birth_country: o código dela só traz o país. Um código que não confere com os dados de nascimento responde 422 com uma entrada codicefiscale_mismatch que traz mismatches, hints e confirmable: quando confirmable é true a pessoa pode confirmá-lo, e você repete a chamada com codicefiscale_confirmed: true. Quando a associação coleta o endereço dos seus associados (aps.member_address no perfil público), adicione address. Quando ela coleta os dados de quem exerce o poder familiar (aps.collects_guardian_data) e a pessoa é menor de idade pelo dob, guardian é obrigatório — first_name, last_name, relation, opcionalmente codicefiscale, email, phone — senão 422 com guardian: required. O caminho completo está em Associados sem código fiscal.

accept_statuto precisa indicar o statuto em vigor: mostre-o à pessoa no seu site (ele está em association(slug); o texto e o documento, em GET /v1/aps/{slug}/statuto) e passe a versão que ela aceitou. Uma associação que não registrou nenhum statuto legível responde accepting_requests: false, e o pedido, 403 not_available. O mesmo vale para o aviso de privacidade aos associados da associação (privacy_notice em association(slug), o texto em GET /v1/aps/{slug}/privacy-notice): quando a associação publica um, o pedido precisa indicar a versão que a pessoa leu, senão 422 (privacy_notice ausente ou privacy_notice_outdated); a ciência fica registrada em nome da pessoa, com o seu cliente indicado. Opcionais, mesma regra: accept_terms e acknowledge_privacy (as condições de uso da conta e o aviso de privacidade da plataforma, GET /v1/legal/{kind}) quando a pessoa os aceitou no seu site. As chamadas são idempotentes: o SDK gera uma Idempotency-Key por chamada, ou passe a sua ({ idempotencyKey: 'order-42' }) para repetir com segurança depois de um timeout. Os e-mails têm um limite (3 por endereço por dia) e nunca são enviados a partir do sandbox.

Com checkins:write um dispositivo na entrada registra a passagem de um associado enviando o token lido no QR da carteirinha (não um identificador): a resposta é só o veredito, sem dados pessoais. O HTTP Basic é aceito diretamente, para hardware e plataformas low-code.

const r = await vimineServer.checkins.create('vmt_…'); // { verdict: 'valid' | 'expired' | 'not_yet_valid' | 'statuto_required' | 'inactive', status, membership_id, valid_until, identity_check, checked_in_at }
Janela do terminal
curl -u "vmc_…:vms_…" -H "Content-Type: application/json" -d '{"token":"vmt_…"}' https://api.vimine.network/v1/checkins

O corpo é { "token": "vmt_…" } — o token lido no QR, de uma carteirinha ou de uma inscrição em evento; só para as carteirinhas, card é aceito como alias.

Um token malformado ou falsificado é um 422 invalid_card; a carteirinha de outra associação é “não encontrada”.

identity_check: 'pending' é uma observação para quem cuida da entrada: o associado não tem um código fiscal verificável e ninguém da associação olhou um documento dele ainda. Mostre-a; ela não faz parte do verdict e não restringe nada (veja a verificação de identidade).

vimineServer.memberships.list({ status?, updated_since?, limit?, cursor? }) devolve ids, status e datas — nunca dados pessoais — em páginas (next_cursor). Com updated_since você sincroniza só o que mudou. Nos planos que não o incluem, a resposta é 403 plan_limit.

No console (Rotacionar segredo): o novo segredo é mostrado uma vez, o anterior continua funcionando por 24 horas, para que você possa atualizar os seus sistemas sem interrupção. Se suspeitar de um comprometimento, revogue o cliente: todas as sessões dele terminam na hora.

  • Um segredo errado, repetido, bloqueia o cliente por 15 minutos.
  • Cada token está vinculado à associação do cliente: uma carteirinha de outra associação é simplesmente “não encontrada”.
  • Um 401 com credenciais recém-rotacionadas é repetido uma vez pelo SDK com um token novo.
  • As respostas usam application/problem+json (veja Permissões, erros e limites).