电商收付通系列①,对请求进行签名,拼接Authorization

举报
悟空码字 发表于 2023/05/31 21:06:37 2023/05/31
【摘要】 对接了下微信电商收付通接口,过程也是不容易,踩了几个小坑,所以在此记录下来,希望能帮到有需要的人,限于本人经验,如有错误,欢迎指正。

大家好,我是小悟

1、开头语

对接了下微信电商收付通接口,过程也是不容易,踩了几个小坑,所以在此记录下来,希望能帮到有需要的人,限于本人经验,如有错误,欢迎指正。

2、介绍

关于电商收付通,官方的介绍是微信支付专为电商行业场景打造的支付、结算解决方案。电商平台的平台商户入驻微信支付成为二级商户。 电商收付通支持将多个二级商户的订单进行合单支付(如电商购物车中的多笔订单合并支付),合单支付款项分别进入到二级商户各自的账户(资金为冻结状态,可用于实现二级商户账期);电商平台在满足业务流程条件下(如确认收货等),可将二级商户的冻结状态的资金解冻,并收取平台佣金。

3、业务场景

社会化分销、网红带货如火如荼,加入这个大浪潮的你还在汇总记账然后转账给达人吗?分账功能,拯救濒临崩溃的财务小姐姐,拿去不谢。开通「电商收付通」后,电商平台直接拥有分账功能,可根据与卖家的协议,实现卖家交易款在线抽成。此外,还可将分销方等角色添加为分账接收方,满足多渠道分销、网红达人带货场景下的多方灵活分账。关于如何开通电商收付通、产品介绍、接入流程、接口规则、开发指引请前往微信电商收付通官网地址。

4、签名生成

微信支付API v3要求商户对请求进行签名。微信支付会在收到请求后进行签名的验证。如果签名验证不通过,微信支付API v3将会拒绝处理请求,并返回401 Unauthorized。也就是说请求电商收付通的每个接口都需要在请求头传入Authorization,否则请求不会成功。下面看签名生成的代码

import cn.hutool.http.HttpResponse;
import com.smartMap.media.common.utils.UuidUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.List;
import java.util.Map;

/**
 * @description 签名相关
 */
public class SignUtils {
private static final Logger logger = LoggerFactory.getLogger(SignUtils.class);

    /**
     * 签名生成
     * @param method 请求方法 如POST
     * @return
     */
    public static String authorization(String method,String urlSuffix,String mchId,String serialNo,String body,String mchPrivateKeyPath) {
    try {
        //商户私钥
        String mchPrivateKey = CertificateUtils.getPrivateKey(mchPrivateKeyPath);
        //时间戳
        String timestamp = Long.toString(System.currentTimeMillis()/1000);
        //随机数
        String nonceStr = UuidUtils.randomUUID();

        //拼签名串
        StringBuilder sb = signMessage(method,urlSuffix,timestamp,nonceStr,body);

        logger.info("sign original string:{}",sb.toString());

        //计算签名
        String sign = new String(Base64.encodeBase64(v3signRSA(sb.toString(),mchPrivateKey)));

        logger.info("sign result:{}",sign);

        //拼装http头的Authorization内容
        String authorization ="WECHATPAY2-SHA256-RSA2048 mchid=\""+mchId+"\",nonce_str=\""+nonceStr+"\",signature=\""+sign+"\",timestamp=\""+timestamp+"\",serial_no=\""+serialNo+"\"";

        logger.info("authorization result:{}",authorization);

        return authorization;

    } catch (Exception e) {
        logger.error("authorization Exception result:{}",e);
        e.printStackTrace();
        return null;
    }
}

/**
* Authorization 签名串
* @return
*/
private static StringBuilder signMessage(String method,String urlSuffix,String timestamp,String nonceStr,String body) {
return new StringBuilder()
        .append(method)
        .append("\n")
        .append(urlSuffix)
        .append("\n")
        .append(timestamp)
        .append("\n")
        .append(nonceStr)
        .append("\n")
        .append(body)
        .append("\n");
}

/**
* 私钥签名
* @return
* @throws Exception
*/
public static byte[] v3signRSA(String data, String mchPriKey) throws Exception {
  //签名的类型
  Signature sign = Signature.getInstance("SHA256withRSA");
  //读取商户私钥,该方法传入商户私钥证书的内容即可
  byte[] keyBytes = Base64.decodeBase64(mchPriKey);
  PKCS8EncodedKeySpec keySpec =new PKCS8EncodedKeySpec(keyBytes);
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PrivateKey priKey = keyFactory.generatePrivate(keySpec);
  sign.initSign(priKey);
  sign.update(data.getBytes(StandardCharsets.UTF_8));
  return sign.sign();
}
}

针对这个CertificateUtils.getPrivateKey方法说明一下,这个方式是用代码获取商户API证书私钥。也可以下载好商户API证书,然后打开apiclient_key.pem文件,复制出来,代码如下。

5、结果

签名原串:
GET
/v3/certificates
1554208460
593BEC0C930BF1AFEB40B4A08C8FB242
签名sign值:Aabu2HuhQh8+4f8lyBIlg7HcXRTweVqy86RS34jVLnKiekDeWDy1YFwmqnLShvFwRidw9F/cgKCU4zpkXV/NilZSrHlFtHhDw4vInIj8GJmg/USCa6b+rqBe2rnLrF9iORyU04dbt3MGyybRahkr0LqFuS+bqn9IgNjFPRgaqS68krlwTuuay2LJtTyfTrqpfbqmFCDw1Ge1wfGor81H6nCIAaoHzFHC/N3EOqgYypARu5nZVOAxcMkP1jSScLvZQaCdv4cgJ+0xcmE9SHgsGGQHjVbWl81LY4QlbxloLw5RoHFTdaPOYtINttReBY4bgY00NSJJBbHQmd2hLHm8iQ==
authorization值:WECHATPAY2-SHA256-RSA2048 mchid="1900009191",nonce_str="593BEC0C930BF1AFEB40B4A08C8FB242",signature="uOVRnA4qG/MNnYzdQxJanN+zU+lTgIcnU9BxGw5dKjK+VdEUz2FeIoC+D5sB/LN+nGzX3hfZg6r5wT1pl2ZobmIc6p0ldN7J6yDgUzbX8Uk3sD4a4eZVPTBvqNDoUqcYMlZ9uuDdCvNv4TM3c1WzsXUrExwVkI1XO5jCNbgDJ25nkT/c1gIFvqoogl7MdSFGc4W4xZsqCItnqbypR3RuGIlR9h9vlRsy7zJR9PBI83X8alLDIfR1ukt1P7tMnmogZ0cuDY8cZsd8ZlCgLadmvej58SLsIkVxFJ8XyUgx9FmutKSYTmYtWBZ0+tNvfGmbXU7cob8H/4nLBiCwIUFluw==",timestamp="1554208460",serial_no="1DDE55AD98ED71D6EDD4A4A16996DE7B47773A8C"


您的一键三连,是我更新的最大动力,谢谢

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。