2024年前端最全微信小程序JSAPI支付 v3 版本 详解 附带源码_微信支付v3后端源码,2024年最新阿里p8面试官

最后

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

        AutoUpdateCertificatesVerifier autoUpdateCertificatesVerifier) {
    return WechatPayHttpClientBuilder.create()
            .withMerchant(mchid, mchSerialNo, merchantPrivateKey)
            .withValidator(new WechatPay2Validator(autoUpdateCertificatesVerifier)).build();
}

/**
 * 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
 */
@Bean
public AutoUpdateCertificatesVerifier autoUpdateCertificatesVerifier(
        PrivateKey merchantPrivateKey,
        @Value("${mchid}") String mchid,
        @Value("${mchSerialNo}") String mchSerialNo,
        @Value("${v3Key}") String v3Key) throws UnsupportedEncodingException {
    return new AutoUpdateCertificatesVerifier(
            new WechatPay2Credentials(mchid, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),
            v3Key.getBytes("utf-8"));
}

/**
 * 加载商户私钥(privateKey:私钥字符串)
 */
@Bean
public PrivateKey merchantPrivateKey(@Value("${privateKey}") String privateKey)
        throws UnsupportedEncodingException {
    return PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
}


static final int KEY_LENGTH_BYTE = 32;
static final int TAG_LENGTH_BIT = 128;

@Value(“${v3Key}”)
private String weChatV3Key;

public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
throws GeneralSecurityException, IOException {
try {
Cipher cipher = Cipher.getInstance(“AES/GCM/NoPadding”);

  SecretKeySpec key = new SecretKeySpec(weChatV3Key.getBytes(StandardCharsets.UTF_8), "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);
}

}


#### 请求下单



/**
* 请求统一下单逻辑处理:
*/
private WxPayOrderResult unifiedOrder(WxPayOrderRequest wxPayOrderRequest) throws IOException {
HttpPost httpPost = new HttpPost(PAYUNIFIEDORDERURL);
// 请求body参数
StringEntity entity = new StringEntity(new Gson().toJson(wxPayOrderRequest), “UTF-8”);
entity.setContentType(“application/json;charset=UTF-8”);
httpPost.setEntity(entity);
httpPost.setHeader(“Accept”, “application/json;charset=UTF-8”);
HttpResponse response = httpClient.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
String body = response.getEntity() == null ? null : EntityUtils.toString(response.getEntity());
if (code != 200) {
log.error(“请求微信统一下单异常: code={}, body={}”, code, body);
throw new RuntimeException(“请求微信统一下单异常”);
}
return new Gson().fromJson(body,
WxPayOrderResult.class);
}


##### 获取下单的预支付id生成签名



@Override
public String payTransactionsJsapi(WxPayOrderRequest wxPayOrderRequest) throws IOException {
    wxPayOrderRequest.setAppid(appid);
    wxPayOrderRequest.setMchid(mchid);
    WxPayOrderResult wxPayUnifiedOrderResult = this.unifiedOrder(wxPayOrderRequest);
    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
    WxPayMpOrderResult wxPayMpOrderResult = new WxPayMpOrderResult().setAppId(
                    wxPayOrderRequest.getAppid())
            .setNonceStr(wxPayOrderRequest.getOut_trade_no())
            .setPackageValue("prepay_id=" + wxPayUnifiedOrderResult.getPrepay_id())
            .setSignType("RSA")
            .setTimeStamp(timestamp);
    /**
     * jsapi 拉起支付文档 : https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml
     * 一定要注意签名方式哪里
     */
    String paySign = sign(getSignStr(wxPayOrderRequest.getAppid(), timestamp,
                    wxPayOrderRequest.getOut_trade_no(), "prepay_id=" + wxPayUnifiedOrderResult.getPrepay_id())
            , privateKey);
    wxPayMpOrderResult.setPaySign(paySign);
    /**
     * 这里是为了做兼容 代码不允许有 package 的处理,所以才做转换,如果可以的话,让前端去做处理也行
     */
    Gson gson = new Gson();
    Map<String, Object> map = gson.fromJson(gson.toJson(wxPayMpOrderResult), Map.class);
    map.put("package", map.get("packageValue"));
    map.remove("packageValue");
    return gson.toJson(map);
}

##### 签名方法



private String getSignStr(String appId, String timeStamp, String nonceStr, String packageValue) {
    return String.format("%s\n%s\n%s\n%s\n", appId, timeStamp, nonceStr, packageValue);
}

public static String sign(String string, PrivateKey privateKey) {
    try {
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(privateKey);
        sign.update(string.getBytes());
        return Base64.getEncoder().encodeToString(sign.sign());
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
    } catch (SignatureException e) {
        throw new RuntimeException("签名计算失败", e);
    } catch (InvalidKeyException e) {
        throw new RuntimeException("无效的私钥", e);
    }
}

这里可以看看官方文档对签名的介绍:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/50451a0c001c41a39521924f8ca44887.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWlyYWl0b3dhQA==,size_20,color_FFFFFF,t_70,g_se,x_16)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/d579fdf9f4ff47b9b33c463e4c2c69c4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATWlyYWl0b3dhQA==,size_20,color_FFFFFF,t_70,g_se,x_16)


#### 回调处理:



@PostMapping("weChat")
public String acceptNotify(@RequestBody WeChatNotify notify) throws Exception {
    log.info("接收到JSAPI支付通知 {}", notify.toString());
    Gson gson = new Gson();
    String decrypt = weChatAesUtil.decryptToString(notify.getResource()
                    .getAssociated_data()
                    .getBytes(StandardCharsets.UTF_8),
            notify.getResource().getNonce().getBytes(StandardCharsets.UTF_8),

最后

今天的文章可谓是积蓄了我这几年来的应聘和面试经历总结出来的经验,干货满满呀!如果你能够一直坚持看到这儿,那么首先我还是十分佩服你的毅力的。不过光是看完而不去付出行动,或者直接进入你的收藏夹里吃灰,那么我写这篇文章就没多大意义了。所以看完之后,还是多多行动起来吧!

可以非常负责地说,如果你能够坚持把我上面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

面列举的内容都一个不拉地看完并且全部消化为自己的知识的话,那么你就至少已经达到了中级开发工程师以上的水平,进入大厂技术这块是基本没有什么问题的了。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值