渠道商总体接入流程
本文档基于 cl-cloud 的渠道商开放接口实现和 ipv-sdk 的 Go SDK 封装整理,用于说明渠道商从申请密钥、同步产品、下单、处理回调到后续运维的整体接入顺序。
1. 接入边界
渠道商调用的是平台开放接口,统一路径前缀为:
/api/open/app/{resource}/v2
cl-cloud/modules/open/service/supplier 是平台对上游供应商的适配层,渠道商接入时通常不需要实现该部分接口。渠道商只需要:
- 向平台申请
appKey、appSecret、产品授权和回调地址配置。 - 使用
ipv-sdk或自行按统一加密规则请求/api/open/app/.../v2。 - 保存平台返回的
orderNo和instanceNo,按回调或轮询补齐订单、实例最终状态。
2. 环境和密钥
| 环境 | 地址 |
|---|---|
| 沙盒 | https://sandbox.ipipv.com |
| 生产 | https://api.ipipv.com |
生产环境会真实开通代理并产生费用。上线前建议先在沙盒完成加密、下单、回调、订单查询和实例查询的完整闭环。
3. 统一加密请求
所有 v2 业务请求外层都是统一报文:
{
"version": "v2",
"encrypt": "AES",
"appKey": "渠道商 appKey",
"reqId": "每次请求的唯一编号",
"params": "业务参数 JSON 经 AES-CBC 加密后 Base64"
}
加密规则:
params的明文是具体业务参数 JSON。- AES-CBC,PKCS5/PKCS7 Padding。
- 密钥使用
appSecret,长度必须是 16、24 或 32 字节。 - IV 使用
appSecret的前 16 字节。 - 响应成功时,外层
data也是 AES-CBC 加密后 Base64,需要用同一个appSecret解密。
响应外层结构:
{
"reqId": "请求编号",
"code": 200,
"msg": "ok",
"data": "加密后的业务响应"
}
如果 code != 200,按 msg 和状态码处理错误,不要按成功响应解析 data。/api/open/app/proxy/user/flow/limit/v2 成功时只返回普通成功结果,不返回加密业务数据。
使用 Go SDK 时,SDK 会自动封装加密、解密和基础错误处理:
client, err := sdk.NewClient(
"https://sandbox.ipipv.com",
"your_app_key",
"your_app_secret",
sdk.Encrypt_AES,
)
4. 接入总流程
申请密钥和配置回调
-> 联调统一加密和 GetAppInfo
-> 同步地域、城市、项目和产品
-> 按产品类型选择静态或动态开通流程
-> 提交订单,保存平台 orderNo
-> 等待 order 回调或轮询 GetOrder
-> 查询订单实例,保存 instanceNo
-> 使用实例,后续按需续费、释放、更换代理、重置密码或查询动态流量
5. 前置初始化
5.1 获取渠道商信息
调用 GetAppInfo:
POST /api/open/app/info/v2
用于确认渠道商状态、余额、授信额度、桥配置和回调地址。status=1 才表示渠道商可正常使用。
5.2 同步基础字典
建议启动时或定时同步:
| 目的 | 接口 | SDK 方法 |
|---|---|---|
| 洲/国家/州/城市树 | /api/open/app/area/v2 | GetArea |
| 城市列表 | /api/open/app/city/list/v2 | GetCityList |
| 项目列表 | /api/open/app/project/list/v2 | GetProjectList |
| 产品列表 | /api/open/app/product/query/v2 | GetProductStock |
| 单产品实时信息 | /api/open/app/product/info/v2 | GetProductInfo |
产品返回中的关键字段:
productNo:平台产品编号,下单优先使用该字段。proxyType:101/102/103 为静态代理,104/105 为动态代理。enable=1:可购买。inventory:库存。duration、unit:产品最小购买周期。productType=2:共享产品,下单需要projectId。cidrBlocks、cidrStatus:是否支持按网段购买。assignIp:是否支持指定 IP 购买。changeProxy:是否支持更换代理。resetPassword:是否支持重置密码。- 动态能力字段:
drawType、ipWhiteList、pwdDrawProxyUser、proxyUserFlowLimit、flowUseLog、proxyGlobalRandom、apiDrawGlobalRandom等。
6. 静态代理开通流程
适用代理类型:101 静态云平台、102 静态国内家庭、103 静态国外家庭、201 WhatsApp 等非动态产品。
-
查询并选择产品。 推荐传
productNo下单。也可以不传productNo,由平台按proxyType、countryCode、cityCode、supplierCode、unit、ispType等条件匹配产品,但推荐只在明确需要自动匹配时使用。 -
提交开通订单。
POST /api/open/app/instance/open/v2
SDK: InstanceOpen
核心参数:
| 参数 | 说明 |
|---|---|
appOrderNo | 渠道商订单号,普通订单最长 32 位,同一渠道商下保持唯一 |
params | 购买项数组,最多 100 项 |
params[].productNo | 平台产品编号,推荐必传 |
params[].count | 静态实例数量,单项最大 100,默认 1 |
params[].cycleTimes | 购买周期数,推荐使用;表示购买几个产品最小周期 |
params[].duration | 兼容字段,不传时使用产品最小周期 |
params[].extBandWidth | 额外带宽,单位 Mbps |
params[].useBridge | 0=随渠道商配置,1=不使用桥,2=使用桥 |
params[].cidrBlocks | 支持网段购买时可传,所有 count 之和必须等于购买数量 |
params[].projectId | 共享产品必填,取项目列表返回的 code |
- 处理下单响应。 开通接口返回的是异步订单受理结果:
{
"orderNo": "平台订单号",
"appOrderNo": "渠道商订单号",
"amount": "订单金额"
}
此时不代表实例已经可用。渠道商需要保存 orderNo,等待回调或轮询订单。
- 查询订单和实例。
POST /api/open/app/order/v2
SDK: GetOrder
可用平台 orderNo 或渠道商 appOrderNo 查询。订单 status:
| 状态 | 说明 |
|---|---|
| 1 | 待处理 |
| 2 | 处理中 |
| 3 | 处理成功 |
| 4 | 处理失败 |
| 5 | 部分完成 |
订单成功或部分完成后,读取返回的 instances,保存每个实例的 instanceNo、ip、port、username、pwd、userExpired、productNo。后续续费、释放、更换代理、重置密码都使用平台 instanceNo。
7. 动态代理开通和提取流程
适用代理类型:104 动态国外、105 动态国内。
7.1 创建主账号
动态代理必须先创建渠道商主账号:
POST /api/open/app/user/v2
SDK: CreateUser
核心参数:
| 参数 | 说明 |
|---|---|
appUsername | 渠道商主账号,同一渠道商下唯一;不传则平台生成 |
password | 不传则平台生成 |
phone、email | 可选 |
authType、authName、no | 实名信息,可创建时传,也可后续同步 |
status | 1=正常,2=禁用 |
创建主账号时,平台会自动创建一个同名代理子账号。若业务需要多个独立子账号,可继续调用 CreateProxyUser。
7.2 可选同步实名
POST /api/open/app/userAuth/v2
SDK: UserAuth
username 和 appUsername 二选一,必须属于当前渠道商。
7.3 可选创建子账号
POST /api/open/app/proxy/user/v2
SDK: CreateProxyUser
核心参数:
| 参数 | 说明 |
|---|---|
appMainUsername | 渠道商主账号;与 mainUsername 二选一 |
mainUsername | 平台主账号;与 appMainUsername 二选一 |
appUsername | 渠道商子账号,不传则平台生成 |
password | 子账号密码,不传则平台生成 |
limitFlow | 子账号流量上限,创建时字段为 MB;独立设置上限接口使用 B |
status | 1=正常,2=禁用 |
7.4 购买动态套餐
动态产品也通过开通接口下单:
POST /api/open/app/instance/open/v2
SDK: InstanceOpen
动态购买项必须关注:
| 参数 | 说明 |
|---|---|
productNo | 动态产品编号 |
appUsername | 渠道商主账号,必须已创建 |
flow | 动态流量,单位 MB;普通流量型动态产品必填 |
cycleTimes | 有固定周期的产品按周期数购买 |
count | 默认 1;按 IP 数量售卖的产品需结合产品 ipCount、ipDuration 规则 |
下单后同样等待 order 回调或轮询 GetOrder。动态套餐对应的实例主要用于记录套餐和余额,实际代理地址通过提取接口获取。
7.5 查询余额和区域
| 目的 | 接口 | SDK 方法 |
|---|---|---|
| 动态余额 | /api/open/app/proxy/info/v2 | ProxyInfo |
| 动态区域 | /api/open/app/product/area/v2 | ProductAreaList |
余额查询中的 total、used、balance 单位为 MB;流量明细中的 used、total、balance 单位为 B。
7.6 提取动态代理
账密提取:
POST /api/open/app/proxy/draw/pwd/v2
SDK: DrawByPwd
使用渠道商子账号 appUsername。sessTime 默认为 5 分钟,通常支持 1 到 120 分钟;传 0 或 -1 表示每次切换代理。addressCode 可传洲、国家、州省或城市代码,空值表示混播,前提是产品支持。
API 提取:
POST /api/open/app/proxy/draw/api/v2
SDK: DrawByApi
使用渠道商主账号 appUsername。返回 proxyUrl,业务方再访问该 URL 获取代理结果。protocol 默认为 socks5,支持 socks5、http;returnType 支持 txt、json。
如产品要求 IP 白名单,提取前先调用:
POST /api/open/app/proxy/addIpWhiteList/v2
POST /api/open/app/proxy/delIpWhiteList/v2
8. 续费、释放和售后
8.1 续费静态实例
POST /api/open/app/instance/renew/v2
SDK: InstanceRenew
核心规则:
appOrderNo同一渠道商下唯一,最长 32 位。instances不能为空,不能重复,单次最多 100 个。- 只支持静态代理;动态代理不支持续费接口。
- 实例必须属于当前渠道商,且状态为运行中。
- 实例不能超过供应商续费宽限期。
cycleTimes优先;不传时默认按原购买周期续费。
续费是异步订单,返回平台 orderNo 后继续按回调或 GetOrder 查询最终结果。
8.2 释放静态实例
POST /api/open/app/instance/release/v2
SDK: InstanceRelease
注意:请求参数里的 orderNo 是渠道商释放订单号,不是平台订单号。
核心规则:
- 渠道商释放订单号同一渠道商下唯一,最长 32 位。
instances不能为空,不能重复,单次最多 100 个。- 只支持运行中的静态代理;动态代理不支持释放接口。
- 已转移、已释放、正在释放、超过无理由释放期限或超过渠道商释放额度的实例会失败。
释放同样是异步订单,最终结果以回调后查询订单为准。
8.3 售后释放
POST /api/open/app/instance/aftersale/v2
SDK: InstanceAfterSale
该能力需要渠道商单独开通。适用于下架、断网、卡顿、地区异常、黑白名单、业务不支持等售后场景。请求中 orderNo 是渠道商售后释放订单号。
9. 可选能力
9.1 指定 IP 购买
先查询指定 IP 是否可购买:
POST /api/open/app/assign/ip/info/v2
SDK: GetAssignIpInfo
确认 canBuyStatus=true 后提交指定 IP 开通:
POST /api/open/app/instance/open/assign/ip/v2
SDK: InstanceOpenAssignIp
指定 IP 购买仅支持静态产品,产品和供应商都必须支持该能力。productNo、assignIp、cycleTimes 必填。
9.2 更换代理
POST /api/open/app/instance/change/v2
SDK: ChangeProxy
核心规则:
- 渠道商和供应商都必须开通更换代理能力。
- 产品列表返回
changeProxy=1才能作为判断依据之一。 - 实例必须属于当前渠道商且为运行中。
appOrderNo为更换代理订单号,最长 64 位,同一渠道商下唯一。- 同一实例同一时间只允许一个更换代理任务处理中。
reason最长 64 字符。
更换代理成功后,实例的 IP、端口、账号密码等连接信息会被更新。收到 op=5 的订单回调后,通过 GetOrder 或 GetInstance 获取最新实例信息。
9.3 重置实例密码
POST /api/open/app/instance/reset/password/v2
SDK: ResetProxyPassword
核心规则:
- 以产品
resetPassword=1和实际供应商能力为准。 resetNo必填,最长 32 位,同一渠道商下用于幂等。instanceNoList不能为空,不能重复。- 实例必须属于当前渠道商且为运行中。
- 重复提交相同
resetNo时,实例列表必须一致,平台返回第一次请求的处理结果。
返回结果中 status 为 1=待处理、2=处理中、3=成功、4=失败;newPassword 为空表示尚未成功生成或处理失败。
9.4 动态子账号流量上限
POST /api/open/app/proxy/user/flow/limit/v2
SDK: SetProxyUserFlowLimit
产品和供应商必须支持 proxyUserFlowLimit=1。limitFlow=-1 表示不限制;如果设置正数,单位为 B,且不能小于 1024000B。
查询子账号信息:
POST /api/open/app/proxy/user/info/v2
SDK: GetProxyUserInfo
9.5 动态流量明细和回收
流量明细:
POST /api/open/app/proxy/flow/use/log/v2
SDK: ProxyFlowUseLog
默认查询近 7 天;分页默认 page=1、pageSize=10,最大 100。
流量回收:
POST /api/open/app/proxy/return/v2
SDK: DynamicProxyReturn
流量型产品使用 flowNum,单位 MB;按 IP 数量购买的产品使用 ipNum。平台会校验当前剩余量并按产品授权价格计算退回金额。
10. 回调处理
平台在订单、实例或产品变化时,向渠道商配置的回调地址发起 GET 请求:
{callbackUrl}?type={type}&no={no}&op={op}
常见回调:
| type | no | op | 处理建议 |
|---|---|---|---|
order | 平台订单号 | 1=创建,2=续费,3=释放,5=更换代理 | 调用 GetOrder 拉取订单和实例最终状态 |
instance | 平台实例编号 | 实例变化操作类型 | 调用 GetInstance 拉取实例最新信息 |
product | 产品编号 | 0 | 调用 GetProductInfo 或 GetProductStock 刷新产品 |
渠道商回调接口必须返回 JSON:
{
"code": "success",
"msg": "ok"
}
如果没有返回 code=success,平台会重试。渠道商需要按 type + no + op 做幂等;同一个回调已经处理成功后,再次收到也应返回 success。
11. 幂等和重试建议
- 普通开通、续费、释放、售后订单使用渠道商订单号幂等,建议最长 32 位。
- 更换代理使用独立
appOrderNo幂等,最长 64 位。 - 重置密码使用
resetNo幂等,最长 32 位。 - 同一个订单号不要跨业务类型复用;例如开通订单号不能再用于续费或释放。
- 网络超时或未收到响应时,使用相同
reqId和相同业务单号重试。 - 如果接口已返回平台
orderNo,后续以订单查询和回调为准,不要重复生成新的渠道商订单号补单。 - 保存平台
orderNo、渠道商订单号、instanceNo、productNo、账号映射关系,便于后续续费、释放、售后和对账。
12. 推荐最小联调清单
GetAppInfo:验证密钥、加密和响应解密。GetArea、GetCityList:验证地域字典。GetProductStock:验证产品授权和产品字段解析。- 静态产品:
InstanceOpen-> 回调 ->GetOrder->GetInstance。 - 动态产品:
CreateUser->InstanceOpen->ProxyInfo->DrawByApi或DrawByPwd。 - 后续操作:选择一个实例完成
InstanceRenew、InstanceRelease或ChangeProxy的沙盒闭环。 - 回调:验证订单回调重复通知时仍返回
success。