e-Buy 权益平台
接入指南
接口域名
| 测试环境 | https://test-rights-platform.e-buy.com |
| 生产环境 | https://rights-platform.e-buy.com |
接口调用方式
| 提交方式 | HTTP POST方式提交,CONTENT-TYPE为application/json |
| 报文格式 | json |
| 字符编码 | utf-8 |
| 签名算法 | sha256 |
安全规范
- 拼接报文参数
除sign参数外的所有参数按照ASCII顺序排序后,以"参数名1=参数值1&参数名2=参数值2"的方式拼接所有参数
- bizContent业务参数
对所有业务参数的json格式做base64再行拼接
- 拼接签名 appSecret(由易百分配)
最后在尾部拼接双方约定的密钥"appSecret=xxxxx",
- 签名值计算
sha256加密后即为签名值,并赋给sign参数。
- 注
当参数值为null或为空时不参与签名串拼接
- JAVA签名参考代码
JSONObject notifyJson = new JSONObject(true);
notifyJson.put("orderNo", "4200001172202109274275163730");
notifyJson.put("transDateTime", "20210928102350");
notifyJson.put("ebuyCode", "1002108300000059091");
notifyJson.put("faceValue", "30");
notifyJson.put("outTradeNo", "89392109280163981");
byte[] encodeBase64 = Base64.encodeBase64(notifyJson.toJSONString().getBytes("UTF-8"));
String bizContent = new String(encodeBase64, "UTF-8");
Map<String, String> map = new TreeMap<>();
map.put("appKey", "274b9cf9f01543619baa726ed24ddd19");
map.put("signType", "sha256");
map.put("timestamp", "1483372334");
map.put("bizContent", bizContent);
StringBuilder buffer = new StringBuilder();
for (Map.Entry<String, String> item : map.entrySet()) {
buffer.append(item.getKey()).append("=").append(item.getValue()).append("&");
}
String signStr = buffer.toString() + "appSecret=XXXXXXXXXXXX";// appSecret(需易百提供);
String checkSign = SHAUtil.sha256(signStr);
System.out.println(signStr);
System.out.println(checkSign);
拼接后签名串:action=verify&appKey=274b9cf9f01543619baa726ed24ddd19&bizContent=eyJvcmRlck5vIjoiNDIwMDAwMTE3MjIwMjEwOTI3NDI3NTE2MzczMCIsInRyYW5zRGF0ZVRpbWUiOiIyMDIxMDkyODEwMjM1MCIsImVidXlDb2RlIjoiMTAwMjEwODMwMDAwMDA1OTA5MSIsImZhY2VWYWx1ZSI6IjMwIiwib3V0VHJhZGVObyI6Ijg5MzkyMTA5MjgwMTYzOTgxIn0=&charset=utf-8&format=json&signType=sha256×tamp=1483372334&appSecret=XXXXXXXXXXXX
最终签名值:bc151776f32a0eed26fd97696ece7e8102e5c1f8f594fbf8ddc392bd579693f1
接口清单及说明
| 接口调用名称 | 接口名称 | 接口适用场景 | 调用方向 |
| queryCodeDetail | 券查询接口 | 查询券关联的产品及活动详细信息 | 外部商户/渠道 调用易百 |
| codeExchange | 券兑换接口 | 用户在商户/渠道侧绑定或兑换易百券 | 外部商户/渠道 调用易百 |
| codeStatusUpdate | 券状态变更 | 外部渠道调易百做券状态更新,如 作废、延期、冻结解冻等,更多类型见接口定义 | 外部商户/渠道 调用易百 |
| verify | 券核销接口 | 核销券,该接口成功后券为 “已使用” | 外部商户/渠道 调用易百 |
| verifyVoid | 券核销撤销接口 | 回退核销交易,该接口成功后券为 “可使用” | 外部商户/渠道 调用易百 |
| 券状态变更通知 | 券状态发生变更时易百通知渠道/商户,如 作废、延期、冻结等,详情见接口定义 | 易百调用 外部商户/渠道,需商户/渠道向易百提供回调URL |
公共参数
请求公共参数
| 参数名 | 说明 | 类型 | 是否必填 | 备注 |
| appKey | 由易百分配 | String(32) | 是 | |
| sign | 签名值 | String(400) | 是 | |
| timestamp | 时间戳(毫秒) | Number(13) | 是 | |
| bizContent | 业务参数集合 | 是 |
返回公共参数
| 参数名 | 说明 | 类型 | 是否必填 | 备注 |
| returnCode | 返回码 | String(20) | 是 | 00: 成功 其他为失败或异常 |
| returnMsg | 返回描述 | String(200) | 是 | |
| data | 具体的交易请求返回结果 | Object | 否 |
电子券业务API
券详情查询
请求参数
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| code | String | 是 | 券号 | |
| orderNo | String | 否 | 制码订单号 | 暂时支持一单一券场景 |
| traceNo | String | 是 | 交易流水号 | 全局唯一 |
响应结果
| 字段 | 数据项 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|---|
| data | codeUrl | String | 否 | 券短链 | 券二维码 |
| code | String | 是 | 券号 | ||
| ebuyTicketId | String | 是 | 易百券批次号 | ||
| faceValue | String | 是 | 券面值 | 单位(元) | |
| validStart | String | 否 | 券有效期 起 | 格式: yyyy-mm-dd hh:mm:ss | |
| validEnd | String | 否 | 券有效期 止 | 格式: yyyy-mm-dd hh:mm:ss | |
| codeStatus | String | 是 | 券状态 | 00:未使用 01:已使用 08:已兑换 04:已冻结 05:已作废 06:已过期 |
|
| codeStatusDesc | String | 否 | 券状态描述 | ||
| activityName | String | 否 | 活动名称 | ||
| activityId | String | 否 | 活动编号 | ||
| activityProductNo | String | 否 | 活动产品编号 | ||
| productName | String | 否 | 产品名称 | ||
| ticketType | String | 否 | 券类型 |
券兑换
请求参数
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| code | String | 是 | 券号 | |
| traceNo | String | 是 | 交易流水号 | 全局唯一 |
响应结果
| 字段 | 数据项 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|---|
| data | code | String | 是 | 券号 | |
| exchangeResult | String | 是 | 兑换结果 | 00:兑换成功,其他为兑换失败 | |
| exchangeDesc | String | 是 | 兑换结果描述 |
券状态变更
请求参数
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| code | String | 是 | 券号 | 多个券号用英文逗号隔开(对接批量券状态更新需提前和易百沟通,暂时默认不支持批量操作) |
| traceNo | String | 是 | 交易流水号 | 全局唯一 |
| updateType | String | 是 | 更新类型 | 支持作废、冻结、解冻; 枚举值见备注 |
注: updateType 枚举
| updateType | 操作名称 | 更新前状态 | 更新后状态 | 备注 |
|---|---|---|---|---|
| invalid | 串码作废 | 00:未使用、初始化 03:未激活 04:已冻结 |
05:已作废 | |
| freeze | 冻结串码 | 00:未使用 | 04:已冻结 | 已冻结的串码,可以调用解冻操作后恢复原状态 |
| unfreeze | 解冻串码 | 04:已冻结 | 00:未使用 |
响应结果
| 字段 | 数据项 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|---|
data |
code | String | 是 | 券号 | |
| codeUpdateResult | String | 是 | 券更新结果 | 00:更新成功, 其他为失败 |
券码核销
请求参数
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| code | String | 是 | 券号 | 多张券码用逗号隔开,英文逗号 |
| traceNo | String | 是 | 交易流水号 | 全局唯一 |
| shopNo | String | 是 | 门店编号 | |
| shopName | String | 否 | 门店名称 | |
| tansTime | String | 是 | 核销时间 | 格式 yyyyMMddhhssSSS |
| goodsList | List<GoodsInfo> | 否 | 券兑换的商品明细 | 代金券默认为A0001 |
| totalAmount | String | 是 | 订单总金额 | 单位(元) |
| verifyScene | String | 是 | 核销场景 | 线上:online, 线下:offline |
GoodsInfo
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| goodsId | String | 是 | 券兑换商品id | |
| price | String | 是 | 兑换商品金额 | 全局唯一 |
| rebateCode | String | 否 | 标签编号 | |
| count | String | 是 | 兑换商品数量 | 默认为1 |
响应结果
| 字段 | 数据项 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|---|
| data | List<VerifyResultData> | List | 是 | 核销结果集 |
VerifyResultData定义
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| verifyResult | String | 是 | 核销结果 | 00:成功 其他为失败 |
| activityNo | String | 否 | 活动编号 | |
| activityName | String | 否 | 活动名称 | |
| totalAmount | String | 否 | 订单总金额 | 单位(元) |
| userRealAmount | String | 否 | 用户购券实付金额 | 单位(元) |
| merchantRealAmount | String | 否 | 商户实收金额 | 单位(元) |
| discountAmount | String | 否 | 券折抵金额 | 单位(元) |
| channelBenefit | String | 否 | 渠道优惠金额 | 单位(元) |
| merchantBenefit | String | 否 | 商户优惠金额 | 单位(元) |
| faceValue | String | 否 | 券面值 | 单位(元) |
| remainUseTimes | String | 否 | 剩余可用次数 | |
| code | String | 是 | 券号 |
券核销撤销
请求参数
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| code | String | 是 | 券号 | 多个券用逗号隔开,不传默认撤销originTraceNo 对应核销的所有券 |
| traceNo | String | 是 | 当前交易流水号 | 全局唯一 |
| originTraceNo | String | 是 | 核销时上送的流水号 | |
| originVerifyDate | String | 否 | 原核销日期 | yyyyMMdd |
响应结果
| 字段 | 数据项 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|---|
| data | List<VerifyVoidResultData> | List | 是 | 核销撤销结果 |
VerifyVoidResultData定义
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| resultDesc | String | 否 | 核销撤销结果结果描述 | |
| result | String | 否 | 核销撤销结果 | 00: 成功 其他为失败 |
| code | String | 是 | 券号 | |
| ticketId | String | 是 | 券批次id |
|
券状态变更通知
请求参数
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| code | String | 是 | 券号 | |
| traceNo | String | 是 | 当前交易流水号 | 全局唯一 |
| saleChannelOrderId | String | 否 | 发券时渠道侧订单号 | 核销、核销撤销场景必传 |
| shopNo | String | 否 | 核销门店编号 | 核销场景必传 |
| timeStamp | String | 否 | 发生时间戳(毫秒) | |
| notifyType | String | 是 | 当前通知交易类型 | |
| validStartDate | String | 否 | 券有效期开始时间 | yyyy-MM-dd HH:mm:ss |
| validEndDate | String | 否 | 券有效期截止时间 | yyyy-MM-dd HH:mm:ss |
注: notifyType 枚举
| notifyType | 操作名称 | 更新前状态 | 更新后状态 |
|---|---|---|---|
| verifyNotify | 券核销 | 未使用 | 已使用 |
| verifyCancelNotify | 券核销撤销 | 已使用 | 未使用 |
| invalidNotify | 券作废 | 未使用 | 已作废 |
| renewalNotify | 券延期 | 已过期 | 可使用 |
| expireNotify | 过期通知 | 过期 | 已过期 |
通知报文(案例)签名过程:
JSONObject notifyJson = new JSONObject(true);
notifyJson.put("code", "10034343334344443209");
notifyJson.put("traceNo", "4200001172202109274275163730");
notifyJson.put("notifyType", "verifyNotify");
byte[] encodeBase64 = Base64.encodeBase64(notifyJson.toJSONString().getBytes("UTF-8"));
String bizContent = new String(encodeBase64, "UTF-8");
Map<String, String> map = new TreeMap<>();
map.put("appKey", "274b9cf9f01543619baa726ed24ddd19");
map.put("action", "verifyNotify");
map.put("format", "json");
map.put("charset", "utf-8");
map.put("signType", "sha256");
map.put("timestamp", "1483372334");
map.put("bizContent", bizContent);
StringBuilder buffer = new StringBuilder();
for (Map.Entry<String, String> item : map.entrySet()) {
buffer.append(item.getKey()).append("=").append(item.getValue()).append("&");
}
String signStr = buffer.toString() + "appSecret=XXXXXXXXXXXX";// appSecret(需易百提供);
String checkSign = SHAUtil.sha256(signStr);
System.out.println(signStr);
System.out.println(checkSign);
}
参与签名报文字符串:
action=verifyNotify&appKey=274b9cf9f01543619baa726ed24ddd19&bizContent=eyJjb2RlIjoiMTAwMzQzNDMzMzQzNDQ0NDMyMDkiLCJ0cmFjZU5vIjoiNDIwMDAwMTE3MjIwMjEwOTI3NDI3NTE2MzczMCIsIm5vdGlmeVR5cGUiOiJ2ZXJpZnlOb3RpZnkifQ==&charset=utf-8&format=json&signType=sha256×tamp=1483372334&appSecret=XXXXXXXXXXXX
签名结果:
17e9fe1250c33fccf517ce4b5810f2c731fa45058181a15cffc4ab38332460d4
响应结果
| 字段 | 类型(最大长度) | 是否必填 | 字段含义 | 备注 |
|---|---|---|---|---|
| resultDesc | String | 否 | 通知结果描述 | |
| result | String | 否 | 通知结果 | 00: 成功 其他为失败 |
支付业务API
订单支付
接口用途
用户展示付款码由店员使用扫码设备读取付款码信息上送
接口地址
/payment/tradePay
请求参数
| 参数名 |
说明 | 类型 | 是否必填 | 备注 | |
| bizContent | traceNo | 交易流水号 | String(32) | 是 | 同一商户全局唯一,用于标识唯一交易 |
| paymentChannelId | 支付渠道ID | String(32) | 否 | 当收款方需要指定支付渠道时填值(由易百分配) | |
| merOrderNo | 商户订单号 | String(32) | 是 | 同一商户全局唯一,用于关联收银机订单号 | |
| orderAmount | 订单原始金额 | Number | 否 | 单位分,收银前端原始点单金额 | |
| totalAmount | 待支付总金额 | Number | 是 | 单位分,收银前端已优惠过剩下要支付的金额 | |
| deviceNo | 设备号 | String(32) | 是 | 收银机具终端编号 | |
| storeId | 商户门店编号 | String(32) | 是 | 商户门店编号 | |
| storeName | 商户门店名称 | String(256) | 是 | 商户门店名称 | |
| returnOptions | 返回选项 | String[](300) | 否 | 需与易百技术约定后启用 | |
| goodsTag | 订单优惠标记 | String(32) | 否 | 特殊活动标记,需与易百技术约定后启用 | |
| authCode | 付款码 | String(32) | 是 | ||
| subject | 订单标题 | String(256) | 是 | ||
| orderTime | 订单创建时间 | String(19) | 是 | yyyy-MM-dd HH:mm:ss | |
| notifyUrl | 支付回调地址 | String(200) | 否 | ||
| goodsDetailList | 订单商品明细 | List | 否 | ||
| |__ gid | 商品编号 | String(32) | 是 | ||
| |__ gname | 商品名称 | String(256) | 是 | ||
| |__ quantity | 商品数量 | Number | 是 | ||
| |__ price | 商品价格 | Number | 是 | 单位分 | |
| |__ category | 商品类目 | String(32) | 是 | ||
请求示例
"bizContent": {
"traceNo": "20240710112246541_11130101",
"merOrderNo": "0007525202407100000835",
"totalAmount": 3300,
"deviceNo": "83520001",
"storeId": "111301",
"goodsTag": "",
"authCode": "132951513806421759",
"subject": "中-冰美式",
"notifyUrl": "",
"goodsDetailList": [
{
"gid": "010403",
"gname": "中-冰美式",
"quantity": 1,
"price": 3300,
"category": "2"
}
]
}
返回参数
| 参数名 |
说明 | 类型 | 是否必填 | 备注 | |
| data |
payChannel | 支付渠道 | String(32) | 是 | wxpay微信;alipay支付宝;dongfu东福随心兑 |
| transactionNo | 易百交易号 | String(32) | 是 | ||
| paymentNo | 收单机构交易号 | String(40) | 否 | ||
| traceNo | 交易流水号 | String(32) | 是 | 按请求原样下发 | |
| transTime | 交易时间 | String(19) | 是 | yyyy-MM-dd HH:mm:ss | |
| account | 支付账号 | String(40) | 否 | ||
| openId | 用户唯一标识 | String(128) | 否 | ||
| totalAmount | 交易总金额 | Number | 是 | 单位分,按请求原样下发 | |
| receiptAmount | 实收金额 | Number | 是 | 单位分 | |
| mdiscountAmount | 商家优惠金额 | Number | 否 | 单位分 | |
| discountAmount | 平台优惠金额 | Number | 否 | 单位分 | |
| payAmount | 用户付款金额 | Number | 是 | 单位分 | |
| invoiceAmount | 给用户可开发票金额 | Number | 是 | 单位分 | |
| storeName | 交易门店名称 | String(200) | 是 | ||
| voucherDetailList | 交易支付所用优惠券信息 | List | 否 | ||
| |__ activityId | 活动ID或券模板ID | String(32) | 否 | ||
| |__ id | 券ID | String(32) | 是 | ||
| |__ name | 券名称 | String(64) | 是 | ||
| |__ type | 券类型 | String(32) | 是 | ||
| |__ amount | 券面额 | Number | 是 | 单位分 | |
| |__ merchantContribute | 商家出资 | Number | 否 | 单位分 | |
| |__ otherContribute | 其他出资方 | Number | 否 | 单位分 | |
| |__ purchaseBuyerContribute | 用户购买实付金额 | Number | 否 | 单位分 | |
| |__ purchaseMerchantContribute | 用户购买商家优惠金额 | Number | 否 | 单位分 | |
| |__ purchaseAntContribute | 用户购买平台优惠金额 | Number | 否 | 单位分 | |
返回示例
{
"data": {
"payChannel": "wxpay",
"transactionNo": "",
"paymentNo": "4200002227202407102297768192",
"traceNo": "20240710112246541_11130101",
"transTime": "2024-07-10 11:28:54",
"account": "",
"openId": "o2Jh6jtk9v28kSk2GUuyqhtdzUTs",
"totalAmount": 3300,
"receiptAmount": 3300,
"mdiscountAmount": 0,
"discountAmount": 0,
"payAmount": 3300,
"invoiceAmount": 3300,
"storeName": "xxx昆山首创奥特莱斯店"
}
}
查询订单
接口用途
当调用订单支付接口失败、网络超时、交易状态未知时调此接口来查询订单结果信息
接口地址
/payment/query
请求参数
| 参数名 |
说明 | 类型 | 是否必填 | 备注 | |
| bizContent | traceNo | 交易流水号 | String(32) | 是 | 全局唯一,用于标识唯一交易 |
| originalTraceNo | 原支付流水号 | String(32) | 是 | ||
| originalDate | 原交易日期 | String(8) | 否 | 传入需要查询的原交易日期,不传默认为当天格式为yyyyMMdd | |
请求示例
"bizContent": {
"traceNo": "20240710112246541_11140102",
"originalTraceNo": "20240710112246541_11130101",
"originalDate": 20240710
}
返回参数
| 参数名 |
说明 | 类型 | 是否必填 | 备注 | |
|
data |
payChannel | 支付渠道 | String(32) | 是 | |
| transactionNo | 易百交易号 | String(32) | 是 | ||
| paymentNo | 收单机构交易号 | String(40) | 否 | ||
| traceNo | 交易流水号 | String(32) | 是 | 按请求原样下发 | |
| transTime | 交易时间 | datetime | 是 | ||
| account | 支付账号 | String(40) | 否 | ||
| openId | 用户唯一标识 | String(128) | 否 | ||
| totalAmount | 交易总金额 | Number | 是 | 单位分,按请求原样下发 | |
| receiptAmount | 实收金额 | Number | 是 | 单位分 | |
| mdiscountAmount | 商家优惠金额 | Number | 否 | 单位分 | |
| discountAmount | 平台优惠金额 | Number | 否 | 单位分 | |
| payAmount | 用户付款金额 | Number | 是 | 单位分 | |
| invoiceAmount | 给用户可开发票金额 | Number | 是 | 单位分 | |
| storeName | 交易门店名称 | String(200) | 是 | ||
返回示例
{
"data": {
"payChannel": "wxpay",
"transactionNo": "",
"paymentNo": "4200002227202407102297768192",
"traceNo": "20240710112246541_11130101",
"transTime": "2024-07-10 11:28:54",
"account": "",
"openId": "o2Jh6jtk9v28kSk2GUuyqhtdzUTs",
"totalAmount": 3300,
"receiptAmount": 3300,
"mdiscountAmount": 0,
"discountAmount": 0,
"payAmount": 3300,
"invoiceAmount": 3300,
"storeName": "xxx昆山首创奥特莱斯店"
}
}
申请退款
接口用途
当用户或商户要进行支付后退款时调用此接口
接口地址
/payment/refund
请求参数
| 参数名 |
说明 | 类型 | 是否必填 | 备注 | |
| bizContent | traceNo | 交易流水号 | String(32) | 是 | 全局唯一,用于标识唯一交易 |
| storeId | 商户门店编号 | String(32) | 是 | ||
| originalTraceNo | 原支付流水号 | String(32) | 是 | ||
| originalDate | 原交易日期 | String(8) | 否 | 传入需要退款的原支付交易日期,不传默认为当天,格式为yyyyMMdd | |
| refundAmount | 本次退款金额 | Number | 是 | 单位分 | |
| refundReason | 退款原因 | String(128) | 是 | ||
请求示例
"bizContent": {
"traceNo": "20240906NJ0070101960163503934",
"storeId": "111301",
"originalTraceNo": "20240906NJ0070101960163406444",
"originalDate": "20240906",
"refundAmount": 13,
"refundReason": "正常退款"
}
返回参数
| 参数名 |
说明 | 类型 | 是否必填 | 备注 | |
| data |
traceNo | 交易流水号 | String(32) | 是 | 全局唯一,用于标识唯一交易 |
| transactionNo | 易百交易号 | String(32) | 是 | ||
| refundNo | 收单机构退款单号 | String(40) | 否 | ||
| transTime | 交易时间 | datetime | 是 | ||
| refundAmount | 退款成功总金额 | Number | 是 | 单位分 | |
| storeName | 交易门店名称 | String(200) | 是 | ||
返回示例
{
"data": {
"traceNo": "20240906NJ0070101960163503934",
"refundNo": "20240906NJ0070101960163406444",
"transTime": "2024-07-10 11:28:54",
"refundAmount": 13,
"storeName": "xxx昆山首创奥特莱斯店"
}
}