《抖音支付》担保支付-预收款

官方提供的签名和验签方法,替换上自己的支付系统秘钥 SALT


import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

public class DouYinSign {
    /**
     * 担保支付请求不参与签名参数
     * app_id 小程序appID
     * thirdparty_id 代小程序进行该笔交易调用的第三方平台服务商id
     * sign 签名
     * other_settle_params 其他分账方参数
     *
     * Guaranteed payment requests do not participate in signature parameters
     * app_id Applets appID
     * thirdparty_id The id of the third-party platform service provider that calls the transaction on behalf of the Applets
     * sign sign
     * other_settle_params Other settle params
     */
    public final static List<String> REQUEST_NOT_NEED_SIGN_PARAMS = Arrays.asList("app_id", "thirdparty_id", "sign", "other_settle_params");

    /**
     * 支付密钥值,需要替换为自己的密钥(完成进件后,开发者可在字节开放平台-【某小程序】-【功能】-【支付】-【担保交易设置】中查看支付系统秘钥 SALT)
     *
     * Payment key value, you need to replace it with your own key
     */
    private static final String SALT = "支付系统秘钥 SALT";

    /**
     * RequestSign 担保支付请求签名算法
     * @param paramsMap {@code Map<String, Object>} 所有的请求参数
     * @return:签名字符串
     *
     * RequestSign Guaranteed payment request signature algorithm
     * @param paramsMap {@code Map<String, Object>} all request parameters
     * @return: Signature string
     */
    public static String requestSign(Map<String, Object> paramsMap) {
        List<String> paramsArr = new ArrayList<>();
        for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
            String key = entry.getKey();
            if (REQUEST_NOT_NEED_SIGN_PARAMS.contains(key)) {
                continue;
            }
            String value = entry.getValue().toString();

            value = value.trim();
            if (value.startsWith("\"") && value.endsWith("\"") && value.length() > 1) {
                value = value.substring(1, value.length() - 1);
            }
            value = value.trim();
            if (value.equals("") || value.equals("null")) {
                continue;
            }
            paramsArr.add(value);
        }
        paramsArr.add(SALT);
        Collections.sort(paramsArr);
        StringBuilder signStr = new StringBuilder();
        String sep = "";
        for (String s : paramsArr) {
            signStr.append(sep).append(s);
            sep = "&";
        }
        return md5FromStr(signStr.toString());
    }

    /**
     * CallbackSign 担保支付回调签名算法
     * @param params {@code List<String>} 所有字段(验证时注意不包含 sign 签名本身,不包含空字段与 type 常量字段)内容与平台上配置的 token
     * @return:签名字符串
     *
     * CallbackSign Guaranteed payment callback signature algorithm
     * @param params {@code List<String>} The content of all fields (note that the sign signature itself is not included during verification, and does not include empty fields and type constant fields) content and the token configured on the platform
     * @return: signature string
     */
    public static String callbackSign(List<String> params) {
        try {
            String concat = params.stream().sorted().collect(Collectors.joining(""));
            byte[] arrayByte = concat.getBytes(StandardCharsets.UTF_8);
            MessageDigest mDigest = MessageDigest.getInstance("SHA1");
            byte[] digestByte = mDigest.digest(arrayByte);

            StringBuffer signBuilder = new StringBuffer();
            for (byte b : digestByte) {
                signBuilder.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
            }
            return signBuilder.toString();
        } catch (Exception exp) {
            return "";
        }
    }

    /**
     * md5FromStr md5算法对该字符串计算摘要
     * @param inStr {@code String} 需要签名的字符串
     * @return:签名字符串
     *
     * md5FromStr The md5 algorithm computes a digest of the string
     * @param inStr {@code String} String to be signed
     * @return: signature string
     */
    private static String md5FromStr(String inStr) {
        MessageDigest md5;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return "";
        }

        byte[] byteArray = inStr.getBytes(StandardCharsets.UTF_8);
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuilder hexValue = new StringBuilder();
        for (byte md5Byte : md5Bytes) {
            int val = ((int) md5Byte) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
}

public  String preOrder(String appId, String notify_url, Integer total_amount, String orderNo, String subject, String detail){

        // 示例参数
        Map<String, Object> params = new HashMap<>();
        params.put("app_id",app_id);
        params.put("out_order_no", orderNo); //商户订单号
        params.put("total_amount", total_amount); //金额。分
        params.put("notify_url", notify_url);  //回调接口
        params.put("subject", subject); //主题
        params.put("body", detail); //商品详情
        params.put("valid_time", 5*60); //过期时间
        String sign = DouYinSign.requestSign(params); //签名
        params.put("sign",sign);
		//发起post请求
        String postJson = doPostJson("https://developer.toutiao.com/api/apps/ecpay/v1/create_order", JSONObject.toJSONString(params), "UTF-8");

        if (StringUtils.isNoneBlank(postJson)) {
            JSONObject jsonObject = JSONObject.parseObject(postJson);
            if ("success".equals(jsonObject.get("err_tips")))
            {
                return jsonObject.get("data").toString();
            } else {
                throw new GlobalException("抖音支付生成失败" + postJson);
            }
        }
        return null;
    }

public String dyNotify(HttpServletRequest request, HttpServletResponse response) {

    try {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Origin", "*");
        InputStream in = request.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        in.close();
        String responseJson = new String(out.toByteArray(),"utf-8");
        logger.info("responseJson:{}",responseJson);
        JSONObject jsonObject = JSONObject.parseObject(responseJson);
        JSONObject msgJson = jsonObject.getJSONObject("msg");
        String resultCode = jsonObject.getString("type");
        if ("payment".equalsIgnoreCase(resultCode)) {
            List<String> sortedString = new ArrayList<>();
            //token
            sortedString.add("token");
            //时间戳
            sortedString.add(jsonObject.getString("timestamp"));
            //随机数
            sortedString.add(jsonObject.getString("nonce"));
            //msg
            sortedString.add(jsonObject.getString("msg"));
            Collections.sort(sortedString);
            StringBuilder sb = new StringBuilder();
            sortedString.forEach(sb::append);
            String msg_signature = jsonObject.getString("msg_signature");
            String sign = DouYinSign.callbackSign(sortedString);
            logger.info("支付回调接口密钥签名:{}",sign);
            if(!sign.equals(msg_signature)) {//判断签名,此处验签有问题
                JSONObject resultJson = new JSONObject();
                resultJson.put("err_no",8);
                resultJson.put("err_tips","error");
            }
          String orderNo =  msgJson.getString("cp_orderno"); //商户订单号
          String order_id =  msgJson.getString("order_id");  //抖音订单id
          Integer orderAmount =  msgJson.getInteger("total_amount");  //支付金额

			//todo 处理支付成功后的订单业务
			
            JSONObject resultJson = new JSONObject();
            resultJson.put("err_no",0);
            resultJson.put("err_tips","success");

            //todo 同步订单变成已支付 

            return resultJson.toString();
        } else {
            //订单编号
            String outTradeNo = msgJson.getString("cp_orderno");
            logger.error("订单" + outTradeNo + "支付失败");
            JSONObject resultJson = new JSONObject();
            resultJson.put("err_no",0);
            resultJson.put("err_tips","error");
            return resultJson.toString();
        }
    } catch (Exception e) {
        e.printStackTrace();
        JSONObject resultJson = new JSONObject();
        resultJson.put("err_no",8);
        resultJson.put("err_tips","error");
        return resultJson.toString();
    }
}

后续还需要同步订单,担保支付的订单需要同步到抖音商场订单里面

验签参考文章:https://blog.csdn.net/m0_59963277/article/details/123048704

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
支付结算业务是现代银行业务中最为重要的一项,它可以为客户提供非常便捷的支付手段,同时也能为银行带来大量的利润。在这篇论文中,我们将对支付结算业务的核算进行详细的论述,从而帮助读者更好地了解这项业务,以及如何进行相关的会计核算。 一、支付结算业务的定义 支付结算业务是指银行作为支付结算中心,向客户提供的各种支付结算服务。这些服务包括但不限于:银行卡支付、网银支付、手机支付、第三方支付等。这些支付结算服务通常涉及到银行账户之间的资金转移,因此需要进行相关的会计核算。 二、支付结算业务的分类 根据支付结算业务的不同形式和功能,可以将其分为以下几类: 1. 银行卡支付:指客户使用银行卡进行支付的业务。这种业务通常涉及到信用卡、借记卡等不同种类的银行卡,客户可以通过刷卡、插卡、扫码等方式完成支付。 2. 网银支付:指客户通过银行网站或手机银行等渠道进行支付的业务。这种业务通常需要客户输入账号密码等信息,以完成支付。 3. 手机支付:指客户使用手机进行支付的业务。这种业务通常涉及到手机应用程序、二维码等技术,客户可以通过扫码、输入密码等方式完成支付。 4. 第三方支付:指由第三方支付机构提供的支付服务。这种支付服务通常涉及到银行卡、网银等多种支付渠道,客户可以通过第三方支付机构完成支付。 以上四种支付结算业务都需要进行相关的会计核算,以确保资金的安全、准确、及时地转移。 三、支付结算业务的会计核算 支付结算业务的会计核算主要涉及到以下几个方面: 1. 收入的核算 在支付结算业务中,银行作为支付结算中心向客户提供各种支付服务,因此可以从中获得收入。这些收入通常包括银行手续费、利息收入等。银行手续费是指银行向客户收取的支付服务费用,通常根据支付金额的大小而定,手续费率也有所不同。利息收入是指银行在资金转移过程中所获得的利息收入,通常根据转移时间、利率等因素而定。 2. 成本的核算 在支付结算业务中,银行需要承担一定的成本,这些成本通常包括银行卡发行成本、网络维护成本、人员工资等。这些成本需要在会计核算中进行记录,以便计算出支付结算业务的净收入。 3. 资金流量的核算 支付结算业务涉及到资金的转移,因此需要对资金流量进行核算。银行需要记录客户的存款、支出、转移等资金流量信息,并定期进行核对,以确保资金的安全、准确、及时地转移。 4. 资产负债的核算 支付结算业务对银行的资产负债表也有一定的影响。在资产方面,银行需要记录客户的存款、借款等信息;在负债方面,银行需要记录支付结算业务所产生的应付款项、预收款项等信息。这些信息需要在会计核算中进行记录和调整。 四、支付结算业务的会计处理流程 支付结算业务的会计处理流程通常包括以下几个步骤: 1. 收集和整理相关信息 在进行会计核算之前,银行需要收集和整理相关的支付结算业务信息,包括收入、成本、资金流量、资产负债等信息。 2. 记账处理 根据收集和整理的信息,银行需要进行会计记账处理。具体来说,需要将收入、成本、资金流量等信息记录在相应的会计科目中,并计算出支付结算业务的净收入。 3. 制作财务报表 根据记账处理的结果,银行需要制作相应的财务报表,包括资产负债表、利润表、现金流量表等。这些报表可以帮助银行管理人员了解支付结算业务的财务状况,以便做出相应的经营决策。 4. 审核和检查 在完成会计处理之后,银行需要对相关信息进行审核和检查,以确保信息的准确性和完整性。如果发现了任何问题,银行需要及时进行调整和纠正。 五、结论 支付结算业务是银行业务中最为重要的一项,它不仅可以为客户提供便捷的支付手段,也可以为银行带来大量的利润。在进行相关会计核算时,银行需要注意收入、成本、资金流量、资产负债等方面的处理,以确保会计信息的准确性和完整性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pywanggui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值