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

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

1、开头语

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

2、介绍

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

image.png

3、业务场景

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

image.png

4、签名生成

文档地址:

https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-sheng-cheng

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

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
     * @param urlSuffix 请求地址后缀 如/v3/certificates
     * @param mchId 电商平台商户号
     * @param serialNo 电商平台商户API证书序列号
     * @param body 请求请求报文主体,如果没有,就传空字符串
     * @param mchPrivateKeyPath 电商平台商户API私钥
     * @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 签名串
* @param method
* @param urlSuffix
* @param timestamp
* @param nonceStr
* @param body
* @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");
}

/**
* 私钥签名
* @param data 需要加密的数据
* @param mchPriKey
* @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文件,复制出来,代码如下。

image.png

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"

image.png

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

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

上一篇:微信小程序模板消息接口下线了,不用慌,调用统一服务消息接口来实现相同功能

相关文章
|
4月前
|
API
支付系统38-----支付宝支付---统一收单线下交易查询 第一步下单------》发起支付请求,登录,确认支付,查单接口开发,swagger接口全部呈现,
支付系统38-----支付宝支付---统一收单线下交易查询 第一步下单------》发起支付请求,登录,确认支付,查单接口开发,swagger接口全部呈现,
|
4月前
|
API
支付系统----微信支付24--APlv3介绍,首先我们要引入支付参数,包含商户号,APPID、API秘钥,数字证书,用代码加载到应用程序当中,之后加载商户私钥,商户需要用私钥进行验签,微信平台接收商
支付系统----微信支付24--APlv3介绍,首先我们要引入支付参数,包含商户号,APPID、API秘钥,数字证书,用代码加载到应用程序当中,之后加载商户私钥,商户需要用私钥进行验签,微信平台接收商
|
4月前
|
数据安全/隐私保护
支付系统18--------支付宝支付,支付调用流程,用时序表进行展示,三大用户用户,商户系统,支付宝,支付宝怎么知道跳转我们商户平台的那个页面,发送支付请求的时候,就携带着功的页面的参数,完整交易流
支付系统18--------支付宝支付,支付调用流程,用时序表进行展示,三大用户用户,商户系统,支付宝,支付宝怎么知道跳转我们商户平台的那个页面,发送支付请求的时候,就携带着功的页面的参数,完整交易流
|
6月前
|
JSON 算法 API
金润数科JR-CLT-003-通过VIN码查询车型信息接口文档
接口名称 通过VIN码查询车型信息 接口编号 JR-CLT-003 接口描述 通过VIN码查询车型信息 接口地址 /dmp/api 请求方式 POST 加密方式 RSA2
|
6月前
|
JSON 算法 API
金润数科JR-CLT-004-通过VIN码查询车轴接口文档
接口名称 通过VIN码查询车轴 接口编号 JR-CLT-004 接口描述 通过VIN码查询车轴 接口地址 /dmp/api 请求方式 POST 加密方式 RSA2
|
Python 开发工具
第三方支付黑马-CodePay 码支付使用(二)
自古以来有关钱的事情都会特别复杂, 无论是人还是物! 在很多项目中我们都会用到支付功能, 市面上目前存在的银联支付, 支付宝支付, 微 信支付等等第三方支付都会遇到比较复杂的流程, 不是合格的商家公司是没法使用的! 而码支付CodePay打破了这个常规, 虽然作为第三方支付平台, 但是这个平台只提供支付结果订单的结算, 并不对接现金流! 采用的是个人/商家自己的收款码现金是直接到账的形式!
第三方支付黑马-CodePay 码支付使用(二)
|
存储 安全 小程序
电商数据API接口如何防止叁数篡改和重放攻击?
目前所有的独立站,APP系统架构都是采用前后端分离的系统架构,那么就不可能避免的需要服务对外提供API,那么如何保证对外的API的安全呢?
|
缓存 安全 API
网络平台挑选实名制认证API接口的注意事项
网络平台实名制认证是对用户真实性身份进行的一种查验审核,有助于建立完善可靠的互联网信用基础。对于网络平台运营者来说,身份实名认证除了符合工信部监管政策外,也可以帮助平台方筛选掉部分无效客户,规避一定的风险,净化网络环境。
347 0
网络平台挑选实名制认证API接口的注意事项
|
JSON 算法 安全
金润·核验通-运营商三要素验证接口文档
接口介绍:支持三大运营商所有号码核验,通过比对姓名、身份证号、手机号的一致性 更新时间:实时 接口类型:API接口 数据优势:直连官方数据,合法合规、权威、精确 数据安全:官方数据,只核验三要素之间的一致性,保护个人信息安全 计费方式:核验计费,详情请咨询
金润·核验通-运营商三要素验证接口文档
|
JSON 文字识别 算法
金润·核验通-个人身份验证接口文档
与身份证OCR技术完美融合,实时快速核实身份信息真实性【实名认证】【身份认证】【身份实名认证】【身份证】【身份证二要素】【身份证二要素核验】【身份证二要素实名认证】【身份证认证】【身份证识别】【身份证实名核验】【身份证实名认证】【身份证实名认证查询】【身份证实名认证接口】【身份证实名认证校验】【身份证实名认证验证】【身份证实名校验】【身份证验证】【身份证一致性实名认证】【实名】【实名鉴权验证】【实名认证】【实名认证api】【实名认证核查】【实名认证接口】【实名验证】【身份证核验】【实名认证身份证】【身份证实名验证】【身份证实名认证api】【实名认证api接口】【身份证实名认证api接口】
金润·核验通-个人身份验证接口文档