没有意大利税号的会员
加入协会并不需要意大利税号(codice fiscale)。需要的是当事人的身份已被识别;在 Vimine 上,有两种方式:
- 通过税号,或者
- 通过出生信息:
dob+birthplace+birth_country(ISO 3166-1 alpha-2)。
两者不能都没有。本指南的其余部分逐个字段说明,对于为他人办理入会的集成——交换生、刚到意大利的志愿者、住在国外的会员——有哪些变化。
识别一个人
章节“识别一个人”POST /v1/enroll 和 POST /v1/signup 接受相同的字段:
| 字段 | |
|---|---|
codicefiscale |
可选。提供时会进行校验,并与姓名、出生日期和出生地比对 |
dob |
出生日期,YYYY-MM-DD |
birthplace |
在意大利出生的人填市镇(comune);在国外出生的人填城市,自由文本 |
birth_country |
出生国,两个字母(IT、FR、SN…) |
gender |
仅用于统计:不再与税号比对 |
// 没有税号:出生日期、出生地和出生国await vimineServer.enroll({ email: 'marie.dupont@example.org', first_name: 'Marie', last_name: 'Dupont', dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR', accept_statuto: { version: statuto.version, sha256: statuto.sha256 }});在 /v1/enroll 上,没有税号时,每缺少一项出生信息,就返回 422 validation_failed,并在 errors[] 中有一条记录:
{ "code": "validation_failed", "errors": [{ "field": "birth_country", "code": "required" }] }/v1/signup 只创建账户:在这里出生信息仍是可选的,等当事人申请会员资格时才需要。
在国外出生:发送 birth_country
章节“在国外出生:发送 birth_country”在意大利出生的人,税号中包含出生市镇;在国外出生的人,税号中只包含国家。因此,对后者的比对看的是 birth_country,并把 birthplace(城市)当作自由文本。发送 birth_country,正是让持有有效税号、在国外出生的人通过校验的关键:如果不发送,“Lyon”会被当作意大利市镇去查找,税号就会显得不一致。(以前把国家的意大利语名称当作出生地发送的表单——birthplace: 'Francia'——仍然可以通过;但更推荐使用 birth_country。)
公开校验接口也是如此,现在它还会说明税号中包含什么:
const r = await publicApi().validateFiscalCode({ code: 'DPNMRA85C50Z110U', first_name: 'Marie', last_name: 'Dupont', date: '1985-03-10', place: 'Lyon', country: 'FR'});// { valid: true, error: null, mismatches: [], hints: [], birth_date: '1985-03-10', birth_country: 'FR' }birth_date 和 birth_country 是从税号本身读取的:您可以用它们预填表单。如果您发送了 gender,这个端点仍会比对它;入会和个人资料则不会。
不一致的税号与确认
章节“不一致的税号与确认”输错的税号(结构或校验码有误)返回 invalid_codicefiscale:必须更正,永远不能确认。格式正确但与所填信息不一致的税号,则返回 422,并带有一条信息更丰富的记录:
{ "code": "validation_failed", "errors": [{ "field": "codicefiscale", "code": "codicefiscale_mismatch", "mismatches": ["place"], "hints": [], "confirmable": true }]}mismatches——哪些地方不一致:lastName、firstName、date、place;hints——当姓和名互换后税号能对上时,为names_swapped:通常提示对方互换即可;confirmable——当事人能否确认这就是其医保卡(tessera sanitaria)上的税号。这种情况确实会发生:已撤销的市镇、音译、以另一种顺序登记的姓名。
当 confirmable 为 true 时,请询问当事人,并带上 codicefiscale_confirmed: true 重复请求。当姓、名和出生日期全都不一致时,就再也没有什么能把这个税号和这个人联系起来:confirmable 为 false,唯一的办法是更正。
import { VimineError } from '@vimine/sdk/server';
try { await vimineServer.enroll(input);} catch (err) { const entry = err instanceof VimineError && err.errors?.find((e) => e.code === 'codicefiscale_mismatch'); if (!entry) throw err; if (entry.confirmable && (await askThePerson(entry.mismatches, entry.hints))) { await vimineServer.enroll({ ...input, codicefiscale_confirmed: true }); }}不要自作主张发送 codicefiscale_confirmed:这是当事人的声明,并会作为声明被记录。
之后再补充税号
章节“之后再补充税号”入会时没有税号的人,在取得税号后可以在自己的个人资料中补充:
const me = await vimine.me.update({ codicefiscale: 'DPNMRA85C50Z110U' });me.codicefiscale_check; // 'matched'PATCH /v1/me 接受 birth_country 和只写字段 codicefiscale_confirmed;codicefiscale 也可以重新设为 null。GET /v1/me 说明当事人是如何被识别的:
codicefiscale_check |
|
|---|---|
matched |
税号与当事人的出生信息一致 |
mismatch_confirmed |
税号不一致,但已由当事人确认 |
absent |
没有税号:通过出生日期、出生地和出生国识别 |
null |
尚未识别:不能申请会员资格 |
matched 的意思是一致,而不是已经过税务登记机关核实:税号始终是当事人申报的信息。
identification_required
章节“identification_required”账户可以存在但尚未识别身份——例如只为登录而注册的人。当这样的人申请会员资格时,API 会明确指出,并列出缺少什么:
POST /v1/me/membership→422 identification_required,errors[]为缺少的出生信息({ field: 'birthplace', code: 'required' }…)。请引导当事人通过PATCH /v1/me(权限profile:write)完善个人资料,然后重复请求。POST /v1/enroll/confirm——已有账户的所有者收到的“确认您的申请”链接 →409 identification_required,errors[]相同。请在页面上询问出生信息,并带上identification再次提交令牌:
await publicApi().confirmEnrollment(token, { dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR' });// POST /v1/enroll/confirm { token, identification: { dob, birthplace, birth_country, codicefiscale?, codicefiscale_confirmed? } }出生信息放在请求体中传送,绝不放在链接中:链接里从来没有任何个人信息。identification 只补全个人资料中的空字段,不会覆盖已有内容;如果校验不通过,响应就是上文那样的 422 validation_failed。
入会审批不变:pending_reasons 对所有人都取决于协会的入会模式(参见入会审批与生效)。
入场时:身份核对
章节“入场时:身份核对”与出生信息一致的税号可以据此核对;仅有出生信息,或由当事人确认的税号,则无法核对。对于这些会员,协会会在当事人第一次到场时查看一次证件。集成扫码器的开发者会在 POST /v1/checkins(权限 checkins:write)针对会员卡的响应中看到它:
const r = await vimineServer.checkins.create('vmt_…');// { kind: 'card', verdict: 'valid', …, identity_check: 'pending' }if (r.identity_check === 'pending') show('首次入场:请查验证件');identity_check |
|
|---|---|
pending |
该会员没有可核实的税号,协会中也还没有人查看过其证件:请把它显示给入口值守人员 |
verified |
协会中已有人查看过证件 |
flagged |
有人查看过证件,但与信息不符:由协会秘书处接手处理 |
null |
无需核对 |
这只是一条提示,不属于 verdict,也不限制任何操作:带有 identity_check: 'pending' 的 valid 会员卡照样可以入场。核对结果在协会的管理后台中记录,而不是通过 API。公开核验接口 GET /v1/verify/{card_token} 从不携带它:从外部核验会员卡的人只能看到状态和到期日。
地址
章节“地址”有些协会会在会员登记册中保存会员的地址,有些则不会。这由协会决定,并且对所有会员都适用,或对所有会员都不适用;公开资料中会声明:
GET https://api.vimine.network/v1/aps/{slug}→ { "aps": { …, "member_address": "optional" } }member_address |
|
|---|---|
none |
不要询问:即使发送了 address 也不会保存 |
optional |
询问,但不强制 |
required |
没有 address 时,入会返回 422,并带有 { field: 'address', code: 'required' } |
await vimineServer.enroll({ …, address: { kind: 'residence', line: 'Via Roma 1', postal_code: '20121', city: 'Milano', province: 'MI', country: 'IT' }});address 中的 line 和 city 为必填;kind 为 residence(默认,户籍地)或 domicile(住所地,与户籍地不同时填写);省略 country 时为 IT;province 仅适用于意大利地址。/v1/signup 没有 address:地址属于会员资格,而不属于账户。
协会不能强制要求税号
章节“协会不能强制要求税号”不存在“税号必填”这样的设置。协会不能要求每位申请人都提供税号:没有税号的人,在任何地方都通过出生信息来识别。如果您的表单把税号设为必填,那是您的表单的选择——它会把协会本可以接纳的人挡在门外。
变更内容(2026-09-19 版)
章节“变更内容(2026-09-19 版)”全部为新增:始终发送税号的表单无需任何改动即可继续使用。现有集成可能会注意到:
POST /v1/enroll中的codicefiscale不再是必填项;没有税号时,需要dob、birthplace和birth_country(每缺少一项返回422required);- 新的可选字段
birth_country、codicefiscale_confirmed(enroll、signup、PATCH /v1/me)和address(enroll); gender不再与税号比对:不会再因为性别单独返回422;- 不一致的税号仍返回
codicefiscale_mismatch,现在在mismatches之外还带有hints和confirmable;格式错误的税号仍是invalid_codicefiscale; GET/PATCH /v1/me现在有声明的 schema(Me),包含birth_country和codicefiscale_check;- 新错误
identification_required:在POST /v1/me/membership上为422,在POST /v1/enroll/confirm上为409(后者在请求体中接受identification); POST /v1/validate/fiscal-code接受country,并且还返回hints、birth_date、birth_country;error为invalid、mismatch或null;POST /v1/checkins在针对会员卡的响应中增加了identity_check;GET /v1/verify/{card_token}保持不变;- 公开资料增加了
aps.member_address。