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

    开放平台加解密规范(新)

    1.概述#

    客户平台通过调用宜员开放平台接口使用宜员相关服务。

    2.接口基本信息#

    名称请求方式
    请求方式post
    content-typex-www-form-urlencoded
    调用地址测试环境: https://t-open.zuifuli.com/api
    生产环境: https://open.zuifuli.com/api
    调用方客户平台
    响应方宜员
    调用限频每分钟访问不超过100次,每天累计访问不超过100000次

    2.1 请求体#

    名称类型是否必填示例说明
    channelCodeString是yiyuan渠道编号
    serviceNameString是order.pay服务名称
    versionString是1.0版本号
    timestampString是yyyy-MM-dd HH:mm:ss若请求发起时间与平台接受请求时间相差大于30秒,平台将直接拒绝本次请求
    bizContentString是UsdgtxhojCjGjPjQjIzodP具体需要请求的服务的业务参数信息,详情信息请参考serviceName所需要的参数信息。序列化后进行加密

    2.4 响应参数#

    名称类型是否必填示例说明
    resultCodeString是-响应编码
    resultDescString否-响应描述
    timestampString否-响应时间
    bizContentString否-具体响应业务参数,使用AES解密

    3 示例demo#

    3.1请求demo#

    package com.zuifuli.ken.zuifuli_api;
    
    import com.alibaba.fastjson.JSON;
    import com.ken.demo.encry.aes.EncryptUtil;
    import com.zuifuli.ken.OkHttpClientUtil;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    public class Demo {
        public static String channelCode = "rlzy";
        public static String appKey = "R6kcK5uBm63w27de1kFzlA==";
        public static String apiUrl = "https://t-open.zuifuli.com/api";
    
        public static void main(String[] args) throws Exception {
            Map<String, String> httpReqMap = new HashMap<>();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            httpReqMap.put("channelCode", channelCode);
            //取调用宜员接口的时间,与宜员服务器的时间差不可超过30秒
            httpReqMap.put("timestamp", simpleDateFormat.format(new Date()));
            httpReqMap.put("serviceName", "recharge.mobile.order");
            httpReqMap.put("version", "3.0");
            httpReqMap.put("bizContent", buildBizContent());
            //注意是x-www-form-urlencoded,不是application/json
            String resp = OkHttpClientUtil.doPost(apiUrl, null, httpReqMap);
            System.out.println("http响应报文:" + resp);
        }
    
        /**
         * 以下方法是组装具体的某个serviceName 所对应的业务参数
         *
         * @return 将参数序列化后进行加密进行返回
         * @throws Exception
         */
        private static String buildBizContent() throws Exception {
            //以下参数是根据具体的业务场景按需替换
            Map<String, Object> bizContentMap = new HashMap<>();
            bizContentMap.put("channelOrderId", "1000001");
            bizContentMap.put("face", "30");
            bizContentMap.put("accoutNo", "15112181812");
            bizContentMap.put("chargeType", "mobile");
            bizContentMap.put("channelCode", "rlzy");
            String originStr = JSON.toJSONString(bizContentMap);
            System.out.println("加密前的原文:" + originStr);
            String encryptedCiphertext = EncryptUtil.aesEncrypt(originStr, appKey);
            System.out.println("加密后的密文:" + encryptedCiphertext);
            return encryptedCiphertext;
        }
    
    
    }
    
    

    3.2加解密工具包#

    
    import com.zuifuli.common.constant.ErrorCode;
    import com.zuifuli.common.exception.BusinessException;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.digest.DigestUtils;
    import org.apache.commons.lang3.StringUtils;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.GeneralSecurityException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Random;
    
    @Slf4j
    public class EncryptUtil {
        private static final String ALGORITHM_HMAC_SHA1 = "HmacSHA1";
        private static final String BASE_NUMBER = "0123456789";
        private EncryptUtil() {
    
        }
    
        // md5加密
        public static String md5(String plainText) {
            if (StringUtils.isBlank(plainText)) {
                return null;
            } else {
                return DigestUtils.md5Hex(plainText);
            }
        }
    
        // sha1加密
        public static String sha1(String plainText) {
            if (StringUtils.isBlank(plainText)) {
                return null;
            } else {
                return DigestUtils.sha1Hex(plainText);
            }
        }
    
        // base64
        public static String base64(String input) {
            return Base64.encodeBase64String(input.getBytes());
        }
    
        // HMAC_SHA1加密
        public static String hmacSha1(String plainText, String secretKey) {
            SecretKeySpec secretKeySpec = new SecretKeySpec(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(secretKey), ALGORITHM_HMAC_SHA1);
            Mac mac;
            try {
                mac = Mac.getInstance(ALGORITHM_HMAC_SHA1);
                mac.init(secretKeySpec);
                return Base64.encodeBase64String(mac.doFinal(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(plainText)));
            } catch (GeneralSecurityException e) {
                throw new IllegalArgumentException(e);
            }
        }
    
        // 生成AES秘钥
        public static String generateAESSecretKey() {
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(128, new SecureRandom());
                return Base64.encodeBase64String(kgen.generateKey().getEncoded());
            } catch (NoSuchAlgorithmException e) {
                log.error("AesCypher.genKey NoSuchAlgorithmException", e);
                return null;
            }
        }
    
        // AES加密
        public static String aesEncrypt(String originText, String secret) {
            AesCypher cypher = new AesCypher(secret);
            try {
                return cypher.encrypt(originText);
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.CMN_MY_ERRO,"加密异常");
            }
        }
    
        // AES解密
        public static String aesDecrypt(String encryptedText, String secret) {
            try {
                AesCypher cypher = new AesCypher(secret);
                String result = cypher.decrypt(encryptedText);
                return result;
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.CMN_MY_ERRO, "解密发生异常");
            }
        }
    
        public static String getRandomString(int length) {
            Random random = new Random();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < length; i++) {
                sb.append(BASE_NUMBER.charAt(random.nextInt(BASE_NUMBER.length())));
            }
            return sb.toString();
        }
    
        public static void main(String[] args) throws Exception {
            String plainText = "";
            // aes解密 和 解密
            String aesKey = EncryptUtil.generateAESSecretKey();
            System.out.println("AES秘钥: " + aesKey);
            String aesEncrypted = EncryptUtil.aesEncrypt(plainText, aesKey);
            System.out.println("AES密文: " + aesEncrypted);
            System.out.println("AES明文: " + EncryptUtil.aesDecrypt(aesEncrypted, aesKey));
        }
    
        // 内部aes类
        static class AesCypher {
    
            private static String DEFAULT_SECRET = "hqXj7NwyKYaL_Lc5TlCSzA==";
            private byte[] linebreak;
            private SecretKey key;
            private Cipher cipher;
            private Base64 coder;
    
            public AesCypher(String secret) {
                this.linebreak = new byte[0];
    
                try {
                    this.coder = new Base64(32, this.linebreak, true);
                    byte[] secrets = this.coder.decode(secret);
                    // 转换为AES专用密钥
                    this.key = new SecretKeySpec(secrets, "AES");
                    // 创建密码器,算法/工作模式/补码方式 提供商
                    this.cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE");
                } catch (Exception e) {
                    log.error("AesCypher.genKey NoSuchAlgorithmException", e);
                }
    
            }
    
            public AesCypher() {
                this(DEFAULT_SECRET);
            }
    
            public synchronized String encrypt(String plainText) throws Exception {
                this.cipher.init(Cipher.ENCRYPT_MODE, this.key);
                byte[] cipherText = this.cipher.doFinal(plainText.getBytes());
                return new String(this.coder.encode(cipherText));
            }
    
            public synchronized String decrypt(String codedText) throws Exception {
                byte[] encypted = this.coder.decode(codedText.getBytes());
                this.cipher.init(Cipher.DECRYPT_MODE, this.key);
                byte[] decrypted = this.cipher.doFinal(encypted);
                return new String(decrypted, "UTF-8");
            }
        }
    }
    
    上一页
    加解签规则
    下一页
    接口地址
    Built with