微信小程序对接微信支付最新版教程

写在前面:做了几次小程序支付,从申请商户号到配置参数到上线整个流程,在这里记录一下,以免自己会忘记,也给没有接触过微信支付的小白提供一点参考,文中我参考的官方文档都放了链接,就不在详细赘述,本文使用了微信官方SDK:com.github.wechatpay-apiv3

1、微信支付平台申请商户号

2、申请商户号成功之后按照官方文档在商户平台配置apikey等等参数

3、申请成功之后按照官方文档做接入前准备

4、搭建springboot工程,一堆文档自己去搜吧

5、引入依赖

      <dependency>
                <groupId>com.github.wechatpay-apiv3</groupId>
                <artifactId>wechatpay-java</artifactId>
                <version>0.2.12</version>
     </dependency>

6、引入配置

wx:
  app:
    #    绩效管理页面
    kar-page: system/register
    #    活动页面
    activity-page: pages/index
  # 服务商商户号绑定的公众号信息
  ma:
    configs:
      - appid: 你的小程序appid
        secret: 你的小程序密钥
        mchId: 微信支付商户平台商户号
        mchSerialNumber: 微信支付商户平台商户序列号
        privateKeyPath: 微信支付商户平台私钥存放路径
        apiV3Key: 微信支付商户平台商台apiv3
        notifyUrl: 微信支付回调地址(微信官方会通过该地址发送支付通知)
package com.yycm.platform.system.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

/**
 * @Description 微信小程序
 * @Author ZJF
 * @Date 2024/7/16 15:37
 */
@Data
@ConfigurationProperties(prefix = "wx.ma")
public class WxMaProperties {
    private List<WxConfig> configs;

    public WxConfig getDefaultWxConfig() {
        return CollUtil.isNotEmpty(configs) ? configs.get(0) : null;
    }


    @Data
    public static class WxConfig {
        /**
         * 公众号appid
         */
        private String appid;

        /**
         * 设置微信小程序的Secret
         */
        private String secret;
        //=============================支付相关参数=========================================//

        /**
         * 服务商商户号
         */
        private String mchId;

        /**
         * 服务商证书序列号
         */
        private String mchSerialNumber;

        /**
         * 服务商API私钥路径
         */
        private String privateKeyPath;

        /**
         * 服务商apiV3密钥
         */
        private String apiV3Key;

        /**
         * 通知回调地址
         */
        private String notifyUrl;
    }

}


package com.yycm.platform.system.config;

import cn.hutool.core.lang.Assert;
import cn.hutool.extra.spring.SpringUtil;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.partnerpayments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.*;
import com.yycm.platform.system.dept.service.DeptService;
import com.yycm.platform.system.pojo.dto.DeptDto;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import yycm.platform.common.exception.PlatformException;

/**
 * @Description
 * @Author ZJF
 * @Date 2024/8/7 15:18
 */
@RequiredArgsConstructor
@Slf4j
@Configuration
@EnableConfigurationProperties(WxMaProperties.class)
public class WxMaConfiguration {


    private final WxMaProperties wxMaProperties;

    private final DeptService deptService;

    @Bean
    public RSAAutoCertificateConfig rsaAutoCertificateConfig() {
        WxMpProperties.WxConfig defaultWxConfig = wxMpProperties.getDefaultWxConfig();
        return new RSAAutoCertificateConfig.Builder()
                .merchantId(defaultWxConfig.getMchId())
                // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
                .privateKeyFromPath(defaultWxConfig.getPrivateKeyPath())
                .merchantSerialNumber(defaultWxConfig.getMchSerialNumber())
                .apiV3Key(defaultWxConfig.getApiV3Key())
                .build();
    }


    @Bean
    public JsapiServiceExtension jsapiServiceExtension(RSAAutoCertificateConfig rsaAutoCertificateConfig) {
        return new JsapiServiceExtension.Builder()
                .config(rsaAutoCertificateConfig)
                // .signType("RSA") // 不填则默认为RSA
                .build();
    }

    /**
     * 用来做支付参数的解密
     * @param rsaAutoCertificateConfig
     * @return
     */
    @Bean
    public NotificationParser notificationParser(RSAAutoCertificateConfig rsaAutoCertificateConfig) {
        return new NotificationParser(rsaAutoCertificateConfig);
    }


    /**
     * jsapi下单接口(这里是服务商模式的,各位自行改成普通小程序的吧)
     *
     * @param prepayRequest
     * @return
     */
    public PrepayWithRequestPaymentResponse buildPrepayWithRequestPaymentResponse(PrepayRequest prepayRequest) {
        //子商户应用ID 说明:子商户申请的公众号/小程序appid
        Assert.notNull(prepayRequest.getSubAppid(), () -> PlatformException.create("subAppId can not be null"));
        DeptDto brandByAppId = deptService.getBrandByAppId(prepayRequest.getSubAppid());
        Assert.notNull(brandByAppId, () -> PlatformException.create("subAppId not exists"));
        //子商户号 说明:子商户的商户号,由微信支付生成并下发
        prepayRequest.setSubMchid(brandByAppId.getWxMchid());
        WxMpProperties.WxConfig defaultWxConfig = wxMpProperties.getDefaultWxConfig();
        //服务商应用ID 说明:服务商申请的公众号appid
        prepayRequest.setSpAppid(defaultWxConfig.getAppid());
        //服务商户号 说明:服务商户号,由微信支付生成并下发
        prepayRequest.setSpMchid(defaultWxConfig.getMchId());
        return getJsapiServiceExtension().prepayWithRequestPayment(prepayRequest, prepayRequest.getSpAppid());
    }

    /**
     * 查询订单支付状态
     * 需要补充的参数:
     * transaction_id 微信支付订单号
     * sub_mchid 子商户号
     *
     * @return
     */
    public Transaction queryOrderById(QueryOrderByIdRequest queryOrderByIdRequest) {
        queryOrderByIdRequest.setSpMchid(wxMpProperties.getDefaultWxConfig().getMchId());
        return getJsapiServiceExtension().queryOrderById(queryOrderByIdRequest);
    }

    /**
     * 根据商户订单号查询订单状态
     * out_trade_no:商户订单号
     * sub_mchid: 子商户号
     *
     * @return
     */
    public Transaction queryOrderByOutTradeNo(QueryOrderByOutTradeNoRequest queryOrderByOutTradeNoRequest) {
        queryOrderByOutTradeNoRequest.setSpMchid(wxMpProperties.getDefaultWxConfig().getMchId());
        return getJsapiServiceExtension().queryOrderByOutTradeNo(queryOrderByOutTradeNoRequest);
    }

    /**
     * outTradeNo:商户订单号
     * 关闭订单
     */
    public void closeOrder(CloseOrderRequest closeOrderRequest) {
        closeOrderRequest.setSpMchid(wxMpProperties.getDefaultWxConfig().getMchId());
        getJsapiServiceExtension().closeOrder(closeOrderRequest);
    }


    public JsapiServiceExtension getJsapiServiceExtension() {
        return SpringUtil.getBean(JsapiServiceExtension.class);
    }


}


### 微信 B2B 支付的实现方式 微信 B2B 支付是一种企业间资金流转的服务,主要用于供应商付款、佣金发放等场景。以下是关于其集成方法和技术细节的相关说明。 #### 1. 接口概述 微信 B2B 支付基于微信支付的企业付款功能扩展而来,主要适用于企业间的批量转账需求。开发者需调用微信支付提供的 **企业付款到零钱 API** 或其他相关接口完成操作[^6]。此接口支持向指定用户的微信钱包进行转账,前提是目标用户已绑定过银行卡并实名认证。 #### 2. 实现步骤 以下是实现微信 B2B 支付的主要技术环节: - **商户资质准备** 商户需要具备以下条件才能使用该功能: - 成功注册成为微信支付服务商; - 开通企业付款权限,并签署相关协议; - 提供有效的商户证书用于签名验证[^3]。 - **构造请求参数** 构造请求时,必须包含必要的字段,例如接收方 OpenID、转账金额(单位为分)、备注信息等。这些参数应严格遵循微信支付官方文档中的定义[^7]。 下面是一个简单的 Java 请求示例代码片段: ```java public static String sendEnterprisePayment(String openId, int amount, String desc) { try { Map<String, Object> data = new HashMap<>(); data.put("mch_appid", "your_merchant_app_id"); data.put("mchid", "your_merchant_id"); data.put("nonce_str", UUID.randomUUID().toString()); data.put("partner_trade_no", System.currentTimeMillis() + ""); data.put("openid", openId); data.put("check_name", "NO_CHECK"); // 不校验收款人姓名 data.put("amount", amount); // 单位为分 data.put("desc", desc); String sign = generateSign(data); // 调用签名算法生成sign值 data.put("sign", sign); String xmlData = convertMapToXml(data); // 将map转换成xml字符串形式 HttpClient client = HttpClients.createDefault(); HttpPost post = new HttpPost("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"); post.setEntity(new StringEntity(xmlData)); HttpResponse response = client.execute(post); return EntityUtils.toString(response.getEntity()); // 返回响应结果XML } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } private static String generateSign(Map<String, Object> params) { /* 签名逻辑 */ } ``` - **安全机制** 安全性方面需要注意两点:一是采用 HTTPS 加密通信;二是利用 MD5/SHA256 对所有敏感数据加签防篡改[^8]。此外,在实际部署过程中还需妥善保管私钥文件以防泄露风险。 - **回调处理** 当交易完成后,微信会主动推送一条消息至预先设定好的 URL 地址告知最终状态(成功与否)[^9]。因此建议提前规划好如何解析此类通知包以便及时更新数据库记录。 #### 3. 常见问题排查指南 如果遇到失败情况可以从以下几个角度入手分析原因所在: - 参数填写错误或者缺失必填项; - 时间戳超出允许范围; - IP 白名单未设置正确导致访问受限等问题发生几率较高。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值