PC网站接入微信(Native)支付-扫码

1. 微信支付接入官网:

        可选择适合其接入方式,我们目前选择的是Native支付接入

        PC网站 - 微信支付接入指引 - 微信支付商户平台

2. 微信Native支付接入前准备:

        接入前准备-Native支付 | 微信支付商户平台文档中心

        主要准备好以下五种接入前的开发参数:

                微信商户账号(mchid)

                商户AppId

                 ApiV3秘钥(商户内自行设置的,并设置操作密码保存)

                证书序列号

                API证书压缩包中的文件apiclient_key.pem

3. 微信支付业务流程

4. 微信接入创建支付订单

PS:微信支付金额单位为分!!

引入微信支付sdk

        <!--WeChat Pay SDK-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.9</version>
        </dependency>

统一初始化RSAAutoCertificateConfig,value的值在对应的yml文件里进行配置即可

package com.geb.common.config;

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@Data
@Component
public class WxPayConfig {

    private static volatile Config config;

    /** 商户号 */
    @Value("${wechat.pay.mchId}")
    public  String mchId;

    /** 商户API私钥路径 */
    @Value("${wechat.pay.privateKeyPath}")
    public  String privateKeyPath;

    /** 商户证书序列号 */
    @Value("${wechat.pay.merchantSerialNumber}")
    public  String merchantSerialNumber;

    /** 商户APIV3密钥 */
    @Value("${wechat.pay.apiV3key}")
    public  String apiV3key;


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

}

创建支付订单-Service层方法

    /** AppId */
    @Value("${wechat.pay.appId}")
    public String appId;

    /** 商户号 */
    @Value("${wechat.pay.mchId}")
    public String mchId;

    /** 支付回调地址 */
    @Value("${wechat.callback.notifyUrl}")
    private String notifyUrl;

    @Autowired
    private WxPayConfig wxPayConfig;


    /**
     * 创建订单 - wechat - 生成预支付订单code_url
     * @param orderAddDto
     * @return
     */
    @Override
    @Transactional
    public OrderCreateVo createOrder(OrderAddDto orderAddDto){
        // 创建订单
        Order order = WrapperUtil.transform(orderAddDto, Order.class);
        order.setOrderCode(generateOrderNumber());
        order.setCreateTime(DateUtils.getNowDate());
        order.setBuyBy(SecurityUtils.getLoginUser().getUser().getNickName());
        order.setBuyId(SecurityUtils.getUserId());
        order.setUserId(SecurityUtils.getUserId());
        order.setPayStatus(PayStatusEnum.WAIT_PAY.getCode());
        order.setChannel(PayChannelEnum.WECHART.getCode()); // 1微信  2支付宝
        // 设置选择的时间
        order.setDuration(orderAddDto.getDurationName().getExpBase());
        BigDecimal cost = productService.calOrderCost(orderAddDto.getProductId().intValue(),  String.valueOf(orderAddDto.getDurationName()), orderAddDto.getResourcePackageNum());
//        BigDecimal cost = new BigDecimal("0.01");
        order.setShouldAmount(cost);
        this.save(order);

        // 获取产品标题
        WdProductEntity product = productMapper.selectById(orderAddDto.getProductId());

        // 使用自动更新平台证书的RSA配置
        Config config = wxPayConfig.getConfig(wxPayConfig);

        // 构建service
        NativePayService service = new NativePayService.Builder().config(config).build();
        // 设置所需参数
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal((cost.multiply(new BigDecimal(100)).intValue()));  // 微信支付用分来结算  记得 * 100
        amount.setCurrency("CNY");
        request.setAmount(amount);
        request.setAppid(appId);
        request.setMchid(mchId);
        request.setDescription(product.getName());
        request.setNotifyUrl(notifyUrl);
        request.setOutTradeNo(order.getOrderCode());
        /*// 微信二维码失效时间 4 分钟
        Date date = new Date(new Date().getTime() + 4 * 60 * 1000);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
        String expire = format.format(date);
        request.setTimeExpire(expire);*/
        PrepayResponse response = null;
        try {
            // 调用下单方法,得到应答
            response = service.prepay(request);
            // 使用微信扫描 code_url 对应的二维码,即可体验Native支付
            System.out.println(response.getCodeUrl());
            log.info("CreateOrder-PrePay code_url:{}", response.getCodeUrl());
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        // 设置返回订单信息
        OrderCreateVo orderCreateVo = new OrderCreateVo();
        orderCreateVo.setCodeUrl(response.getCodeUrl());
        orderCreateVo.setOrderCode(order.getOrderCode());
        orderCreateVo.setCompanyName(orderAddDto.getCompanyName());
        orderCreateVo.setShouldAmount(order.getShouldAmount());
        orderCreateVo.setExpireTime(orderAddDto.getExpireTime());
        return orderCreateVo;
    }

创建完订单后向微信发起创建预支付订单请求,然后会返回code_url,是二维码的url,前端用qrcode库转成待支付的二维码,然后用户进行扫码支付(二维码默认俩小时内有效)

5. 微信回调商户平台接口 -> 微信二维码扫码支付成功后

PS: 回调接口一定要域名备案的https的443端口哦~   否则回调失败

    /**
     * 微信支付回调接口
     * @param request
     * @param response
     * @return
     */
    @Override
    @Transactional
    public String wxpayNotify(JSONObject body, HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("微信支付回调:body:{}, request:{}, response:{}", body, request, response);

        // 获取请求体原内容(此时获取的数据是加密的)
        BufferedReader reader = request.getReader();
        StringBuilder requestBody = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            requestBody.append(line);
        }
        log.info("微信支付回调-requestBody:{}", requestBody);

        // 构造 RequestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(request.getHeader("wechatPay-Serial"))     //证书序列号
                .nonce(request.getHeader("wechatPay-Nonce"))             // 随机字符串
                .signature(request.getHeader("wechatPay-Signature"))     // 签名
                .timestamp(request.getHeader("wechatPay-Timestamp"))     // 时间戳
                .signType(request.getHeader("wechatPay-Signature-Type")) // 签名类型
                .body(requestBody.toString())                               // 请求体内容(原始内容,不要解析)
                .build();
        log.info("微信支付回调-requestData:requestParam:{}", requestParam);


        //获取微信证书,没有的话重新构造一个
        Config config = wxPayConfig.getConfig(wxPayConfig);
        NotificationParser parser = new NotificationParser((NotificationConfig)config);
        // 以支付通知回调为例,验签、解密并转换成 Transaction
        Transaction transaction = parser.parse(requestParam, Transaction.class);
        // 获取支付单号
        log.info("支付成功,回调信息:{}", transaction);
        // 打印其中的"微信支付单号"字段,可用于查单操作
        log.info("微信支付单号:{}", transaction.getTransactionId());
        // 获取微信支付回调状态
        Transaction.TradeStateEnum tradeState = transaction.getTradeState();
        log.info("微信Native支付回调状态 tradeState:{}", tradeState);

        // 返回给微信回调信息成功与否
        JSONObject json = new JSONObject();
        if (tradeState == Transaction.TradeStateEnum.SUCCESS) {
            // 业务逻辑代码

            // 将微信返回的订单号参数信息传到Dao层,进行校验
            QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_code", transaction.getOutTradeNo());
            Order order = wdOrderMapper.selectOne(queryWrapper);
            log.info("微信支付回调-Order:order:{}", order);
            // 订单待支付状态 - 更新订单信息
            if(order.getPayStatus().equals(PayStatusEnum.WAIT_PAY.getCode())){
                updateOrder(transaction, order);
                // 更新权益状态
                ProductDurationEnums productDurationEnums = null;
                switch (order.getDuration()){
                    case 1 : productDurationEnums = ProductDurationEnums.ONE_MONTH; break;
                    case 3 : productDurationEnums = ProductDurationEnums.THREE_MONTH; break;
                    case 12 : productDurationEnums = ProductDurationEnums.TWELVE_MONTH; break;
                    case 14 : productDurationEnums = ProductDurationEnums.TWELVE_MONTH2; break;
                }
                productCompanyService.subscriptionProduct(order.getCompanyId(), order.getProductId().intValue(), order.getOrderCode(), productDurationEnums,order.getResourcePackageNum());
            }
            response.setStatus(200);
            json.put("code", "SUCCESS");
            json.put("message", "操作成功");
        } else {
            response.setStatus(400);
            json.put("code", "FAIL");
            json.put("message", "验签失败");
        }
        return json.toString();
    }

以上就是接入微信Native支付的流程 申请好对应的相关信息后直接引入微信的sdk 有没有很方便!

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Core Web 可以通过微信支付提供的 API 进行扫码支付接入。下面是实现步骤: 1. 申请微信支付账号和开通扫码支付功能。在申请过程中,需要提供商户信息和开户银行信息等。 2. 在 ASP.NET Core Web 中引入微信支付 SDK,可以通过 NuGet 包管理器安装。 ``` Install-Package Senparc.Weixin.MP.Pay ``` 3. 在 ASP.NET Core Web 项目中添加配置文件 appsettings.json,用于存储微信支付相关的配置参数,如下所示: ``` { "WeixinPay": { "MchId": "微信支付分配的商户号", "AppId": "应用ID", "Key": "商户支付密钥" } } ``` 4. 在 ASP.NET Core Web 项目中创建一个控制器,用于处理扫码支付的请求。控制器代码如下所示: ``` [Route("api/[controller]")] [ApiController] public class WeixinPayController : ControllerBase { private readonly IOptions<WeixinPayOptions> _options; public WeixinPayController(IOptions<WeixinPayOptions> options) { _options = options; } [HttpPost("unifiedorder")] public async Task<IActionResult> UnifiedOrder([FromBody]UnifiedorderRequest request) { // 设置请求参数 var data = new TenPayV3UnifiedorderRequestData( body: request.Body, outTradeNo: request.OutTradeNo, totalFee: request.TotalFee, spbillCreateIp: request.SpbillCreateIp, notifyUrl: request.NotifyUrl, tradeType: "NATIVE", productId: request.ProductId ); // 调用统一下单 API 进行支付 var result = await TenPayV3.UnifiedorderAsync(_options.Value.AppId, _options.Value.MchId, _options.Value.Key, data); // 处理返回结果 if (result.ReturnCode == "SUCCESS" && result.ResultCode == "SUCCESS") { // 生成二维码图片 var url = result.CodeUrl; var qrCode = new QRCodeGenerator().CreateQrCode(url, QRCodeGenerator.ECCLevel.Q); // 返回二维码图片 return File(qrCode.GetGraphic(20), "image/png"); } // 返回错误信息 return BadRequest(result.ReturnMsg); } } ``` 5. 创建一个模型类,用于保存扫码支付的请求参数。 ``` public class UnifiedorderRequest { public string Body { get; set; } public string OutTradeNo { get; set; } public int TotalFee { get; set; } public string SpbillCreateIp { get; set; } public string NotifyUrl { get; set; } public string ProductId { get; set; } } ``` 6. 在 Startup.cs 文件中添加微信支付相关的配置,代码如下所示: ``` services.Configure<WeixinPayOptions>(Configuration.GetSection(nameof(WeixinPayOptions))); ``` 7. 启动 ASP.NET Core Web 项目,使用 Postman 或其他工具向接口发送扫码支付的请求,请求参数包括:商品描述、商户订单号、总金额、终端 IP、通知地址、商品 ID 等。 ``` POST /api/weixinpay/unifiedorder HTTP/1.1 Host: localhost:5000 Content-Type: application/json { "body": "测试商品", "outTradeNo": "123456", "totalFee": 1, "spbillCreateIp": "127.0.0.1", "notifyUrl": "http://localhost:5000/api/weixinpay/notify", "productId": "123456" } ``` 8. 如果请求成功,将返回一个二维码图片,可以使用扫码工具扫描该二维码进行支付。如果请求失败,将返回错误信息。 以上就是 ASP.NET Core Web 支付功能接入微信扫码支付的实现步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值