在电商和零售行业,卡券系统是促进销售、提升用户体验的重要工具。卡券核销作为整个流程中的关键环节,其稳定性和可靠性直接影响到商户和消费者的体验。本文将深入分析卡券核销接口V2版本的设计原理、使用方法和最佳实践,帮助开发者更好地理解和应用这一接口。
卡券核销接口V2版本(/coupons/verifyV2)是一个用于验证和核销电子卡券的API接口。该接口需要获取店铺授权,主要功能包括:
相比于V1版本,V2版本主要增加了以下特性:
subCode:isv.business-failed:10029,用于处理并发请求场景hmac-sha256替代md5接口采用HTTP/HTTPS协议,请求方法为GET或POST(根据平台要求)。请求URL基本格式如下:
https://openapi-fxg.jinritemai.com?app_key=your_appkey_here&method=coupons.verifyV2&...所有请求必须包含以下公共参数:
参数名称 | 类型 | 必填 | 示例值 | 描述 |
|---|---|---|---|---|
method | String | 是 | coupons.verifyV2 | 调用的API接口名称 |
app_key | String | 是 | 6839996111118329223 | 应用创建完成后被分配的key |
access_token | String | 是 | edae7c30-8386-443b-88a1-031111 | 用于调用API的access_token |
param_json | String | 是 | {“cid”:12,“page”:1} | 业务参数JSON字符串 |
timestamp | String | 是 | 2020-09-15 14:48:13 | 时间戳,格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8 |
v | String | 是 | 2 | API协议版本 |
sign | String | 是 | 796559d40beb08a1a1113c456c5c5a62 | 输入参数签名结果 |
sign_method | String | 否 | hmac-sha256 | 签名算法类型(推荐使用hmac-sha256,不传则默认为"md5",未来会下线) |
在param_json中需要传递的业务参数如下:
参数名称 | 类型 | 必填 | 示例值 | 描述 |
|---|---|---|---|---|
cert_no | String | 是 | “123456” | 卡券号码 |
verify_time | Int64 | 否 | 1614787200000 | 核销时间(时间戳) |
batch_no | String | 否 | “3” | 幂等请求id,用于防止重复请求 |
verify_count | Int64 | 否 | 1 | 当次核销的次数 |
cert_key | String | 否 | “12345” | 卡券密码 |
cert_type | Int64 | 否 | 1 | 卡券类型:0-电商三方卡券,1-即时零售提货券等 |
store_id | Int64 | 否 | 123 | 门店Id(提货券核销必传) |
verify_order_id | String | 否 | “123123” | 三方订单Id |
check_verify_order_id | Bool | 否 | false | 是否检查订单Id和卡券号码的关联关系 |
签名是API调用安全性的重要保障,以下是使用hmac-sha256算法生成签名的示例代码:
import hmac
import hashlib
import urllib.parse
def generate_sign(params, secret_key):
# 将参数按key排序
sorted_params = sorted(params.items(), key=lambda x: x[0])
# 构建待签名字符串
query_string = '&'.join([f"{k}={v}" for k, v in sorted_params])
# 使用hmac-sha256算法生成签名
signature = hmac.new(
secret_key.encode('utf-8'),
query_string.encode('utf-8'),
hashlib.sha256
).hexdigest()
return signature
# 示例参数
params = {
"method": "coupons.verifyV2",
"app_key": "6839996111118329223",
"timestamp": "2020-09-15 14:48:13",
"v": "2",
"param_json": '{"cert_no":"123456"}'
}
secret_key = "your_app_secret"
sign = generate_sign(params, secret_key)
print(f"生成的签名: {sign}")以下是一个完整的Python请求示例:
import requests
import json
import time
from urllib.parse import quote
def verify_coupon_v2(cert_no, access_token, app_key, app_secret, store_id=None):
# 基础URL
base_url = "https://openapi-fxg.jinritemai.com"
# 准备公共参数
params = {
"method": "coupons.verifyV2",
"app_key": app_key,
"access_token": access_token,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
"v": "2",
"sign_method": "hmac-sha256"
}
# 准备业务参数
business_params = {
"cert_no": cert_no,
"verify_time": int(time.time() * 1000) # 当前时间戳毫秒级
}
# 如果有门店ID,添加到业务参数
if store_id:
business_params["store_id"] = store_id
# 将业务参数转为JSON字符串并排序
sorted_business_params = json.dumps(business_params, sort_keys=True)
params["param_json"] = sorted_business_params
# 生成签名
sign = generate_sign(params, app_secret)
params["sign"] = sign
# 构建查询字符串
query_string = "&".join([f"{k}={quote(str(v))}" for k, v in params.items()])
# 发送请求
url = f"{base_url}?{query_string}"
response = requests.get(url)
return response.json()
# 使用示例
result = verify_coupon_v2(
cert_no="123456",
access_token="your_access_token",
app_key="your_app_key",
app_secret="your_app_secret",
store_id=123
)
print(result)接口响应为JSON格式,基本结构如下:
{
"code": 10000,
"msg": "success",
"sub_code": "",
"sub_msg": ""
}主要响应字段说明:
code: 主返回码,10000表示成功msg: 主返回信息sub_code: 子返回码,用于更详细的错误分类sub_msg: 子返回信息以下是常见的错误码及其处理建议:
主返回码 | 子返回码 | 描述 | 解决方案 |
|---|---|---|---|
10000 | - | 成功 | - |
40002 | isv.missing-parameter:000002 | 缺少必选参数 | 检查必填参数是否全部提供 |
50002 | isv.business-failed:010002 | 非未使用状态电子凭证禁止核销 | 检查卡券状态 |
50002 | isv.business-failed:010009 | 核销数量超出最大可核销数量 | 调整核销数量 |
50002 | isv.business-failed:010017 | 未在有效期内禁止核销 | 检查卡券有效期 |
50002 | isv.business-failed:10006 | 找不到该电子凭证 | 检查卡券号码是否正确 |
50002 | isv.business-failed:010014 | 卡密校验失败 | 检查卡券密码 |
50002 | isv.business-failed:10029 | 并发请求,请稍后重试 | 实现重试机制,避免频繁调用 |
50002 | isv.business-failed:9999 | 系统内部错误 | 联系平台技术支持 |
为了防止重复核销,建议使用batch_no参数实现幂等性控制:
import uuid
# 生成唯一的batch_no
batch_no = str(uuid.uuid4())
# 在业务参数中添加batch_no
business_params = {
"cert_no": "123456",
"batch_no": batch_no,
# 其他参数...
}针对并发请求错误(10029),可以实现自动重试机制:
import time
def verify_with_retry(cert_no, max_retries=3):
retries = 0
while retries < max_retries:
result = verify_coupon_v2(cert_no)
if result.get("code") == 10000:
return result
elif result.get("sub_code") == "isv.business-failed:10029":
retries += 1
time.sleep(1 * retries) # 指数退避
else:
return result
raise Exception("Max retries exceeded")对于批量核销场景,可以考虑以下优化策略:
verify_count参数,减少API调用次数app_secret和access_token卡券核销接口V2版本提供了稳定、安全的卡券核销能力,支持多种业务场景。通过本文的详细解析,开发者可以:
在实际应用中,建议结合业务需求,封装适合自己业务的SDK,简化接口调用流程,提高开发效率。同时,密切关注平台API更新,及时调整实现以适应新版本特性。