POST /api/partner/login
POST /api/partner/coupons/place
GET /api/partner/coupons/calculated?time=10 1. 你需要从经理那里得到什么
- 基本 URL API;
- 客户帐户登录名和密码;
- 使用回调时 - 启用该功能和秘密短语
callback_secret。
这些示例使用条件地址:
BASE_URL="https://coupon-api.example.com"
在生产中,使用 HTTPS。所有日期都以毫秒为单位的 Unix 时间戳传输,货币值以没有固定精度的十进制数字传输。
2. API响应格式
成功:
{
"code": 1,
"body": {},
"error_code": null,
"error_message": null,
"date": 1784970000000,
"time_ms": 5,
"path": "/api/partner/example"
}
业务错误通常还伴随HTTP 200:
{
"code": 0,
"body": null,
"error_code": 1002,
"error_message": "Not all params",
"date": 1784970000000,
"time_ms": 5,
"path": "/api/partner/example"
}
始终检查 HTTP 代码,然后是 code,然后是 error_code。请勿使用文本 error_message 作为软件密钥。
3. 授权
POST /api/partner/login
Content-Type: application/json
{
"username": "partner-demo",
"password": "strong-password"
}
支持字段 login 作为兼容别名 username。
成功响应:
{
"code": 1,
"body": {
"token": "<jwt-token>",
"user_id": 17,
"username": "partner-demo"
},
"error_code": null,
"error_message": null
}
在所有受保护的请求中,传递:
Authorization: Bearer <jwt-token>
基本登录错误:
| 代码 | 原因 |
|---|---|
1002 | 未发送登录名或密码。 |
1003 | 未知的登录名或密码不正确。 |
1004 | 客户帐户已被禁用。 |
1006 | 访问日期已过期。 |
1007 | 客户余额为零或负数。 |
这些错误是从 HTTP 200、code = 0 返回的。受保护方法的 HTTP 401 表示 JWT 丢失、无效、过期或撤销;再次登录。 HTTP 403 表示不适当的角色或访问被拒绝。
4. 投注指针
每个选定的结果都作为体育线路中的现成线路传输:
line_type#game_id#group_id#type_id#rate#coefficient[#player_id]
示例:
line#737779544#1#1#0#1.85
live#738917381|119|5869|0.5#3.6#149439538
line_type:line或live;rate:总/让分参数或0;player_id:可选玩家ID;- 支持分隔符
#和|。
不要手动收集或更正指针 - 将从行获得的值保持不变。
5. 优惠券放置
POST /api/partner/coupons/place
Authorization: Bearer <jwt-token>
Content-Type: application/json
{
"list_bets": [
"line#737779544#1#1#0#1.85"
],
"amount": 10,
"currency": "USD",
"callback_url": "https://partner.example.com/api/coupon-result",
"lang": "en",
"mode": "reject",
"mode_type": null,
"multi": false
}
| 领域 | 强制 | 目的 |
|---|---|---|
list_bets | 是的 | 一个或多个指针。 |
amount | 是的 | 所创建的一张优惠券的正金额。 |
currency | 否 | 任何字符串名称,包括虚拟货币。 |
callback_url | 否 | 网址回调;如果没有回调,则无法发送它,您可以传递 null、空字符串或站点域。 |
lang | 否 | 大约 50 种受支持语言之一的两个字母代码。名字的语言在创造时就固定下来了。 |
mode | 否 | reject 或 accept;默认reject。 |
mode_type | 对于accept | 允许系数变化方向。 |
multi | 否 | 一张普通优惠券或个人单张;默认false。 |
赔率
| 设置 | 行为 |
|---|---|
mode = reject | 当赔率变化时拒绝创建。 |
mode = accept, mode_type = 1 | 只接受赔率增加。 |
mode = accept, mode_type = 2 | 只接受赔率降低。 |
mode = accept, mode_type = 3 | 接受任何改变。 |
单打、多重彩和 multi
| 请求 | 结果 | 借方客户余额 |
|---|---|---|
| 一个结果 | 一张单人 | amount |
多种结果,multi = false | 1个蓄能器 | amount |
多种结果,multi = true | 每个结果单独一个 | amount × 创建优惠券数量 |
一组累加器序列最多可包含 15 个事件。您不能在同一场比赛中合并多个投注,包括主比赛、半场、赛节、角球、犯规和其他相关子赛事。该组合返回 506。
6. 确认优惠券和投注
完整成功响应,包含 events_data 内的优惠券和接受的投注数据:
{
"code": 1,
"body": {
"coupons": [
{
"coupon_code": "000000000272",
"amount": 10,
"win": 18.5,
"potential_win": 18.5,
"real_win": null,
"coef": 1.85,
"original_coef": 1.85,
"calculate_coef": null,
"has_return": false,
"date": 1784970000000,
"status": 0,
"asian": false,
"calculate_date": null,
"coupon_type": 1,
"events_count": 1,
"events_data": [
{
"id": 912,
"game_id": 737779544,
"main_game_id": 737779544,
"is_sub_game": false,
"parent_game_id": null,
"sub_game_key": null,
"raw_pointer": "line#737779544#1#1#0#1.85",
"line_type": "line",
"is_live": false,
"bet_group_id": 1,
"bet_group_name": "Match result",
"bet_id": 1,
"bet_name": "First team to win",
"sport_id": 1,
"sport_name": "Football",
"tournament_id": 10001,
"tournament": "National League",
"event_date": 1784971800000,
"status": 0,
"opp1": "Team A",
"opp2": "Team B",
"coef": 1.85,
"calc_coef": null,
"bet_score": "line#737779544#1#1#0#1.85",
"calculate_date": null,
"calculate_score": null,
"settlement_reason_code": null,
"settlement_reason": null,
"placement_score_full": null,
"placement_score_periods": null,
"calculation_score_full": null,
"calculation_score_periods": null,
"timer": null,
"dop_name": null,
"rate": "0",
"sgame_id": null,
"game_num": null,
"stat_id": null,
"team1_id": 101,
"team2_id": 102,
"opp_icon1": 101,
"opp_icon2": 102
}
]
}
]
},
"error_code": null,
"error_message": null,
"date": 1784970000015,
"time_ms": 45,
"path": "/api/partner/coupons/place"
}
优惠券字段
每件商品 body.coupons[] 都是单独创建的优惠券。
| 领域 | 类型 | 含义 |
|---|---|---|
coupon_code | string | 公共 12 位优惠券代码。存储为字符串以避免丢失前导零。 |
amount | number | 创建时转移的优惠券金额。 |
win | number | 当前显示的中奖金额。 |
potential_win | number | 最终结算前可能赢得的奖金。 |
real_win | number/null | 计算后的实际支付金额;计算前 - null。 |
coef | number | 当前或最终票面利率。 |
original_coef | number | 优惠券创建时的总系数。 |
calculate_coef | number/null | 最终计算系数;计算前 - null。 |
has_return | boolean | true,如果优惠券包含退款状态的投注。 |
date | integer | 优惠券创建日期,Unix 时间戳(以毫秒为单位)。 |
status | integer | 当前优惠券状态。这些值在“优惠券和投注状态”部分中描述。 |
asian | boolean | 存在亚洲结算的迹象,包括一半的赢利或损失。 |
calculate_date | integer/null | 优惠券计算日期(以毫秒为单位);计算前 - null。 |
coupon_type | integer | 优惠券类型:1 - 普通,2 - 快递。 |
events_count | integer | 优惠券内的投注次数。 |
events_data | array | 优惠券中包含完整的投注范围。 |
投注字段
events_data[] 的每个元素都描述了优惠券中特定的接受投注。
| 领域 | 类型 | 含义 |
|---|---|---|
id | integer/null | 已接受投注的内部 ID。与 coupon_code 结合使用,在优惠券中查找投注。 |
game_id | integer | 下注的赛事或子赛事的 ID。 |
main_game_id | integer/null | 赛事或子赛事所属的主比赛ID。 |
is_sub_game | boolean | true,如果投注涉及半场、赛节、赛盘、角球或其他子赛事。 |
parent_game_id | integer/null | 直接父事件的 ID(如果存在)。 |
sub_game_key | string/null | 子事件或周期的技术要点。 |
raw_pointer | string | API 接受的原始投注指针。 |
line_type | string | 线路类型:line - 赛前,live - 实时赛事。 |
is_live | boolean | true,如果投注是在实时盘线上创建的。 |
bet_group_id | integer | 投注组或市场的ID。 |
bet_group_name | string/null | 投注组的本地化名称。 |
bet_id | integer | 下注组中所选选项的 ID。 |
bet_name | string/null | 所选选项的本地化全名。 |
sport_id | integer/null | 运动ID。 |
sport_name | string/null | 运动的本地化名称。 |
tournament_id | integer/null | 比赛ID。 |
tournament | string/null | 锦标赛的本地化名称。 |
event_date | integer/null | 事件开始日期,Unix 时间戳(以毫秒为单位)。 |
status | integer | 当前投注结算状态。不要与优惠券状态混淆。 |
opp1 | string/null | 第一个团队或参与者的名称。 |
opp2 | string/null | 第二支队伍或参赛者的姓名。 |
coef | number | 接受投注的投注赔率。 |
calc_coef | number/null | 计算的投注乘数;计算前 - null。 |
bet_score | string | 旧版 API 兼容字段包含投注指示符而不是比赛得分。 |
calculate_date | integer/null | 投注结算日期(以毫秒为单位);计算前 - null。 |
calculate_score | string/null | 用于计算投注的帐户。 |
settlement_reason_code | string/null | 结算或退款原因的稳定机器码;计算前 - null。 |
settlement_reason | string/null | 结算或退款原因的说明文字;计算前 - null。 |
placement_score_full | string/null | 创建投注时的赛事总得分(如果有)。 |
placement_score_periods | string/null | 按创建投注时的时段得分(如果有)。 |
calculation_score_full | string/null | 投注结算时赛事的总得分。 |
calculation_score_periods | string/null | 投注结算时按时段得分。 |
timer | integer/null | 数据保存时的事件计时器(如果有)。 |
dop_name | string/null | 子赛事名称:半场、赛段、局数、局数等。 |
rate | string | 结果参数,例如总分或让分的数值;对于没有参数的结果 - "0"。 |
sgame_id | string/null | 子事件外键。 |
game_num | integer/null | 游戏编号(如果来源提供)。 |
stat_id | string/null | 外部统计事件ID。 |
team1_id | integer/null | 第一个队伍或参赛者的ID。 |
team2_id | integer/null | 第二支队伍或参赛者的ID。 |
opp_icon1 | integer/null | 第一个命令图标的兼容ID;匹配 team1_id。 |
opp_icon2 | integer/null | 兼容第二队图标ID;匹配 team2_id。 |
对于尚未计算或不可用的数据,值 null 是正常的。不要自动将其替换为 0 或空字符串。
仅当 code = 1 且 body.coupons 中存在对象时才考虑接受优惠券。在此之前,篮子是一个初步选择:选择可能会消失、被阻止或赔率发生变化。
成功后:
- 保存所有
body.coupons对象,而不仅仅是第一个; - 将
coupon_code存储为带有前导零的字符串; - 从
events_data中保存所需数据; - 将优惠券与最终用户相匹配;
- 在合作伙伴的系统中记录用户的财务交易。
标识符:
| 领域 | 目的 |
|---|---|
coupon_code | 公共优惠券代码。 |
events_data[].id | 优惠券内特定接受投注的 ID。 |
回调 events_data[].uuid | 相同的投注 ID,作为字符串传递。 |
batchId | 回调套餐版本ID,不是优惠券或费率。 |
完整模型和回调中不返回currency。如果需要货币,请保存创建请求中的值。
7. 创建错误
| 代码 | 原因 | 行动 |
|---|---|---|
10 | 无请求正文。 | 更正请求。 |
11 | 无效指针。 | 从该行获取当前指针。 |
12 | 无效 amount。 | 传递一个正数。 |
501 | 胜算已经改变。 | 显示新值或更改 mode。 |
502 | 没有结果。 | 删除/更新购物车中的出价。 |
503 | 结果被封锁了。 | 报告暂时不可用。 |
504 | 结果验证错误。 | 不考虑接受优惠券;稍后重复。 |
506 | 多重彩包含来自同一场比赛的投注。 | 保留一个结果或使用单独的单项。 |
507 | 客户余额不足。 | 充值您的余额或减少总金额。 |
1002 | 参数集无效。 | 正确的参数。 |
10000 | 内部错误。 | 记录错误并在重试之前检查结果。 |
对于 501–504,新 API 返回 body.changes[] 中的有问题的费率。字段change_type:1 - 系数已增加,2 - 减少,null - 方向不适用。
超时后不要盲目重试 POST /coupons/place:第一个请求可能已被接受,重试将创建重复的请求。
8. 领取优惠券
| 操作 | 端点 | 结果 |
|---|---|---|
| 一张优惠券 | GET /api/partner/coupons/get?coupon_code={code} | 优惠券位于body。 |
| 活跃 | GET /api/partner/coupons/active | 数组位于 body[]。 |
| 最近的计算 | GET /api/partner/coupons/calculated?time=10 | 数组在body[];最多 120 分钟。 |
| 按代码/期间 | POST /api/partner/coupons/results | 数组位于 body.coupons 中。 |
| 客户余额 | GET /api/partner/balance | body.balance。 |
您可以使用代码传输最多 100 个值:
{
"coupon_ids": ["000000000272", "000000000273"]
}
或者传递创建周期不超过24小时:
{
"start_date": 1784880000000,
"end_date": 1784966400000
}
请勿在同一查询中组合 coupon_ids 和日期。 results 按创建时间过滤,calculated 按最终结算时间过滤。
9. 优惠券和投注状态
优惠券状态:
| 代码 | 含义 | 决赛 |
|---|---|---|
0 | 活跃或部分定居。 | 否 |
2 | 赢了。 | 是的 |
4 | 迷失了。 | 是的 |
8 | 全额退款。 | 是的 |
15 | 返回重新计算;期待新的结果。 | 否 |
投注状态:
| 代码 | 含义 | calc_coef |
|---|---|---|
0 | 没有计算。 | null |
1 | 获胜。 | 原始系数 |
2 | 输了。 | 0 |
3 | 返回。 | 1 |
4 | 等待重新计算。 | null |
21 | 奖金的一半。 | (coef + 1) / 2 |
22 | 损失一半。 | 0.5 |
23 | 推。 | 1 |
对于最终用户的财务应计,请使用现成的 real_win。请勿使用potential_win,也不要自行重新计算支出。计算前,real_win、calculate_coef、calc_coef、calculate_date 等于null,而不是0。
在优惠券 15 的第一个状态下,如果先前的结果已进行财务处理,则合作伙伴再次从最终用户处借记 amount,期望新的最终状态并收取新的 real_win。保护操作免受再处理。
10. 计算原因
完整模型和回调中的每个投注都有:
| 领域 | 目的 |
|---|---|
settlement_reason_code | 稳定的结算/退款原因代码。 |
settlement_reason | 解释性源文本。 |
计算前,两个字段均等于null。对于本地化通知,请使用如下代码:
MATCH_POSTPONED- 比赛已推迟;MATCH_CANCELLED- 比赛取消;MARKET_PUSH——按照市场规则回报。
如果代码未知,请将其保存并使用非空 settlement_reason 作为后备文本。请勿根据原因 - 使用状态和 real_win 计算支出。
这些字段解释已经执行的计算或返回,并不是比赛状态的单独实时反馈。
11. 回调
回调是可选的。合作伙伴只能通过投票的方式进行工作。对于回调,管理器必须启用该功能并创建callback_secret; URL 会在创建的每张优惠券中发送。
回调URL由合作伙伴自主决定。在生产中应该使用https://;在测试环境中,允许使用http://。
系统发送:
POST {callback_url}
Content-Type: application/json
X-Coupon-Signature: sha256=<hex_hmac_sha256>
短有效负载:
{
"event": "coupons.settled",
"batchId": "d407e986f3a64d9d36a77bf532322ef8",
"couponCount": 1,
"coupons": [
{
"coupon_code": "000000000272",
"realWin": 18.5,
"calculate_coefficient": 1.85,
"status": 2,
"calculate_date": 1784973600000,
"events_data": [
{
"uuid": "912",
"status": 1,
"calculate_coefficient": 1.85,
"calculate_date": 1784973600000,
"calculate_score": "2:1",
"settlement_reason_code": "REMOTE_WIN",
"settlement_reason": "Win",
"timer": 0
}
]
}
]
}
强制性规则:
- 在 JSON 解析之前从正文的确切源字节计算
sha256=<hex(HMAC-SHA256(raw_body, callback_secret))>并以安全的方式比较签名; - 处理所有商品
coupons,包裹最多可包含100张优惠券; - 使用唯一索引存储
batchId; - 重复
batchId不应重复借记或应计; - 一个
coupon_code在渐进计算和重新计算时可以配备不同的batchId; - 只有在整个数据包被安全存储后才返回 HTTP
200。
最小成功响应是空 HTTP 200。高级:
{
"success": true,
"processed": 1
}
processed 必须等于 couponCount。响应 201、202 和 204 不被视为成功。
仅在超时、传输错误或 HTTP 500、502、503、504 的情况下执行重播:立即,然后在 1、5、15 和 60 分钟后 - 发送不超过 5 次。对于带有 success: false 或部分 processed 的 HTTP 200 没有自动重试。
12. 轮询回退
即使有回调,也要定期检查结果:
GET /api/partner/coupons/calculated?time=10
休息时间超过 120 分钟后,可在保存的 coupon_ids 或创建时间长达 24 小时内使用 POST /api/partner/coupons/results。再次接收相同的状态不应重复金融交易。
13. 安全和存储
- 仅在服务器上存储登录名、密码、JWT 和
callback_secret; - 不要在 URL 中传递 JWT,也不要将完整令牌写入日志中;
- 使用小数类型表示货币;
- 将
coupon_code存储为字符串; - 保存
amount、所需的投注数据和currency(如果使用); - 区分优惠券和投注状态;
- 接受未知字段和原因代码,不会出现错误;
- 使所有最终用户金融交易幂等。
14. 旧 API 和提现
继续支持旧路由,但新集成必须使用 /api/partner/**。旧的答案和错误有不同的格式。要更新现有客户端,请使用单个文件“从旧 API 迁移”。
Cashout 正在开发中,尚未经过充分测试,不建议用于生产。
15. 最终清单
- 收到
BASE_URL、登录名和密码。 - JWT 作为承载令牌传输。
- 指针取自该行,未经修改。
- 仅在
code = 1之后,购物车才会保存为接受的优惠券。 - 已处理
multi、累加器限制和错误501–507。 - 已考虑客户余额的自动借记。
- 所有
coupon_code和投注 ID 均已保存。 - 最终支出取自
real_win。 - 根据源字节检查回调并使用
batchId进行重复数据删除。 - 备份轮询已配置。
- 用户余额与客户余额SportAPI是分开的。
详细文档以API概述开始。完整的端点映射在手册中。