最新小程序微信支付V3使用SDK

小程序微信支付V3使用SDK

1.先引入依赖,引入微信支付的SDK依赖,Redisson分布式锁

        <!-- 微信支付 -->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.12</version>
        </dependency>
        <!-- redission -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.15.6</version>
        </dependency>

2.Redisson的配置信息

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {

    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private int redisPort;

    @Value("${spring.redis.password}")
    private String redisPassword;

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + redisHost + ":" + redisPort)
                .setPassword(null); //Redis设置的无密码所以必须为null,有密码的话 引入密码
        return Redisson.create(config);
    }
}

3.所需要的各种配置信息都放在 配置文件中 application.yml

wechatpay:
  appId: 微信公众号或者小程序等的appId
  merchantId: 微信支付商户号
  merchantSerialNumber: 商戶API ID
  apiV3key: 商户APIv3密钥
  certPemPath: 商户证书路径(此处绝对路径,为下载商户证书中的apiclient_key.pem) D:\Code\enterprise-management-master\ruoyi-enterprise\src\main\resources\apiclient_key.pem
#  certPemPath:  /home/ruoyi/serve/pem/apiclient_key.pem
  payNotifyUrl: https://ip:8080/weChatPay/callback #支付成功回调地址,必须为https请求
  appSecret: APP 秘钥

4.参数初始化到内存中

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * Description: 微信支付配置类
 *
 * @author shangzewei
 * @date 2023/11/29 10:27
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "wechatpay")
public class WechatPayProperties {
    /**
     * 微信公众号或者小程序等的appId
     */
    private String appId;
    /**
     * 微信支付商户号
     */
    private String merchantId;
    /**
     * 商户证书路径
     */
    private String certPemPath;
    /**
     * 商户API私钥路径
     */
    private String privateKeyPath;
    /**
     * 商户APIv3密钥
     */
    private String apiV3key;
    /**
     * 支付回调通知地址
     */
    private String payNotifyUrl;

    /**
     * 商戶API ID
     */
    private String merchantSerialNumber;

    /**
     * APP 秘钥
     */
    private String appSecret;

}

6初始化商户对象,服务对象

参考官方API

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * Description: 微信支付相关自动配置
 *
 * @author shangzewei
 * @date 2023/12/1 10:50
 */
@Slf4j
@Configuration
public class WechatPayAutoConfiguration {

    @Autowired
    private WechatPayProperties properties;


    /**
     * 自动更新证书,初始化商户
     * RSAAutoCertificateConfig 会利用 AutoCertificateService 自动下载微信支付平台证书。 
     * AutoCertificateService 将启动一个后台线程,定期(目前为每60分钟)更新证书,以实现证书过期时的平滑切换。
     *
     * 在每次构建 RSAAutoCertificateConfig 时,SDK 首先会使用传入的商户参数下载一次微信支付平台证书。 
     * 如果下载成功,SDK 会将商户参数注册或更新至 AutoCertificateService。若下载失败,将会抛出异常。
     *
     * 为了提高性能,建议将配置类作为全局变量。 复用 RSAAutoCertificateConfig 可以减少不必要的证书下载,避免资源浪费。 
     * 只有在配置发生变更时,才需要重新构造 RSAAutoCertificateConfig
     *
     * @return RSAAutoCertificateConfig
     */
    @Bean
    public Config config() throws IOException {
        log.info("==========加载商戶對象");
//        String privateKeyPath = WechatPayAutoConfiguration.class.getClassLoader().getResource(properties.getCertPemPath()).getFile();
        // 初始化商户配置
        RSAAutoCertificateConfig config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(properties.getMerchantId())
                        // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
//                        .privateKeyFromPath(privateKeyPath)
                        .privateKeyFromPath(properties.getCertPemPath())
                        .merchantSerialNumber(properties.getMerchantSerialNumber())
                        .apiV3Key(properties.getApiV3key())
                        .build();
        log.info("==========商戶對象加載完成");
        return config;
    }

    /**
     * 微信支付对象
     * @param config Config
     * @return JsapiServiceExtension
     */
    @Bean
    public JsapiServiceExtension jsapiServiceExtension(Config config){
        log.info("==========加载微信支付对象");
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        log.info("==========微信支付对象加載完成");
        return service;
    }

    /**
     * 微信回调对象
     *
     * @param config Config
     * @return NotificationParser
     */
    @Bean
    public NotificationParser notificationParser(Config config) {
        log.info("==========加载微信回调解析对象");
        NotificationParser parser = new NotificationParser((NotificationConfig) config);
        return parser;
    }


}

7.Controller

import com.ruoyi.enterprise.config.WechatPayProperties;
import com.ruoyi.enterprise.entity.CreateOrderPayRequest;
import com.ruoyi.enterprise.service.WechatPayExternalService;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/weChatPay")
public class WeChatPayController {

    @Autowired
    private WechatPayProperties properties;
    @Autowired
    WechatPayExternalService wechatPayExternalService;
    @PostMapping("/createorder")
    public PrepayWithRequestPaymentResponse createOrder(@RequestBody CreateOrderPayRequest createOrderPayRequest) throws Exception {

        //生成订单号  openid+时间戳
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String timestamp = dateFormat.format(new Date());
        createOrderPayRequest.setOutTradeNo(createOrderPayRequest.getOpenId().substring(0,10) + timestamp);
        createOrderPayRequest.setPayContent("小程序下單");
        return wechatPayExternalService.prepayWithRequestPayment(createOrderPayRequest);
    }


    /**
     * 回调接口
     *
     * @param request
     * @return
     * @throws
     */
    @RequestMapping(value = "/callback", method = {RequestMethod.POST, RequestMethod.GET})
    public Map<String, String> payCallback(HttpServletRequest request, HttpServletResponse response) {
        log.info("------收到支付通知------");
        Map<String, String> result = new HashMap<>();
        try {
            wechatPayExternalService.payCallBack(request);
            result.put("code", "SUCCESS");
            result.put("message", "成功");
            return result;
        } catch (Exception e) {
            log.error("支付处理失败,req:{}", request, e);
//            alarm();
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            result.put("code", "FAIL");
            result.put("message", e.getMessage());
            return result;
        }
    }



}

7.Service

import com.ruoyi.enterprise.entity.CreateOrderPayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.ruoyi.enterprise.entity.WechatPayCallBackRequest;

import javax.servlet.http.HttpServletRequest;

/**
 * Description: 微信支付对接 V3(基于JSAPI 支付的扩展类实现)
 *
 * @author shangzewei
 * @date 2023/11/30 11:38
 */
public interface WechatPayExternalService {

    /**
     * 提交预支付请求付款
     * @param createOrderPay 订单请求体
     * @return PrepayWithRequestPaymentResponse 预付费与请求付款响应
     */
    PrepayWithRequestPaymentResponse prepayWithRequestPayment(CreateOrderPayRequest createOrderPay);

    /**
     * 查询状态
     *
     * @param outTradeNo 商户支付no
     * @return 状态信息
     */
    Transaction queryStatus(String outTradeNo);

    /**
     * 取消订单
     *
     * @param outTradeNo
     */
    void closeOrder(String outTradeNo);

    /**
     * 解析签名
     * 官网地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml
     *
     * @param wechatPayCallBackRequest
     * @param clazz
     * @param <T>
     * @return
     */
    <T> T analysisSign(WechatPayCallBackRequest wechatPayCallBackRequest, Class<T> clazz);

    /**
     * 处理回调
     * 官网地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml
     *
     */
    public void payCallBack(HttpServletRequest request) throws Exception;
}

8.ServiceImpl

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.enterprise.Enum.OrderPayStatusEnum;
import com.ruoyi.enterprise.config.WechatPayProperties;
import com.ruoyi.enterprise.domain.EmEnterprise;
import com.ruoyi.enterprise.entity.CreateOrderPayRequest;
import com.ruoyi.enterprise.entity.WechatPayCallBackRequest;
import com.ruoyi.enterprise.service.IEmEnterpriseService;
import com.ruoyi.enterprise.service.WechatPayExternalService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.cipher.PrivacyEncryptor;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.redisson.api.RedissonClient;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

/**
 * Description: 微信支付对接(基于JSAPI 支付的扩展类实现)
 *
 * @author shangzewei
 * @date 2023/12/1 11:49
 */
@Slf4j
@Service
public class WechatPayExternalServiceImpl implements WechatPayExternalService {
    @Autowired
    IEmEnterpriseService emEnterpriseService;

    @Resource
    private Config config;

    @Resource
    private WechatPayProperties properties;

    @Resource
    private JsapiServiceExtension jsapiServiceExtension;

    @Resource
    private NotificationParser notificationParser;



    @Resource
    private RedissonClient redissonClient;
    /**
     * 分布式锁
     */
    private final String LOCK_KEY = "WECHAT_PAY_LOCK:";


    /*
    预支付订单
     */
    @Override
    public PrepayWithRequestPaymentResponse prepayWithRequestPayment(CreateOrderPayRequest createOrderPay) {
        EmEnterprise emEnterprise = emEnterpriseService.selectEmEnterpriseByCode(createOrderPay.getSocietalCode());
        log.info("prepayWithRequestPayment start");
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        BigDecimal payMoney = createOrderPay.getPayMoney();
        BigDecimal amountTotal = payMoney.multiply(new BigDecimal("100").setScale(0, RoundingMode.DOWN));
        amount.setTotal(amountTotal.intValue());
        request.setAmount(amount);
        Payer payer = new Payer();
        payer.setOpenid(createOrderPay.getOpenId());
        request.setPayer(payer);
        request.setTimeExpire(getExpiredTimeStr());
        request.setAppid(properties.getAppId());
        request.setMchid(properties.getMerchantId());

        request.setDescription(createOrderPay.getPayContent());
        //回调地址
        request.setNotifyUrl(properties.getPayNotifyUrl());
        //添加附加数据,代表社会代码
        request.setAttach(createOrderPay.getSocietalCode());
        //这里生成流水号,后续用这个流水号与微信交互,查询订单状态
        request.setOutTradeNo(createOrderPay.getOutTradeNo());
        PrepayWithRequestPaymentResponse result;
        try {
            result = jsapiServiceExtension.prepayWithRequestPayment(request);
        } catch (HttpException e) {
            log.error("微信下单发送HTTP请求失败,错误信息:{}", e.getHttpRequest());
            throw new RuntimeException("微信下单发送HTTP请求失败", e);
        } catch (ServiceException e) {
            // 服务返回状态小于200或大于等于300,例如500
            log.error("微信下单服务状态错误,错误信息:{}", e.getErrorMessage());
            throw new RuntimeException("微信下单服务状态错误", e);
        } catch (MalformedMessageException e) {
            // 服务返回成功,返回体类型不合法,或者解析返回体失败
            log.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
            throw new RuntimeException("服务返回成功,返回体类型不合法,或者解析返回体失败", e);
        }
        log.info("prepayWithRequestPayment end");
        return result;
    }

    @Override
    public Transaction queryStatus(String outTradeNo) {
        QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
        request.setMchid(properties.getMerchantId());
        request.setOutTradeNo(outTradeNo);
        try {
            return jsapiServiceExtension.queryOrderByOutTradeNo(request);
        } catch (ServiceException e) {
            log.error("订单查询失败,返回码:{},返回信息:{}", e.getErrorCode(), e.getErrorMessage());
            throw new RuntimeException("订单查询失败", e);
        }
    }

    /*
    关闭订单
     */
    @Override
    public void closeOrder(String outTradeNo) {
        log.info("closeOrder");
        CloseOrderRequest closeRequest = new CloseOrderRequest();
        closeRequest.setMchid(properties.getMerchantId());
        closeRequest.setOutTradeNo(outTradeNo);
        try {
            //方法没有返回值,意味着成功时API返回204 No Content
            jsapiServiceExtension.closeOrder(closeRequest);
        } catch (ServiceException e) {
            log.error("订单关闭失败,返回码:{},返回信息:{}", e.getErrorCode(), e.getErrorMessage());
            throw new RuntimeException("订单关闭失败", e);
        }
    }

    @Override
    public <T> T analysisSign(WechatPayCallBackRequest wechatPayCallBackRequest, Class<T> clazz) {
        log.info("payCallBack");
        PrivacyEncryptor privacyEncryptor = config.createEncryptor();
        String weChatPayCertificateSerialNumber = privacyEncryptor.getWechatpaySerial();
        if (!wechatPayCallBackRequest.getSerial().equals(weChatPayCertificateSerialNumber)) {
            log.error("证书不一致");
            throw new RuntimeException("证书不一致");
        }
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPayCallBackRequest.getSerial())
                .nonce(wechatPayCallBackRequest.getNonce())
                .signType(wechatPayCallBackRequest.getSignatureType())
                .signature(wechatPayCallBackRequest.getSignature())
                .timestamp(wechatPayCallBackRequest.getTimestamp())
                .body(wechatPayCallBackRequest.getBody())
                .build();
        // 以支付通知回调为例,验签、解密并转换成 Transaction
        return notificationParser.parse(requestParam, clazz);
    }


    /**
     * 获取失效时间 5分钟
     */
    private String getExpiredTimeStr() {
        //失效时间,10分钟
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime expiredTime = now.plusMinutes(5);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        return formatter.format(expiredTime);
    }



    @Override
    public void payCallBack(HttpServletRequest request) throws Exception {
        BufferedReader reader = request.getReader();
        String line;
        StringBuilder sb = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        WechatPayCallBackRequest callBackRequest = new WechatPayCallBackRequest();
        callBackRequest.setBody(sb.toString());
        callBackRequest.setNonce(request.getHeader("Wechatpay-Nonce"));
        callBackRequest.setSerial(request.getHeader("Wechatpay-Serial"));
        callBackRequest.setSignature(request.getHeader("Wechatpay-Signature"));
        callBackRequest.setSignatureType(request.getHeader("Wechatpay-Signature-Type"));
        callBackRequest.setTimestamp(request.getHeader("Wechatpay-Timestamp"));
        log.info("验签参数{}", JSONObject.toJSONString(callBackRequest));

        Transaction transaction = analysisSign(callBackRequest, Transaction.class);
        log.info("验签成功!-支付回调结果:{}", transaction.toString());

        String lockKey = LOCK_KEY + transaction.getOutTradeNo();
        RLock lock = redissonClient.getLock(lockKey);
        try {
            boolean isLock = lock.tryLock();
            if (!isLock) {
                throw new RuntimeException("请勿重复操作");
            }
            log.info("开始用户支付后业务处理");
            // 以支付通知回调为例,验签、解密并转换成 Transaction
            processTransaction(transaction);
            log.info("用户支付后业务处理成功");
        } catch (Exception e) {
            log.error("用户支付后业务处理错误, e{}", e);
            throw e;
        } finally {
            // 释放锁
            lock.unlock();
        }
    }

    /**
     * 处理回调业务(需要保证事务操作哦)
     * @param transaction Transaction
     */
    private void processTransaction(Transaction transaction) {
        // 修改订单前,主动请求微信查询订单是否支付成功,防止恶意post
        transaction = queryStatus(transaction.getOutTradeNo());
        if (Transaction.TradeStateEnum.SUCCESS != transaction.getTradeState()) {
            log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", transaction.getOutTradeNo(), transaction.getTransactionId());
            throw new RuntimeException("订单支付未成功");
        }
        // 修改支付信息   代码修改数据库的支付状态
//        PayLogPO payLog = payLogDao.getByOutTradeNo(transaction.getOutTradeNo());
        EmEnterprise emEnterprise = emEnterpriseService.selectEmEnterpriseByCode(transaction.getAttach());
        if (Objects.isNull(emEnterprise)){
            log.error("用户支付后业务处理错误, 统一社会信用代码不存在" + transaction.getAttach());
        }
        if (OrderPayStatusEnum.PAY_SUCCESS.getCode().equals(emEnterprise.getCode())) {
            // 若订单状态已为支付成功则不处理
            return;
        }
        //微信支付系统生成的订单号
//        payLog.setTransactionId(transaction.getTransactionId());
        //支付完成时间
//        if (Objects.nonNull(transaction.getSuccessTime())) {
//            payLog.setPayTime(LocalDateTime.parse(transaction.getSuccessTime(), DateTimeFormatter.ISO_OFFSET_DATE_TIME));
//        }
        emEnterprise.setStatus(Integer.valueOf(OrderPayStatusEnum.PAY_SUCCESS.getCode()));

//        payLogDao.store(payLog);
        // 修改订单信息
//        OrderPO order = orderDao.getById(payLog.getOrderId());
//        order.setStatus(OrderStatusEnum.DELIVER_GOODS.getCode());
//        orderDao.store(order);
        emEnterpriseService.updateEmEnterprise(emEnterprise);
        // 其他业务操作
    }
}

9.CreateOrderPayRequest

/**
 * Description: 提交预支付请求付款请求体
 *
 * @author shangzewei
 * @date 2023/12/1 17:06
 */
@Data
public class CreateOrderPayRequest {
    /**
     * 主键id
     */
    private Long id;

    /**
     * 商户支付no 和微信交互 查询订单使用(outTradeNo)
     */
    private String outTradeNo;

    /**
     * 用户openid
     */
    private String openId;

    /**
     * 支付金额
     */
    private BigDecimal payMoney;

    /**
     * 支付内容
     */
    private String payContent;

    /**
     * 社会代码
     */
    private String societalCode;

}
import lombok.Data;

@Data
public class WechatPayCallBackRequest {

        private String body;

        /*
            Wechatpay-Nonce
         */

        private String Nonce;
        /*
            Wechatpay-Serial
        */

        private String Serial;
        /*
            Wechatpay-Signature
        */

        private String Signature;
        /*
            Wechatpay-Signature-Type
        */

        private String SignatureType;
        /*
            Wechatpay-Timestamp
        */

        private String Timestamp;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 `com.github.wechatpay-apiv3` 库处理微信 H5 支付的 Java 代码示例: ```java import com.github.wechatpay.apiv3.WxPayApiV3; import com.github.wechatpay.apiv3.WxPayApiV3Config; import com.github.wechatpay.apiv3.model.notify.WxPayOrderNotifyResult; import com.github.wechatpay.apiv3.model.notify.WxPayOrderNotifyResult.NotifyResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class WeChatH5NotifyHandler { private static final String WECHAT_API_CERT_SERIAL_NUMBER = "YOUR_WECHAT_API_CERT_SERIAL_NUMBER"; private static final String WECHAT_API_CERTIFICATE_PATH = "path/to/your/wechat/api/certificate.pem"; public void handleNotify(HttpServletRequest request, HttpServletResponse response) throws IOException { try { // 创建微信支付 API 配置 WxPayApiV3Config config = new WxPayApiV3Config.Builder() .appId("your_app_id") .merchantId("your_merchant_id") .privateKeySerialNumber(WECHAT_API_CERT_SERIAL_NUMBER) .privateKeyPath(WECHAT_API_CERTIFICATE_PATH) .build(); // 创建微信支付 API 实例 WxPayApiV3 wxPayApiV3 = new WxPayApiV3(config); // 解析异步通知数据 WxPayOrderNotifyResult notifyResult = wxPayApiV3.parseOrderNotifyResult(request); // 验证签名 if (wxPayApiV3.verifySignature(notifyResult)) { // 签名验证成功 // 处理支付成功的逻辑 // ... // 返回成功响应给微信服务器 response.setStatus(HttpServletResponse.SC_OK); response.getWriter().write("SUCCESS"); } else { // 签名验证失败,返回失败响应给微信服务器 response.setStatus(HttpServletResponse.SC_BAD_REQUEST); response.getWriter().write("FAIL"); } } catch (Exception e) { e.printStackTrace(); // 返回失败响应给微信服务器 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.getWriter().write("FAIL"); } } } ``` 在上述代码中,我们创建了一个名为 `WeChatH5NotifyHandler` 的类,其中的 `handleNotify` 方法用于处理微信 H5 支付的异步通知。该方法接收 `HttpServletRequest` 和 `HttpServletResponse` 对象作为参数,从请求中获取异步通知的数据,并进行相应的处理逻辑。 在 `handleNotify` 方法中,我们首先创建了一个 `WxPayApiV3Config` 对象,用于配置微信支付 API 的相关参数。其中,我们需要提供应用 ID(`appId`)、商户号(`merchantId`)、微信支付 API 证书的序列号(`privateKeySerialNumber`)以及证书的路径(`privateKeyPath`)。您需要将这些参数替换为您自己的值。 然后,我们使用 `WxPayApiV3` 实例来解析异步通知数据,并验证签名。如果签名验证成功,则表示支付成功,可以进行相应的处理逻辑,并返回成功响应给微信服务器。如果签名验证失败,则返回失败响应给微信服务器。 请注意,以上示例代码仅供参考,具体的实现可能因应用的需求而有所不同。您需要根据实际情况进行修改和完善。另外,在真实的项目中,请确保您已正确配置和保护微信支付 API 证书的私钥。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值