java 接入 微信支付 网页扫码支付(native方式)V3

1.导入依赖

        <!-- 微信支付 -->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.9</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.0.6</version>
        </dependency>
        <!--生成二维码-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.3</version>
        </dependency>

接入前的准备
参考文档:接入前准备-Native支付 | 微信支付商户平台文档中心 (qq.com)icon-default.png?t=N7T8https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_1.shtml#top

2.支付所需参数配置

wx:
# 商户号
  mch-id: 
#  appId
  appId: 
# 商户证书序列号
  mc-serial-no: 
#  API V3密钥
  api-v3-key: 
#  回调地址
  notify-domain: 
#  商户证书地址
  keyPath: ../ttlive-server/Common/src/main/java/com/common/cert/apiclient_key.pem
  certPath: ../ttlive-server/Common/src/main/java/com/common/cert/apiclient_cert.pem
  certP12Path: ../ttlive-server/Common/src/main/java/com/common/cert/apiclient_cert.p12

微信配置类

@Configuration
@Data
@Component
public class WxPayConfig {
    private static volatile Config config;
    /**
     * 商户号 
     */
    public static String merchantId = "1657.....5";
  
      // 商户API私钥路径 本地路径
//    public static String privateKeyPath="../ttliveserver/Common/src/main/java/com/common/cert/apiclient_key.pem";

    // 服务器上部署测试路径
    public static String privateKeyPath = "../root/cert/apiclient_key.pem";
    /**
     * 商户证书序列号
     */
    public static String merchantSerialNumber = "6E225996B0BE..........B043B6B726";
    /**
     * 商户APIV3密钥
     */
    public static String apiV3Key = "31cc22a............bba9a411";;


    //SDK 提供的定时更新平台证书
    public static synchronized Config getConfig(WxPayConfig wxPayConfig) {
        if (config == null) {
            config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKeyFromPath(privateKeyPath)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();
        }
        return config;
    }

    public static Config getConfig() {
        return config;
    }

    public static void setConfig(Config config) {
        WxPayConfig.config = config;
    }
}

这里我们设置的是 API v3密钥 提前下载并配置商户证书文件,将文件移入项目中


3.生成微信支付二维码
 

@Autowired
private WxPayConfig wxPayConfig;

Config config = WxPayConfig.getConfig(wxPayConfig);
NativePayService service = new NativePayService.Builder().config(config).build();           
// request.setXxx(val)设置所需参数,具体参数可见Request定义
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal(商品价格);
request.setAmount(amount);
request.setAppid("APPID");
request.setMchid("商户号");
request.setDescription("商品名称");
request.setNotifyUrl("回调地址,需绑定域名,否则需要内网穿透工具");
request.setOutTradeNo("你所生成的订单号");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
// 微信二维码失效时间 4 分钟
Date date = new Date(new Date().getTime() + 4 * 60 * 1000);
String expire = format.format(date);
request.setTimeExpire(expire);
// 调用下单方法,得到应答
PrepayResponse response = service.prepay(request);
// 生成二维码链接,扔给前端,或者自己写二维码代码
String codeUrl = response.getCodeUrl();

4.微信回调
 

    public String paymentSuccessNotify(String body, HttpServletRequest request, HttpServletResponse response) {
        //时间戳
        String timestamp = request.getHeader("wechatPay-Timestamp");
        //随机字符串
        String nonce = request.getHeader("wechatPay-Nonce");
        //签名
        String signature = request.getHeader("wechatPay-Signature");
        //签名类型
        String sigType = request.getHeader("wechatPay-Signature-Type");
        //证书序列号
        String wechatPayCertificateSerialNumber = request.getHeader("wechatPay-Serial");
//        String ciphertext = request.getHeader("ciphertext");
//        String associateData = request.getHeader("associated_data");
//        //解密方法
//        AesUtil aesUtil = new AesUtil("31cc22a17ada73b81ad85832bba9a411".getBytes(StandardCharsets.UTF_8));
//        String info = null;
//        try {
//            info = aesUtil.decryptToString(associateData.getBytes(StandardCharsets.UTF_8), nonce.getBytes(StandardCharsets.UTF_8), ciphertext);
//        } catch (GeneralSecurityException e) {
//            throw new RuntimeException(e);
//        } catch (IOException e) {
//            throw new RuntimeException("解密失败");
//        }
//        System.out.println(info);
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(wechatPayCertificateSerialNumber)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                .signType(sigType)
                .body(body)
                .build();
        //获取微信证书,没有的话重新构造一个

        Config config = WxPayConfig.getConfig(wxPayConfig);
        NotificationParser parser = new NotificationParser((NotificationConfig) config);
        // 以支付通知回调为例,验签、解密并转换成 Transaction
        Transaction transaction = parser.parse(requestParam, Transaction.class);
        Transaction.TradeStateEnum trade_state = transaction.getTradeState();
//        根据transaction的结果进行回调操作
        String message = null;
        if (trade_state == Transaction.TradeStateEnum.SUCCESS){
            message = "200";
        }else {
            message ="400";
        }

//      下面的是业务处理,到这一步,获取到transaction 方法即可 
        String outTradeNo = transaction.getOutTradeNo();
        String transactionId = transaction.getTransactionId();
        String poll = outTradeNo+":"+transactionId+"-"+message;
//        String poll = JSONObject.toJSONString(transaction);
        this.payDao.addOrderNoInfoToQueue(poll);
//      将微信返回的订单号参数信息传到Dao层,进行校验
        if (trade_state == Transaction.TradeStateEnum.SUCCESS) {
            response.setStatus(200);
            JSONObject json = new JSONObject();
            json.put("code", "SUCCESS");
            return json.toString();
        } else {
            response.setStatus(400);
            JSONObject json = new JSONObject();
            json.put("code", "FAIL");
            json.put("message", "验签失败");
            return json.toString();
        }
    }

### 一、微信支付集成与接入指南 在数字化时代,微信支付已成为商家不可或缺的支付方式之一。以下是关于如何集成微信支付并完成接入的详细指南。 #### 1. 前期准备 在开始集成微信支付之前,需要完成以下准备工作[^1]: - **注册商户号**:进入微信支付官网,提交相关资料并通过审核后获取商户号。 - **签署协议**:与微信支付签署相关合作协议。 - **下载SDK**:根据开发语言选择对应的微信支付SDK,例如Java SDK。 - **配置证书**:下载商户平台提供的API证书,并妥善保管。 #### 2. 开发环境配置 为了顺利对接微信支付接口,需确保开发环境已正确配置。以下是关键步骤: - **引入依赖**:在项目中添加微信支付SDK的依赖项。例如,在Maven项目中添加以下依赖: ```xml <dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-java</artifactId> <version>0.4.0</version> </dependency> ``` - **配置参数**:在代码中配置商户号、API密钥、证书路径等信息。示例代码如下: ```java import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder; public class WeChatPayConfig { public static void main(String[] args) throws Exception { // 商户号 String mchId = "your_merchant_id"; // API密钥 String apiV3Key = "your_api_v3_key"; // 证书路径 String certPath = "path_to_your_cert.p12"; WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() .withMerchant(mchId, apiV3Key, new File(certPath)); } } ``` #### 3. 调用支付接口 调用微信支付接口时,需根据实际业务场景选择合适的支付方式。以下是常见的支付方式及其调用方法: - **Native支付**:适用于PC网站或移动应用中的码支付场景[^4]。 - **H5支付**:适用于移动端浏览器内的支付场景。 - **JSAPI支付**:适用于微信内嵌浏览器的支付场景。 以Native支付为例,调用接口的代码示例如下: ```java import com.wechat.pay.contrib.apache.httpclient.WechatPayRequest; import com.wechat.pay.contrib.apache.httpclient.WechatPayResponse; public class NativePayment { public static void main(String[] args) throws Exception { // 构建请求对象 WechatPayRequest request = new WechatPayRequest(); request.set("body", "商品描述"); request.set("out_trade_no", "订单号"); request.set("total_fee", "金额(分)"); request.set("spbill_create_ip", "客户端IP"); request.set("notify_url", "回调地址"); request.set("trade_type", "NATIVE"); // 发送请求并处理响应 WechatPayResponse response = client.post("/v3/pay/transactions/native", request); System.out.println(response.toString()); } } ``` #### 4. 回调处理 支付完成后,微信支付服务器会向商户系统发送回调通知。为确保交易状态准确,需正确处理回调通知。示例代码如下: ```java import com.wechat.pay.contrib.apache.httpclientNotifyParser; public class NotifyHandler { public static void main(String[] args) throws Exception { // 解析回调数据 NotifyParser parser = new NotifyParser(); Map<String, String> notifyData = parser.parse(request.getInputStream()); // 验证签名 if (parser.verify(notifyData)) { // 处理业务逻辑 String transactionId = notifyData.get("transaction_id"); String outTradeNo = notifyData.get("out_trade_no"); String totalFee = notifyData.get("total_fee"); // 返回成功响应 response.getWriter().write("<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>"); } else { // 签名验证失败 response.getWriter().write("<xml><return_code><![CDATA[FAIL]]></return_code></xml>"); } } } ``` #### 5. 测试与上线 在正式上线前,建议使用微信支付提供的API调试工具进行功能测试[^2]。确保所有接口调用正常且回调逻辑无误。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值