0


SpringBoot整合weixin-java-pay实现微信小程序支付

使用weixin-java-pay实现微信小程序支付

准备工作

依赖引入

<dependency><groupId>com.github.binarywang</groupId><artifactId>weinxin-java-pay</artifactId><version>对应的版本号</version></dependency>

证书申请和下载

官方文档: 直达
在这里插入图片描述

撸起袖子使劲干

配置类

  1. 参数配置类
/**
 * @author: Eden4J
 * @Description: 微信支付商户信息配置类
 */@Data@Component@RefreshScope@ConfigurationProperties(prefix ="wechat.pay")publicclassWeChatPayProperties{/**
     * 微信小程序或者微信公众号appId
     */privateString appid;/**
     * 商户号
     */privateString mchId;/**
     * 商户密钥
     */privateString mchKey;/**
     * 商户证书序列号
     */privateString serialNo;/**
     * apiV3Key
     */privateString apiV3Key;/**
     * 证书
     */privateString keyPath;/**
     * 商户私钥文件
     */privateString privateKeyPath;/**
     * apiclient_cert.pem证书文件
     */privateString privateCertPath;/**
     * 交易类型
     * JSAPI--公众号支付
     * NATIVE--原生扫码支付
     * APP--app支付
     */privateString tradeType;/**
     * 支付结果异步通知回调地址
     */privateString notifyUrl;}
  1. 微信支付配置类
/**
 * @author: Eden4J
 * @Description: 微信支付配置类
 */@Component@ConditionalOnClass(WxPayService.class)@RequiredArgsConstructorpublicclassWeChatPayConfig{privatefinalWeChatPayProperties properties;@Bean@ConditionalOnMissingBeanpublicWxPayConfigpayConfig(){WxPayConfig payConfig =newWxPayConfig();
        payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppid()));
        payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
        payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey()));
        payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getSerialNo()));
        payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiV3Key()));
        payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath()));
        payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
        payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));
        payConfig.setTradeType(StringUtils.trimToNull(this.properties.getTradeType()));return payConfig;}@BeanpublicWxPayServicewxPayService(WxPayConfig payConfig){WxPayService wxPayService =newWxPayServiceImpl();
        wxPayService.setConfig(payConfig);return wxPayService;}}
  1. 自定义的微信预支付返回信息类
@DatapublicclassWxPayInfoVOimplementsSerializable{privateString appId;privateString timeStamp;privateString nonceStr;privateString packageValue;privateString signType;privateString paySign;}
工具类
/**
 * @author: Eden4J
 * @Description: 微信支付相关工具类
 */publicclassWxPayUtil{publicstaticStringsign(String signStr,PrivateKey privateKey){Sign sign =SecureUtil.sign(SignAlgorithm.SHA256withRSA, privateKey.getEncoded(),null);returnBase64.encode(sign.sign(signStr.getBytes()));}publicstaticStringbuildMessage(String appId,String timeStamp,String nonceStr,String body){return appId +"\n"+ timeStamp +"\n"+ nonceStr +"\n"+ body +"\n";}publicstaticAutoUpdateCertificatesVerifiergetVerifier(WxPayConfig wxPayConfig)throwsIOException{PrivateKey privateKey =PemUtils.loadPrivateKey(newClassPathResource("apiclient_key.pem").getInputStream());AutoUpdateCertificatesVerifier verifier =newAutoUpdateCertificatesVerifier(newWxPayCredentials(wxPayConfig.getMchId(),newPrivateKeySigner(wxPayConfig.getCertSerialNo(), privateKey)), wxPayConfig.getApiV3Key().getBytes("utf-8"));return verifier;}/**
     * 验证签名
     *
     * @param certificate
     * @param message
     * @param signature
     * @return
     */publicstaticbooleanverify(AutoUpdateCertificatesVerifier certificate,byte[] message,String signature){try{Signature sign =Signature.getInstance("SHA256withRSA");
            sign.initVerify(certificate.getValidCertificate());
            sign.update(message);return sign.verify(java.util.Base64.getDecoder().decode(signature));}catch(NoSuchAlgorithmException e){thrownewRuntimeException("当前Java环境不支持SHA256withRSA", e);}catch(SignatureException e){thrownewRuntimeException("签名验证过程发生了错误", e);}catch(InvalidKeyException e){thrownewRuntimeException("无效的证书", e);}}}
接口层和服务处理层代码

重点注意:微信支付回调结果通知不要使用JSONObject去做接收

  1. 接口层
@RestController@RequestMapping("/请求路径")@RequiredArgsConstructorpublicclassAppCustomerUserRechargeOrderController{privatefinalIAppCustomerUserRechargeOrderService rechargeOrderService;@PostMapping("/preOrder")publicResult<WxPayInfoVO>preOrder(@RequestParam("goodId")String goodId){returnResult.success(rechargeOrderService.preOrder(goodId));}// 支付回调@PostMapping("/back")publicMap<String,String>back(@RequestBodyMap body,HttpServletRequest request){return rechargeOrderService.formalOrder(body, request);}}
  1. 处理层
@OverridepublicWxPayInfoVOpreRecharge(String goodId){try{//看看是否有其他的业务逻辑// 调用微信的统一下单接口获取预支付单返回前端 createOrderV3(TradeTypeEnum tradeType, WxPayUnifiedOrderV3Request request)WxPayUnifiedOrderV3Request payRequest =newWxPayUnifiedOrderV3Request();
            payRequest.setOutTradeNo(rechargeNo);//系统充值订单号
            payRequest.setDescription(goodsPackage.getPackageName());//订单失效时间SimpleDateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
            payRequest.setTimeExpire(dateFormat.format(DateUtil.offset(newDate(),DateField.HOUR_OF_DAY,1)));WxPayUnifiedOrderV3Request.Payer payer =newWxPayUnifiedOrderV3Request.Payer();
            payer.setOpenid(userAccount.getOpenId());
            payRequest.setPayer(payer);WxPayUnifiedOrderV3Request.Amount amount =newWxPayUnifiedOrderV3Request.Amount();
            amount.setTotal(rechargeOrder.getTotalAmount().multiply(BigDecimal.valueOf(100)).intValue());
            amount.setCurrency("CNY");
            payRequest.setAmount(amount);
            payRequest.setNotifyUrl(weChatPayProperties.getNotifyUrl());WxPayUnifiedOrderV3Result.JsapiResult jsapiResult = wxPayService.createOrderV3(TradeTypeEnum.JSAPI, payRequest);String encode =WxPayUtil.sign(WxPayUtil.buildMessage(weChatPayProperties.getAppid(), jsapiResult.getTimeStamp(), jsapiResult.getNonceStr(), jsapiResult.getPackageValue()),PemUtils.loadPrivateKey(newClassPathResource("apiclient_key.pem").getInputStream()));WxPayInfoVO payInfoVO =PojoUtil.exchangePojo(jsapiResult,WxPayInfoVO.class);
            payInfoVO.setPaySign(encode);return payInfoVO;}catch(WxPayException e){
            e.printStackTrace();thrownewBizException("微信支付失败", e);}catch(IOException e){
            e.printStackTrace();thrownewBizException("微信支付失败", e);}}@OverridepublicMap<String,String>createFormalOrder(Map body,HttpServletRequest request){try{Map<String,String> resultMap =newHashMap<>();
            resultMap.put("code","FAIL");ObjectMapper objectMapper =newObjectMapper();try{//官方文档中有说明切记不要改变原始报文主体,如果使用JSONObject接收的话,不能使用JSON转换出来的字符串,会出现验签错误的情况,请注意String data = objectMapper.writeValueAsString(body);SignatureHeader header =newSignatureHeader();
                header.setTimeStamp(request.getHeader("Wechatpay-Timestamp"));
                header.setNonce(request.getHeader("Wechatpay-Nonce"));
                header.setSignature(request.getHeader("Wechatpay-Signature"));
                header.setSerial(request.getHeader("Wechatpay-Serial"));WxPayNotifyV3Result notifyV3Result =wxPayService.parseOrderNotifyV3Result(data, header);WxPayNotifyV3Result.DecryptNotifyResult decryptNotifyResult = notifyV3Result.getResult();//解密后的数据if("SUCCESS".equalsIgnoreCase(decryptNotifyResult.getTradeState())){
                        resultMap.put("code","SUCCESS");}}catch(Exception e){
                e.printStackTrace();}return resultMap;}catch(Exception e){
            e.printStackTrace();thrownewBizException("微信支付成功回调失败", e);}}

结束!


本文转载自: https://blog.csdn.net/qq_15090197/article/details/136938894
版权归原作者 Eden要努力搞钱 所有, 如有侵权,请联系我们删除。

“SpringBoot整合weixin-java-pay实现微信小程序支付”的评论:

还没有评论