1. 收银订单-收银台对接-供应商使用-v1
开放平台
  • 开放平台 ReadMe
  • 加解签规则
  • 开放平台加解密规范(新)
  • 接口地址
  • 关于小程序
  • 最福利订单状态枚举
  • 最福利物流编码
  • 内部文档-不提供外部使用
  • 供应商
    • 收银订单-收银台对接-供应商使用-v1
      • 加解签规则
      • 发起收银--同步保存商品明细
      • 退款接口-支持退款某个指定商品
      • 查询商品详细信息
        GET
      • 免密登陆
        GET
      • 发起收银
        POST
      • 取消订单
        POST
      • 收银异步通知
        POST
      • 查询交易记录
        POST
      • 发起退款申请
        POST
      • 退款异步通知
        POST
      • 退款状态查询
        POST
      • 跳转第三方订单详情页面
        GET
      • 发起收银-传输用户id
        POST
      • 免密支付
        POST
      • 发起收银--同步保存商品明细(废弃)
        POST
    • 登录相关
      • 跳转外部
        • 个人用户免密登录-跳转到外部(不推荐)
        • 网页授权登陆链接,获取访问用户身份(推荐)
      • 外部跳转最福利
        • 个人用户免密登录-代理版本
        • 个人用户免密登录-普通版本
  • 渠道方
    • 最福利收银台-积分在外部系统-渠道方使用
      • 余额查询
      • 发起交易
      • 发起退款
      • 订单状态推送
      • 交易分页查询
    • 第三方系统收银台-积分在外部系统-渠道方使用
      • 余额查询
      • 发起收银
      • 收银异步通知
      • 查询交易记录
      • 订单状态推送
      • 发起退款
    • 实物商城-api对接-渠道方使用
      • 类目查询
      • 商品列表
      • 查询同类商品
      • 商品详情
      • 商品价格查询
      • 商品库存查询
      • 地址详情转换地址编码
      • 查询省市区收货地址编码
      • 商品下单
      • 商品物流轨迹
      • 商品物流轨迹V3
      • 商品信息查询
      • 京东商品根据skuid查询商品详情
    • 订单系统
      • 确认订单(需传入用户信息)
      • 确认订单(渠道信息作为用户信息)
      • 订单状态变更异步通知
      • 查询订单信息(用户为公司用户)
      • 查询订单信息(需要指定buyerId)
    • 电子卡券对接
      • 电子卡对接ReadMe
      • 电子卡下单
        • 电子卡券下单-个人用户
        • 电子卡券下单-企业用户
      • 电子卡券列表
      • 电子卡券详情
      • 订单状态变更通知
      • 根据订单号查询卡号卡密
      • 电子卡券详情 Copy
    • 充值中心对接
      • 下单
      • 支付
      • 查询充值结果(与支持轮询充值的下单配套使用)
    • 充值1.0
      • 下单
      • 确认支付
      • 订单查询
      • 获取openId链接
      • 获取核销信息
  • 定制需求
    • 永辉
      • 发起收银--同步保存商品明细
      • 发起退款申请---支持退款指定商品
    • 众安订餐定制需求
      • 获取可见的加班餐商户
      • 查询指定商户售卖的套餐信息
      • 获取当前员工所属公司有哪些职场
      • 下单接口 并支付
      • 取消订单
    • 云学堂
      • oa调用稳赢云发消息
    • 体检
      • 【内】下单并静默支付并绑定使用手机号
      • 【内】下单并静默支付并绑定具体使用者信息
      • 下单并静默支付并绑定具体使用者信息
    • 众安十周年需求定制
      • 个人用户免密登录至众安【众安十周年需求】
      • 众安定制接口,根据手机号码查询基础信息
    • 实物商城卡券兑换
      • 给指定用户发放卡券
    • 机票/酒店对接外部渠道
      • 壹钱包对接
        • 航班舱位激励信息查询
        • 机票/酒店下单接口
        • 支付回调--供应商实现
    • 众安积分买保险
      • 相关密钥地址等信息
      • 众安积分买保险-下单并支付
      • 众安积分买保险-退款
    • 众安车险权益商城-途虎养车
      • 众安权益商场下单接口
      • 众安权益商场退款接口
      • 众安查询权益状态
      • 众安传递数据查询核销链接
      • 权益成功后的回调
      • 权益退款成功后的回调
    • 权益商城对接3.0
      • 下单接口
      • 支付成功回调
      • 退款接口
      • 退款成功回调
      • 权益详情查询
      • 支付状态查询
      • 退款状态查询
      • 接口特殊字段信息
    • 快手-体检权益兑换
      • 查询指定员工有哪些体检权益
      • 扣除体检权益
      • 扣除体检权益状态查询
      • 退还体检权益
      • 退还体检权益状态查询
    • 荷叶普药
      • 荷叶普药核销完后异步回调最福利
  • ZALife
    • 查询部门信息
    • 查询员工信息
    • 企微消息通知
    • 网页授权登陆链接,获取访问用户身份(推荐)
  • 积分
    • 积分发放
    • 查询发放详情
    • 可用积分查询-众安专用
  • 通讯录
    • 通用接口规范
    • 同步员工
    • 查询员工
    • 公司列表查询
    • 同步部门
    • 查询部门
  • 收银订单业务-v2
    • 宜员收银订单标准接口文档
      • 宜员订单系统接入文档-加解密规则
      • 联合登录
      • 余额查询
      • 下单接口
      • 订单取消
      • 退款接口
      • 支付状态查询
      • 退款状态查询
      • 支付成功回调
      • 退款成功回调
      • 跳转订单详情页面
      • 错误码
      • 免密支付
    • 客户定制接口
      • 唯品会
        • 拆单后同步宜员系统
        • 唯品会专用,退款详情异步通知
      • 快手对接-AON
        • 免密支付
  • 非对外开放
    • 获取临时凭证
    • 查询差旅对账单数据信息
    • 根据id获取差旅对账单信息
    • 根据时间区间获取third_task 任务表执行情况
  • 开放平台-接口模版
    POST
  • 开放平台-接口模版(对接实例)
    POST
  • 数据模型
    • 体检
      • CardTradeRequest
      • ReserveParams
      • CardTradeResponse
    • BaseResult
    • GwApiResponse
    • ChannelSignedBean
    • GwCommonBean
    • GwApiCommonRequest
    • GwApiRequest
    • 收银订单明细
    • JdAddress
    • BaseResult«JdAddress»
  1. 收银订单-收银台对接-供应商使用-v1

加解签规则

最福利使用https协议,只需要对请求的参数进行加解签即可.请对所有参数进行验签

加签规则(排除sign,signType)#

请求参数 s=XXXX,b=XXXX,a=XXXX
1.
构建签名串:
对请求参数按照字母升序排序, a=XXXX,b=XXXX,s=XXXX(bizcontext 参数中的值不参与排序)
对参数名称,参数值utf8 进行URLEncodeing 且使用&拼接成参数串 a=XXXX&b=XXXX&s=XXXX(可能会有特殊用途)
参数串+appKey
2.
使用MD5算法对以上签名串进行加签,从而获取sign.ps:使用UTF8字符集
3.
将sign作为请求参数,signType=MD5.

验签规则(排除sign,signType)#

请求参数s=YYYY,b=YYYY,a=YYYY,sign=ab6e81f0adc128,signType=MD5
1.
构建验签串
2.
请求参数除sign按照字母升序排序a=YYYY,b=YYYY,s=YYYY
3.
对参数名称,参数值utf8 进行URLEncodeing 且使用&拼接成参数串 a=YYYY&b=YYYY&s=YYYY
参数串+appKey
4.
使用MD5算法对以上签名串进行加签,从而获取targetSign.ps:使用UTF8字符集
如果sign==targetSign验签成功.
注意
各个语言之间 针对特殊字符串的URLEncodeing可能会存在差异,具体需以java URLEncode 后的结果为准。
以下提供java针对某些特殊字符串的URLEncode结果:

 String str = "!\"#$%&'()*+,-./0123456789:;<=>?@ABC[\\]^_`abc{|}~江 西【】「」()北极。;‘《》背景";
 System.out.println(URLEncoder.encode(str, "UTF-8"));
 
 结果:
 %21%22%23%24%25%26%27%28%29*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABC%5B%5C%5D%5E_%60abc%7B%7C%7D%7E%E6%B1%9F+%E8%A5%BF%E3%80%90%E3%80%91%E3%80%8C%E3%80%8D%EF%BC%88%EF%BC%89%E5%8C%97%E6%9E%81%E3%80%82%EF%BC%9B%E2%80%98%E3%80%8A%E3%80%8B%E8%83%8C%E6%99%AF

加签demo python版#

_SIGN='sign'
_SIGNTYPE='signType'

def icareSign(params,appKey):
    #先排序
    params = {k: v for k, v in sorted(params.items(), key=lambda x: x[0])}
    #去除不需要参与加签的字符串
    for k in list(params.keys()):
        if (k.casefold() == _SIGN.casefold() or k.casefold() == _SIGNTYPE.casefold()):
            del params[k]
            continue
    # 计算MD5前的字符串
    md5Str = urllib.parse.urlencode(params) + appKey
    print("md5Str--括号内字符串-->(%s)" % ( md5Str))
    # 计算签名
    sign = hashlib.md5(md5Str.encode(encoding='utf-8')).hexdigest()
    return sign

加签demo java版本#

public void doWork(Config config) {
        Map<String, String> map = new HashMap<>();
        map.put("channelCode", config.getChannelCode());
        map.put("thirdUserId", config.getThirdUserId());
        map.put("charset", "UTF8");
        map.put("nonce", UUID.randomUUID().toString());
        map.put("name", "我爱吃西瓜");
        map.put("phone", "15112121234");
        map.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //扩展信息======================start
        Map<String, Object> bizContentMap = new HashMap<>();
        //当redirect 填入指定值后,免密登录成功由最福利跳转到该指定的页面,不填入则默认跳转到最福利首页
        bizContentMap.put("redirect", "https://t-ord.zuifuli.com/m/customer");
        map.put("bizContent", JSON.toJSONString(bizContentMap));
        //扩展信息======================end
        String sign = ZflSignUtil.sign(map, ImmutableSet.of("sign", "signType"), config.getAppKey(), false);
        map.put("sign", sign);
        map.put("signtType", "MD5");
        String query = ZflSignUtil.buildQuery(map, null, StandardCharsets.UTF_8.name(), true);
        String requestUrl = String.format("%s?%s", config.getLoginUrlPersonalV2(), query);
        System.out.println(String.format("联合登录的请求的地址:%s", requestUrl));
    }
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class ZflSignUtil {

    /**
     * @param params      请求参数
     * @param excludSet   ImmutableSet.of("sign", "signType")
     * @param appKey
     * @param isLowerCase  是否转小写
     * @return
     */
    public static String sign(Map<String, String> params, Set<String> excludSet, String appKey, boolean isLowerCase) {
        params = exclude(params, excludSet);
        String s = buildQuery(params, null, "UTF-8", true);
        if (isLowerCase) {
            s = s.toLowerCase();
        }
        return string2MD52(s + appKey);
    }

    /**
     * 构建加密参数
     *
     * @param params
     * @param paramsSortSet
     * @param charset
     * @param emptyIgnore
     * @return
     */
    public static String buildQuery(Map<String, String> params, Set<String> paramsSortSet, String charset, boolean emptyIgnore) {
        StringBuffer sb = new StringBuffer();
        if (paramsSortSet == null) {
            paramsSortSet = new TreeSet<>(params.keySet());
        }
        for (String paraName : paramsSortSet) {
            try {
                String value = params.get(paraName);
                if (StringUtils.isEmpty(value) && emptyIgnore)
                    continue;
                sb.append(URLEncoder.encode(paraName, charset));
                sb.append("=");
                sb.append(URLEncoder.encode(value == null ? "" : value, charset));
                sb.append("&");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
        if (sb.length() > 0) {
            sb.delete(sb.length() - 1, sb.length());
        }
        return sb.toString();
    }

    /**
     * md5
     */
    private static String string2MD52(String md5) {
        System.out.println("MD5前的字符串:"+md5);
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(md5.getBytes());
            return Hex.encodeHexString(array);
        } catch (java.security.NoSuchAlgorithmException e) {
        }
        return null;
    }

    /**
     * 排除指定的字段
     * @param params
     * @param paramExclude
     * @return
     */
    private static Map<String, String> exclude(Map<String, String> params, Set<String> paramExclude) {
        if (paramExclude != null) {
            for (String key : paramExclude) {
                params.remove(key);
            }
        }
        return params;
    }
}

c#版本urlEncode#

// 这个方法是为了跟java的encode相兼容
        public static string Encode(string s)
        {
            StringBuilder sb = new StringBuilder(s.Length * 2);
            byte[] arr = Encoding.UTF8.GetBytes(s);
            for (int i = 0; i < arr.Length; i++)
            {
                byte c = arr[i];
                if (c == '*' || c == '_' || c == '-' || c == '.')
                    sb.Append((char)c);
                else if(c == ' ')
                    sb.Append((char)'+');
                else if (c >= 0x41 && c <= 0x5A)//A-Z
                    sb.Append((char)c);
                else if (c >= 0x61 && c <= 0x7A)//a-z
                    sb.Append((char)c);
                else if (c >= 0x30 && c <= 0x39)//123456789
                    sb.Append((char)c);
                else
                {
                    sb.Append('%');
                    sb.Append(Convert.ToString(c, 16).ToUpper());//转成 16进制
                }
            }
            return sb.ToString();
        }
    }

自用工具使用Demo(工具类使用上文的ZflSignUtil)#

public class DemoAction {
    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String now = sdf.format(new Date());
        String nonce = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        Map<String,String> params = new HashMap<>();
        params.put("merchantCode","yonghuichaoshi");
        params.put("timestamp",now);
        params.put("charset","UTF8");
        params.put("nonce",nonce);
        Set<String> exclude = new HashSet<>();
        exclude.add("sign");
        exclude.add("signType");
        String sign = ZuifuliSignUtil.sign(params, exclude, "nOjRu2V4FDjNyCqkMJSpQMuXEUxYoj", true);
        params.put("sign",sign);
        params.put("signType","MD5");
        log.info("---------------------------" + JSON.toJSONString(params));

    }
}
修改于 2026-03-13 08:38:51
上一页
收银订单-收银台对接-供应商使用-v1
下一页
发起收银--同步保存商品明细
Built with