服务器集成
对于协会自己的系统——管理软件、闸机、CMS 插件——使用带有 client_id + client_secret 的机密客户端。secret 只显示一次,绝不能出现在浏览器中。
认证
章节“认证”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 — 1 小时有效的令牌,自动续期不使用 SDK 时:POST /v1/oauth/token,带上 grant_type=client_credentials 和 HTTP Basic client_id:client_secret(或在请求体中传 client_id/client_secret):
curl -u "vmc_…:vms_…" -d "grant_type=client_credentials&scope=memberships:read" \ https://api.vimine.network/v1/oauth/token在读取端点(/v1/memberships/{id}/status、/v1/memberships)上,也可以直接使用 HTTP Basic,无需先获取令牌,方便硬件和低代码平台——但绝不能在浏览器中这样做。
会员卡状态
章节“会员卡状态”const s = await vimineServer.memberships.status('membership-uuid');// { id, status: 'active', verdict: 'valid', valid_until: '2027-…', membership_type: { cod: 'ORD' } }不含任何个人数据:只有状态和有效期。id 是会员在自己的会员卡上看到的 id(通过“使用 Vimine 登录”获得的 membership.id),或您的系统在登记该会员卡时收到的 id。
如需核验入场时出示的会员卡,请改用二维码中的令牌调用 /v1/verify/{card_token}:它完全不需要认证。
从您的系统为会员办理入会
章节“从您的系统为会员办理入会”拥有 identity:signup 和 enroll:write 后,您的管理系统可以创建账户并提交入会申请,无需当事人经过 Vimine:当事人会通过电子邮件收到链接,用于确认邮箱地址并设置密码。
// 仅创建账户(此人尚未入会)await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi' });
// 账户 + 待处理的入会申请,由秘书处在 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', // 可选:没有税号时,需要 dob + birthplace + birth_country dob: '1980-01-01', birthplace: 'Roma', birth_country: 'IT', gender: 'M', // 仅用于统计:不与税号比对 membership_type: membership_types[0].uid, // 只有一种类型时可省略 accept_statuto: { version: statuto.version, sha256: statuto.sha256 }, privacy_notice: privacy_notice && { version: privacy_notice.version, sha256: privacy_notice.sha256 } // 协会发布了隐私声明时必填});无论该地址背后是什么情况,响应始终是 202 { status: 'accepted' }:您无法得知某个电子邮箱是否已有 Vimine 账户(只有邮箱的所有者会通过邮件得知)。具体来说:
- 新地址 → 创建账户;使用
enroll时,还会创建一份待处理的入会申请;发送欢迎邮件,附带邮箱地址确认; - 已注册的地址 → 使用
enroll时不写入任何内容:邮箱所有者会收到一个“确认您向 <协会> 提交的申请”的链接,有效期 24 小时,只有在他使用该链接后才会创建申请。如果他已经是会员,则什么也不会发生; 422错误只与您的请求数据有关(带errors[].field的validation_failed、statuto_outdated、invalid_type);协会不接受申请时返回403 api_disabled;在内测期间账户只能凭邀请创建,此时返回403 not_available。
识别一个人,要么依靠税号,要么依靠出生日期、出生地和出生国(dob、birthplace、birth_country)——两者不能都没有:没有税号时,每缺少一项出生信息,errors[] 中就有一条 required。对于在国外出生的人,请务必发送 birth_country:他们的税号中只包含国家。税号与出生信息不一致时,返回 422,其中一条 codicefiscale_mismatch 带有 mismatches、hints 和 confirmable:当 confirmable 为 true 时,当事人可以确认该税号,您再带上 codicefiscale_confirmed: true 重复调用。如果协会登记会员的地址(公开资料中的 aps.member_address),请加上 address。如果协会收集监护人(行使父母责任者)的信息(aps.collects_guardian_data),且根据 dob 此人为未成年人,则 guardian 为必填——first_name、last_name、relation,可选 codicefiscale、email、phone——否则返回 422,并带有 guardian: required。完整流程见没有意大利税号的会员。
accept_statuto 必须指明现行章程:请在您的网站上向当事人展示章程(可在 association(slug) 中找到;文本和文件在 GET /v1/aps/{slug}/statuto),并传入其接受的版本。未登记可读章程的协会会返回 accepting_requests: false,申请则返回 403 not_available。协会面向会员的隐私声明也是如此(association(slug) 中的 privacy_notice,文本在 GET /v1/aps/{slug}/privacy-notice):协会发布了隐私声明时,申请必须指明当事人阅读的版本,否则返回 422(缺少 privacy_notice 或 privacy_notice_outdated);阅读确认以当事人的名义记录,并注明您的客户端。规则相同的可选项:accept_terms 和 acknowledge_privacy(账户使用条款和平台的隐私声明,GET /v1/legal/{kind}),在当事人已于您的网站上接受时传入。这些调用是幂等的:SDK 会为每次调用生成一个 Idempotency-Key,您也可以传入自己的键({ idempotencyKey: 'order-42' }),以便在超时后安全地重试。邮件有发送配额(每个地址每天 3 封),沙盒中从不发送邮件。
入场登记
章节“入场登记”拥有 checkins:write 后,入口处的设备通过发送从会员卡二维码中读取的令牌(而不是某个标识)来记录会员的通行:响应只有判定结果,不含任何个人数据。可以直接使用 HTTP Basic,方便硬件和低代码平台。
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 }curl -u "vmc_…:vms_…" -H "Content-Type: application/json" -d '{"token":"vmt_…"}' https://api.vimine.network/v1/checkins请求体为 { "token": "vmt_…" }——从二维码中读取的令牌,可以来自会员卡,也可以来自活动报名;仅对会员卡而言,card 也可作为别名使用。
格式错误或伪造的令牌返回 422 invalid_card;其他协会的会员卡则是“未找到”。
identity_check: 'pending' 是给入口值守人员的提示:该会员没有可核实的税号,协会中也还没有人查看过其证件。请把它显示出来;它不属于 verdict,也不限制任何操作(参见身份核对)。
会员卡列表(Pro 和 Network 套餐)
章节“会员卡列表(Pro 和 Network 套餐)”vimineServer.memberships.list({ status?, updated_since?, limit?, cursor? }) 分页返回(next_cursor)id、状态和日期——绝不含个人数据。使用 updated_since 只同步发生变化的内容。在不包含此功能的套餐上,响应为 403 plan_limit。
secret 轮换
章节“secret 轮换”在管理后台中(“重新生成 secret”):新的 secret 只显示一次,旧的 secret 继续有效 24 小时,因此您可以在不中断服务的情况下更新系统。如果怀疑 secret 已泄露,请撤销该客户端:它的所有会话会立即结束。
安全
章节“安全”- secret 多次输错,客户端会被锁定 15 分钟。
- 每个令牌都绑定在客户端所属的协会上:其他协会的会员卡只会显示为“未找到”。
- 使用刚轮换的凭据收到
401时,SDK 会用新令牌重试一次。 - 响应采用
application/problem+json(参见权限、错误与限制)。