springboot整合微信扫码支付(详细)

微信扫码支付

以下主要是针对微信支付V3接口进行的整合,且为Native支付

前期准备工作

1️⃣:获取微信相关数据

#绑定支付的appid
#商户id
#商户支付秘钥wechatKey,这个需要V3的
#证书序列号
#私钥文件(.pem文件)
#下面给出了相应的链接

微信支付商户平台

⚠️:这里千万别用微信服务商去注册,原因见下图

image-20230429154001177

上面的参数都获取到后,就可以进行springboot的整合了

2️⃣:导入maven坐标

<!--微信支付-->
<dependency>
  <groupId>com.github.wechatpay-apiv3</groupId>
  <artifactId>wechatpay-java</artifactId>
  <version>0.2.6</version>
</dependency>
package com.test.test.api.wechat.pay;

import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.nativepay.model.Transaction;
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


/**
 * @author xiaobo
 * @date 2023/3/8
 */
@Controller
@Slf4j
@RequestMapping("/wechat")
public class WechatPayApi extends BaseController {

    private static final String APP_ID = "";

    private static final String MERCHANT_ID = "";

    private static final String WECHAT_KEY = "";

    private static final String MERCHANT_SERIAL_NUMBER = "";

    private static final String NOTIFY_URL = "";


    public static NativePayService service;
    public static Config config = null;
  
    public static final String WECHAT_PAY_SIGNATURE = "Wechatpay-Signature";
  
    public static final String WECHAT_PAY_TIMESTAMP = "Wechatpay-Timestamp";
  
    public static final String WECHAT_PAY_SIGNATURE_TYPE = "Wechatpay-Signature-Type";
  
    public static final String WECHAT_PAY_SERIAL = "Wechatpay-Serial";
  
    public static final String WECHAT_PAY_NONCE = "Wechatpay-Nonce";

    /**
     * Native支付预下单
     */
    @RequestMapping("prepay")
    @ResponseBody
    public RespResult wechatPay(double total_amount) {
        PrepayRequest prepayRequest = new PrepayRequest();
        Amount amount = new Amount();
        // total为分
        amount.setTotal((int) (total_amount * 100));
        prepayRequest.setAmount(amount);
        prepayRequest.setMchid(MERCHANT_ID);
        prepayRequest.setAppid(APP_ID);
        prepayRequest.setNotifyUrl(NOTIFY_URL);
        prepayRequest.setDescription("账户充值");
      	// 这里的订单号要保证唯一,这种方法不推荐(因为并发高的情况下会出现订单号不唯一)
        prepayRequest.setOutTradeNo(new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()) + RandomUtil.randomNumbers(4));
        PrepayResponse prepayResponse = service.prepay(prepayRequest);
        // TODO 数据库处理订单(这里应该相应的生成订单)
        // 返回成功,以及相应的二维码地址(前端需要进行转换为二维码)
        return RespResult.success(prepayResponse.getCodeUrl(), jsonObject);
        }
        return RespResult.fail("获取微信支付码失败!");
    }

    @ResponseBody
    @PostMapping("success")
    public RespResult success(HttpServletRequest request) throws IOException {
        // 读取请求头内容
        String serialNumber = request.getHeader(WECHAT_PAY_SERIAL);
        String nonce = request.getHeader(WECHAT_PAY_NONCE);
        String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
        String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
        String signType = request.getHeader(WECHAT_PAY_SIGNATURE_TYPE);
        log.error(serialNumber, nonce, signature, timestamp);
        // 获取请求体内容
        ServletInputStream servletInputStream = request.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(servletInputStream));
        StringBuffer stringBuffer = new StringBuffer();
        String s;
        while ((s = bufferedReader.readLine()) != null) {
            stringBuffer.append(s);
        }
        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(serialNumber)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                // 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
                .signType(signType)
                .body(stringBuffer.toString())
                .build();

        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser((NotificationConfig) config);

        // 验签并解密报文
        Transaction decryptObject = parser.parse(requestParam, Transaction.class);
        log.error(decryptObject.toString());
        Map params = new HashMap(3);
        Map resultMap = (Map) JSON.parse(stringBuffer.toString());
        // TODO 你的业务逻辑处理
        return RespResult.success("成功!");
        }
        return RespResult.success("失败!");
    }

    @PostConstruct
    public static NativePayService initializeWechatConfiguration() throws FileNotFoundException {
        // 初始化商户配置
        String privateKeyPath = Objects.requireNonNull(KuocaiCdnBootApplication.class.getResource("/apiclient_key.pem")).getPath();

        if (config == null) {
            config =
                    new RSAAutoCertificateConfig.Builder()
                            .merchantId(MERCHANT_ID)
                            // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
                            .privateKeyFromPath(privateKeyPath)
                            .merchantSerialNumber(MERCHANT_SERIAL_NUMBER)
                            .apiV3Key(WECHAT_KEY)
                            .build();
        }
        if (service == null) {
            service = new NativePayService.Builder().config(config).build();
        }
        log.info("初始化微信配置成功~~~~~~");
        // 初始化服务
        return service;
    }
}

注意:这里的回调接口一定是域名下的接口,且可以访问,后面没参数

相应的微信V3接口文档说明如下

微信V3接口文档

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用的)。另外,您不会使用资源的话(这种情况不支持退款),也可以找我们帮助(需要追加额外费用) 爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只牛博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值