百摩网
当前位置: 首页 生活百科

微信支付接入方法(微信支付接入)

时间:2023-07-12 作者: 小编 阅读量: 1 栏目名: 生活百科

微信的接入文档当时没看明白,不知道两者的作用是什么。商户api证书,用作签名微信支付APIv3要求商户对请求进行签名。同样的,微信支付会在回调的HTTP头部中包括回调报文的签名。商户必须验证回调的签名,以确保回调是由微信支付发送。

商户平台产品中心配置开发配置
  • 开通JSApi支付、Native支付
  • JSAPI支付授权目录(前端项目域名)
  • Native支付回调链接
appid账号配置

这一步,完成商户与微信公众号关联

账户中心配置
  • 申请api证书
  • 设置apiV3秘钥
微信公众号配置微信支付配置

商户平台关联完公众号,在公众号平台,微信支付页面,需要点击确认,完成关联操作。

微信支付关键数据清单

名称

说明

appid

公众账号ID

mch_no

商户号

mch_api_cert

商户api证书

mch_api_private_key

商户api私钥

mch_api_cert_serial_no

商户api证书序号

wx_platform_cert

微信支付平台证书

wx_platform_cert_serial_no

微信支付平台证书序号

wx_platform_private_key

微信支付平台私钥

api_v3_key

APIv3密钥

微信平台证书获取

postman调用https://api.mch.weixin.qq.com/v3/Certificates?,获取证书

解密证书密文

package com.insuresmart.claim.postback;import java.io.IOException;import java.security.GeneralSecurityException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.util.Base64;import javax.crypto.Cipher;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.GCMParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AesUtil {static final int KEY_LENGTH_BYTE = 32;static final int TAG_LENGTH_BIT = 128;private final byte[] aesKey;public AesUtil(byte[] key) {if (key.length != KEY_LENGTH_BYTE) {throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");}//密钥为apiv3密钥this.aesKey = key;}public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)throws GeneralSecurityException, IOException {try {Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");SecretKeySpec key = new SecretKeySpec(aesKey, "AES");GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);cipher.init(Cipher.DECRYPT_MODE, key, spec);cipher.updateAAD(associatedData);return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new IllegalStateException(e);} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {throw new IllegalArgumentException(e);}}}

商户api证书VS微信平台证书

微信支付需要用到两种证书,商户api证书和微信平台证书,当时做接入的时候,懵逼。。。。微信的接入文档当时没看明白,不知道两者的作用是什么。

后面看了这个文档https://pay.weixin.qq.com/wiki/doc/apiv3/Wechatpay/wechatpay4_0.shtml,整明白了。

商户api证书,用作签名

微信支付API v3 要求商户对请求进行签名。微信支付会在收到请求后进行签名的验证。如果签名验证不通过,微信支付API v3将会拒绝处理请求,并返回401 Unauthorized

商户api证书中包含了签名所需要的私钥和商户证书,如何签名,参考 签名生成,或者使用微信提供的sdk wechatpay-apache-httpclient

微信平台证书,验签

微信平台证书,对微信应答签名的验签。

如果验证商户的请求签名正确,微信支付会在应答的HTTP头部中包括应答签名。我们建议商户验证应答签名。

同样的,微信支付会在回调的HTTP头部中包括回调报文的签名。商户必须 验证回调的签名,以确保回调是由微信支付发送。


apiv3-key 用作解密微信支付签名工具类

import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;import org.springframework.util.Base64Utils;import java.io.ByteArrayInputStream;import java.nio.charset.StandardCharsets;import java.security.*;/** * @author:shixianqing * @Date:2021/8/17 17:36 * @Description: **/public class SignUtils {/*** @param signStr 签名字符串* @param privateKeyStr 商户证书私钥*/public static String createSign(String signStr, String privateKeyStr) throws InvalidKeyException,NoSuchAlgorithmException,SignatureException {PrivateKey privateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKeyStr.getBytes(StandardCharsets.UTF_8)));Signature sign = Signature.getInstance("SHA256withRSA");sign.initSign(privateKey);sign.update(signStr.getBytes(StandardCharsets.UTF_8));return Base64Utils.encodeToString(sign.sign());}}

微信支付验签

public class WechatVerifyServiceImpl implements wechatVerifyService {/*** 验签* @param wxPlatformCert 微信支付平台证书* @param request* @param requestBody 请求报文体* @return*/@Overridepublic boolean verify(String wxPlatformCert, HttpServletRequest request, String requestBody) {String timestamp = request.getHeader("Wechatpay-Timestamp");String nonce = request.getHeader("Wechatpay-Nonce");String serial = request.getHeader("Wechatpay-Serial");String signature = request.getHeader("Wechatpay-Signature");log.info("支付通知,验签开始,timestamp:{},nonce:{},serial:{},signature:{}",timestamp,nonce,serial,signature);// 验签处理器Verifier verifier = WechatVerifierUtils.getVerifier(wxPlatformCert);String body = requestBody;String beforeSign = String.format("%s\n%s\n%s\n",timestamp,nonce,body);return verifier.verify(serial,beforeSign.getBytes(StandardCharsets.UTF_8),signature);}}public class WechatVerifierUtils {public static Verifier getVerifier(String wxPlatformCert){X509Certificate wechatPayPlatformCertificate = PemUtil.loadCertificate(new ByteArrayInputStream(wxPlatformCert.getBytes(StandardCharsets.UTF_8)));ArrayList<X509Certificate> wxPlatformCertList = new ArrayList<>();wxPlatformCertList.add(wechatPayPlatformCertificate);Verifier certificatesVerifier = new CertificatesVerifier(wxPlatformCertList);return certificatesVerifier;}}

微信支付解密

package com.insuresmart.base.pay.common.util;import com.google.common.base.CharMatcher;import com.google.common.io.BaseEncoding;import com.insuresmart.base.common.utils.StringUtils;import javax.crypto.Cipher;import javax.crypto.Mac;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.GCMParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.io.IOException;import java.security.GeneralSecurityException;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.util.Base64;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;public class AesUtils {static final int KEY_LENGTH_BYTE = 32;static final int TAG_LENGTH_BIT = 128;private final byte[] aesKey;public AesUtils(byte[] key) {if (key.length != KEY_LENGTH_BYTE) {throw new IllegalArgumentException("无效的ApiV3Key,长度必须为32个字节");}// apiv3私钥this.aesKey = key;}public static byte[] decryptToByte(byte[] nonce, byte[] cipherData, byte[] key)throws GeneralSecurityException {return decryptToByte(null, nonce, cipherData, key);}public static byte[] decryptToByte(byte[] associatedData, byte[] nonce, byte[] cipherData, byte[] key)throws GeneralSecurityException {try {Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, spec);if (associatedData != null) {cipher.updateAAD(associatedData);}return cipher.doFinal(cipherData);} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new IllegalStateException(e);} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {throw new IllegalArgumentException(e);}}public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)throws GeneralSecurityException, IOException {try {Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");SecretKeySpec key = new SecretKeySpec(aesKey, "AES");GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);cipher.init(Cipher.DECRYPT_MODE, key, spec);cipher.updateAAD(associatedData);return new String(cipher.doFinal(BaseEncoding.base64().decode(CharMatcher.whitespace().removeFrom(ciphertext))), "utf-8");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new IllegalStateException(e);} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {throw new IllegalArgumentException(e);}}public static String decryptToString(String associatedData, String nonce, String ciphertext,String apiV3Key)throws GeneralSecurityException, IOException {try {Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(), "AES");GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes());cipher.init(Cipher.DECRYPT_MODE, key, spec);associatedData = StringUtils.isNotBlank(associatedData) ? associatedData : "";cipher.updateAAD(associatedData.getBytes());return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), "utf-8");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {throw new IllegalStateException(e);} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {throw new IllegalArgumentException(e);}}public static String HMACSHA256(String data, String key) {try {Mac sha256_HMAC = Mac.getInstance("HmacSHA256");SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");sha256_HMAC.init(secret_key);byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));StringBuilder sb = new StringBuilder();for (byte item : array) {sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}return sb.toString().toUpperCase();} catch (Exception e) {e.printStackTrace();return null;}}}

附录

微信接入规范地址

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_1.shtml

微信支付接口文档地址

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_1.shtml

,
    推荐阅读
  • 单位缴纳的社保费怎么入账(企业缴纳社会保险费的正确账务处理)

    我们一起去了解并探讨一下这个问题吧!单位缴纳的社保费怎么入账企业缴纳社会保险费,这两种账务处理错误最常见!

  • 十五年车多久审一次?

    15年以上的车每半年需要验车1次。小型轿车审车时间规定。6年以内免检,满2年需免费领取免检标志,即二证和一,6年以上1年1审。汽车年检就是指每个已经取得正式号牌和行驶证的车辆都必须要的一项检测,相当于每年一次按《机动车运行安全技术条件》给车辆做体检。年检时需要注意的事情如下:1、年检时会检测车尾气检测是否合格,也就是氧传感器和三元催化器。

  • 女人情感心理学(女性情感上升三角)

    再看到那些让我牙疼的解答,于是,我被牙疼折磨的不知道如何是好,决定把这个“女性情感上升三角”公布于众。在得到女性的高度IOI时要用肢体近挪去回应!这时候男生才想起来给女生买了一份礼物,作为表白礼物,但是“女生情感上升三角”已经下滑到底部,女生不会再见他了!第四次的错过,让他们永远的擦肩而过在男女互动中要把握好“女性情感上升三角”的规则,很多时候不是没有吸引,而是你没有把握好吸引的时机。

  • 绿宝树怎么修剪 绿宝树怎么修剪好看

    绿宝树怎么修剪吧!1、时间一般生长最繁茂的时期在夏天,夏天是绿宝树的生长期,这个时候生长速度很快,我们需要用剪刀将一些较长的枝条减掉,把一些较密的枝条减掉,这样能让它长得更快,看起来也更整齐,这样修剪也对于冬天的生长有好处,能够矫正某些枝条的长势,等到冬天修剪的时候就没那么麻烦了,长得也会更健康。

  • 孕妇吃饱了难受怎么办(怀孕期间吃的太饱了怎么办)

    而且还可能让食物出现回流的情况。而适当的走动便能够促进肠胃蠕动,使食物消化的速度加快。在孕妇吃撑了不舒服时,虽然可以通过散步来消食,但是却不能进行剧烈运动。这时候可以喝几口温开水,就能够有效的刺激肠胃,让胃部分泌更多的消化液,从而加速食物的消化以及吸收。如果按摩肚子的位置或者是方法不正确,就很容易引起胎儿胎位不正和宫缩。此外,孕妇也不能够吃山楂或者是喝山楂水来消食,这是有可能引起流产的。

  • 娃娃菜怎么泡制方法(泡制娃娃菜的方法)

    娃娃菜怎么泡制方法娃娃菜一开四份,反复洗净,清水浸泡30分钟.烧开水,烫10秒,捞起晾干。晾干的娃娃菜放入干净的锅或大盘中,用盐拌匀轻轻搓揉几分钟,放一边约15分钟。挤干被盐腌过的娃娃菜水份,用凉水冲净盐份,再挤干备用。取大口瓶,洗净烘干,底部铺上之前准备的一半的柠檬片,再铺一层拌好的辣椒碎,接着铺一层娃娃菜;然后铺一层姜蒜蓉和柠檬片,再铺一层娃娃菜,然后铺一层糖,接着铺娃娃菜,然后铺一层辣椒碎。

  • 校园情景剧剧本6人十分钟(校园情景剧短小剧本)

    接下来我们就一起去研究一下吧!校园情景剧剧本6人十分钟校园情景剧短视频小剧本,公众号“剧本创作工厂”可以免费下载。顿时物理老师脸色一阵黑拍摄建议人物神态、动作演绎自然,结束尾可加搞笑音效

  • 防水卷材不送检行吗(消费者将所购远大洪雨防水卷材送检后发现)

    对于违法行为及抽查发现的不合格产品生产者、销售者,北京市市场监督管理局已全部移交经营主体所在地市场监管部门依法进行处理。下一步,市场监管总局将持续加大产品质量国家监督抽查力度,对消费投诉集中、共性质量问题突出的区域开展专项治理,严防严控不合格产品流入市场,严肃查处质量违法行为。中国房产质量周在此特别提醒广大消费者,购买产品要谨慎,遇到不合格产品,一定要保留证据,并及时向相关部门反映情况。

  • mr先生英文怎么读(mr先生怎么造句)

    mr先生怎么造句Mr读音:英[mɪstə(r)]、美[mɪstər] 含义:n.先生(Mister的缩写)用法:名词有先生,阁下(Mister的缩写),先生,用在男性姓或全名前作为有礼貌的称呼,先生,用于政府官员头衔。

  • 瓜蒌仁的功效与作用禁忌(瓜蒌仁的功效与作用有哪些呢)

    部分患者症状明显好转,咽下通畅,可进干硬食物。瓜蒌霜的这些反应较轻。瓜蒌片可使个别病人月经过多。还有人报道用瓜蒌注射液静滴413例,有7例发生副反应,表现症状有胸闷。血压下降、下腹疼痛、畏寒、低热、头晕等。但所有肌注者无不良反应。每服12克,用水220毫升,加生姜5片,煎服,不拘时。