Appearance
SmileID Phone Number Verification 接入说明
官方文档:https://docs.usesmileid.com/products/for-individuals-kyc/phone-number-verification
更新时间参考:官方页面显示 Last updated 3 months ago
1. 功能场景
Phone Number Verification 是 SmileID 的手机号身份验证产品,用手机号和提交的匹配字段做身份核验。官方说明该产品适用于低摩擦身份验证、基础 KYC、触达 unbanked population 等场景。
当前官方说明的覆盖范围:
- Ghana
- South Africa
- Tanzania
- Uganda
- 覆盖这些区域超过 330 million phone numbers
这个产品不是短信 OTP,不负责发送验证码。它验证的是:提交的 phone_number 与 match_fields 中的字段,在 SmileID 可用的数据源记录中是否匹配。
2. 接口地址
官方只支持 REST API,并提供同步和异步两个接口。官方建议大多数场景优先使用异步接口。
Base URL:
| 环境 | Base URL |
|---|---|
| Sandbox | https://testapi.smileidentity.com |
| Production | https://api.smileidentity.com |
| Dev | https://devapi.smileidentity.com |
Endpoint:
| 类型 | Method | Endpoint | 官方说明 |
|---|---|---|---|
| 异步 | POST | /v2/async-verify-phone | 推荐用于大多数集成,更适合处理网络延迟 |
| 同步 | POST | /v2/verify-phone-number | 适合需要立即返回结果的场景 |
3. 请求 Header
两个 endpoint 都使用相同 Header:
| Header | 是否必填 | 说明 | 示例 |
|---|---|---|---|
smileid-partner-id | 是 | SmileID Partner ID | 002 |
smileid-request-signature | 是 | 请求签名 | sample-signature |
smileid-timestamp | 是 | 请求时间戳 | 2024-07-30T19:16:56.426Z |
smileid-source-sdk | 是 | 来源 SDK 标识 | rest_api |
smileid-source-sdk-version | 是 | 来源 SDK 版本 | 1.0.0 |
签名规则沿用 SmileID REST API 签名规则:
text
Base64(HMAC-SHA256(timestamp + partner_id + "sid_request", api_key))注意:Header 名称按官方文档使用小写形式即可;HTTP Header 本身大小写不敏感,但实现时建议和官方保持一致。
4. 请求 Body
Content-Type:
http
application/json官方示例请求体:
json
{
"callback_url": "https://webhook.site/c5b9a01f-f224-494a-86b8-39ffe0c292a4",
"country": "ZA",
"phone_number": "0000000000",
"match_fields": {
"first_name": "Test",
"last_name": "Test",
"other_name": "Test",
"id_number": "text"
}
}字段说明:
| 字段 | 是否必填 | 说明 |
|---|---|---|
callback_url | 是 | 回调地址;官方在同步和异步 endpoint 的 Body 中都标为 Required |
country | 是 | 国家码,例如 ZA |
phone_number | 是 | 手机号,格式需符合对应国家 regex |
match_fields | 是 | 要与手机号记录进行匹配的字段对象 |
match_fields 中的字段按国家支持情况传入,不是所有国家都支持 id_number。
5. 支持国家、手机号格式和匹配字段
官方支持列表:
| 国家 | Phone Number Regex | Match Fields |
|---|---|---|
| Ghana | /^[0-9]{10}$/ | First Name, Other Name, Last Name |
| South Africa | /^[0-9]{10}$/ | First Name, Other Name, Last Name, ID Number |
| Tanzania | /^[0-9]{12}$/ | First Name, Other Name, Last Name |
| Uganda | /^[0-9]{10}$/ | First Name, Other Name, Last Name |
Ghana 特别要求:
json
{
"operator": "MTN"
}Ghana 的 operator 必须是以下之一:
MTNVODAFONEAIRTELTIGO
6. Sandbox 测试数据
官方提供以下 Sandbox 测试数据:
| Country | Test Phone Number | Last Name | First Name | Other Name | ID Number |
|---|---|---|---|---|---|
| Ghana | 00000000000 | Leo | Joe | Doe | N/A |
| South Africa | 0000000000 | Leo | Joe | Doe | 0000000000000 |
| Tanzania | 000000000000 | Leo | Joe | Doe | N/A |
| Uganda | 0000000000 | Leo | Joe | Doe | N/A |
官方模拟结果规则:
| Final Digit | Simulated Result | Code |
|---|---|---|
0,例如 0000000000 | 根据 match_fields 返回不同结果 | 根据 match_fields 变化 |
1,例如 0000000001 | Failure, no record found | 1023 |
2,例如 0000000002 | Invalid phone number format | 2413 |
3,例如 0000000003 | Database unavailable/unknown network issue | 1015 |
7. 返回结果
异步接口 /v2/async-verify-phone
提交成功:
json
{
"success": true
}错误示例:
json
{
"success": false,
"code": "2413",
"error": "Invalid request"
}最终验证结果通过 callback_url 接收。
同步接口 /v2/verify-phone-number
同步接口直接返回完整验证结果。官方示例:
json
{
"code": "1020",
"created_at": "2024-08-05T11:09:20.232Z",
"job_id": "12cf30bb-d181-4d5e-a804-83253bafe6e4",
"job_type": "phone_number_verification",
"matched_fields": {
"first_name": "Exact Match",
"last_name": "Exact Match"
},
"message": "Exact Match",
"partner_id": "002",
"partner_params": {
"job_id": "12cf30bb-d181-4d5e-a804-83253bafe6e4",
"user_id": "8a1ccd25-b6e6-47ca-ab48-df5439b4613c"
},
"signature": "sample-signature",
"timestamp": "2024-08-05T11:09:20.232Z"
}8. 结果码
官方结果码:
| Code | Message | Description |
|---|---|---|
1020 | Exact Match | All fields provided match the record in the database. |
1021 | Partial Match | Some, but not all, fields match the record in the database. |
1022 | No Match | None of the fields match the record in the database. |
1023 | Record Not Found | The phone number does not exist in the database. |
1015 | ID Authority Unavailable | The verification could not be completed because the ID authority was unavailable. |
匹配规则:
- Exact Match:字段完全匹配。
- Partial Match:字段 Levenshtein distance
<= 2。 - No Match:其他情况。
按官方说明,不同市场数据库有差异,因此字段匹配方式可能因国家而不同。
9. 如何接入
推荐后台接入流程:
text
业务系统生成本地 user_id/job_id
-> 选择国家 country 并校验 phone_number regex
-> 根据国家组装 match_fields
-> 生成 smileid-timestamp
-> 生成 smileid-request-signature
-> POST /v2/async-verify-phone 或 /v2/verify-phone-number
-> 异步接口保存 PENDING 并等待 callback_url
-> 同步接口直接解析 code/message/matched_fieldsJava/Spring Boot 请求伪代码:
java
String timestamp = Instant.now().toString();
String signature = signatureService.generateSignature(timestamp, partnerId, apiKey);
Map<String, Object> body = Map.of(
"callback_url", callbackUrl,
"country", "ZA",
"phone_number", "0000000000",
"match_fields", Map.of(
"first_name", "Joe",
"last_name", "Leo",
"other_name", "Doe",
"id_number", "0000000000000"
)
);
PhoneVerificationResponse response = restClient.post()
.uri("/v2/verify-phone-number")
.contentType(MediaType.APPLICATION_JSON)
.header("smileid-partner-id", partnerId)
.header("smileid-request-signature", signature)
.header("smileid-timestamp", timestamp)
.header("smileid-source-sdk", "rest_api")
.header("smileid-source-sdk-version", "1.0.0")
.body(body)
.retrieve()
.body(PhoneVerificationResponse.class);10. 接入注意点
- endpoint 必须使用官方路径:
/v2/async-verify-phone或/v2/verify-phone-number。 - 认证参数在 Header 中,不是在 Body 中。
match_fields是必填对象;字段是否可用要按国家支持列表来传。- Ghana 要传
operator,且只能是MTN、VODAFONE、AIRTELTIGO。 phone_number不要随意加+国际区号,需按官方 regex 校验。1023 Record Not Found表示手机号不在数据库中;不应直接等同于现实中手机号不存在。1015 ID Authority Unavailable是外部数据源不可用,应重试或走降级流程。- 官方说明匹配方法会因不同市场数据库特征而不同,不能把所有国家的匹配细节写死成同一套业务规则。
- Sandbox 和 Production 的 Partner ID、API Key、Base URL 必须成套使用,不能混用。