接入微信支付APIv3

一、使用微信支付前言

	之前公司微信支付使用的第三方支付商的支付通道,由于业务整改现决定直接对接微信官方的支付通道。在接入微信支付过程中,对接入过程进行了整理,希望对接入有需要的朋友有所帮助。
	前言:
	1.微信支付使用微信APIv3支付。
	2.微信使用直连方式(商户模式非合作商模式)。
	3.公司接入的公众号支付、小程序支付、APP支付三种支付方式。此文章以公众号支付来介绍接入微信支付,虽然是以公众号支付为事例讲解,但是博主认为集中接入并没有区别,只不过调用微信底层接口不同,入参公众号支付与小程序支付一致,APP稍有差别。

二、微信支付APIv3接入准备

接入准备看官方文档即可,讲解的很详细,博主也是按照官方文档接入准备一步一步配置完成的。

微信官方接入准备文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_1.shtml

根据官方接入准备文档,完成公众号AppID申请、商户号申请、AppID与商户号绑定、配置API key、下载配置商户证书、配置支付授权目录、配置授权域名等上述7步。

每步步骤结果如下,各位朋友可以参考:
1.申请公众号AppID
在这里插入图片描述
2.申请商户号mchid
在这里插入图片描述
3.绑定公众号AppID和商户号mchid
在这里插入图片描述
4.配置API key
在这里插入图片描述
5.配置商户证书
在这里插入图片描述
6.配置支付授权目录
在这里插入图片描述
7.设置授权域名
在这里插入图片描述
备注:完成配置后可与上述步骤图片进行对比确定配置结果。

三、微信支付APIv3开发指引

开发指引官方文档。

微信官方《开发指引文档》地址:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_3.shtml

1.下载微信支付 APIv3 Java SDK

官方推荐版(java): wechatpay-java
其他版本请进入到《开发指引文档》查看:
在这里插入图片描述

备注:博主认为是有下载需要的,可以去看事例和实现,方便学习和快速接入。

2.业务流程图
在这里插入图片描述
在这里插入图片描述

四、微信支付官方api介绍

1.接口列表
官方接口列表地址:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_4.shtml
在这里插入图片描述
根据自己的需求选择接入的接口。
2.官方SDK学习
–直接看README,说明指引也很详细,这里展示一下位置,不做过多展示,有兴趣的朋友可以仔细看一遍。
在这里插入图片描述
查看SDK中的具体实现方法
在这里插入图片描述
查看上下文可以看到测试方法
在这里插入图片描述
感兴趣的朋友可以进行试着调试一下。

五、微信支付实操接入演示

开发重点准备与说明:

商户号:
public static String merchantId = "";
商户API私钥路径 **/apiclient_key.pem
public static String privateKeyPath = "";
商户证书序列号 登录商户平台可以看到
public static String merchantSerialNumber = "";
 商户APIV3密钥 登录商户平台设置
public static String apiV3key = "";

接入的整体流程:

	第一步:封装支付申请对象数据以及初始化商户配置信息数据。
	第二步:初始化商户配置信息。
	第三步:初始化服务。
	第四部:调用微信方法。

接下来看代码:
1.创建处理方法

添加依赖:

<!--wechatpay-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.9</version>
        </dependency>
/**
     * <b>方法名: </b> applyPay <br>
     * <b>说明: </b> 支付申请处理方法 <br>
     *
     * @param wechatPayApplyRequest {@link WechatPayApplyRequest}
     * @return {@link PrepayResponse} <br>
     * <b>修改履历: </b>
     * @author 2023/6/27 zj
     */
    public static PrepayResponse applyPay(WechatPayApplyRequest wechatPayApplyRequest) {
        PrepayResponse response = new PrepayResponse();
        try {
           response = CreateRequestUtil.prepay(wechatPayApplyRequest);
            logger.info("微信官方支付---支付请求完成,响应参数:{}"+ JSON.toJSONString(response));
            return response;
        } catch (Exception e) {
            logger.error("微信官方支付---支付请求异常:", e);
        }
        return response;
    }
CreateRequestUtil:为我们的自定义支付下单申请处理Util
WechatPayApplyRequest:封装的入参数,其中包括两部分1.初始化商户部分信息、支付申请部分信息
PrepayResponse:为我们的返回对象,微信支付提供的。

2.创建CreateRequestUtil 支付申请处理类

/**
 * 创建请求工具类
 */
public class CreateRequestUtil {

    /**
     * 微信公众号支付下单方法
     * @param wechatPayApplyRequest 支付下单入参对象
     * @return prepayResponse PrepayResponse
     */
    public static PrepayResponse prepay(WechatPayApplyRequest wechatPayApplyRequest) {
        PrepayRequest prepayRequest = new PrepayRequest();
        prepayRequest.setAppid(wechatPayApplyRequest.getAppid());
        prepayRequest.setMchid(wechatPayApplyRequest.getMchid());
        prepayRequest.setDescription(wechatPayApplyRequest.getDescription());
        prepayRequest.setOutTradeNo(wechatPayApplyRequest.getOutTradeNo());
        if(null !=wechatPayApplyRequest.getTimeExpire() ){
            prepayRequest.setTimeExpire(wechatPayApplyRequest.getTimeExpire());
        }
        if(null !=wechatPayApplyRequest.getAttach() ){
            prepayRequest.setAttach(wechatPayApplyRequest.getAttach());
        }
        prepayRequest.setNotifyUrl(wechatPayApplyRequest.getNotifyUrl());
        if(null !=wechatPayApplyRequest.getGoodsTag() ){
            prepayRequest.setGoodsTag(wechatPayApplyRequest.getGoodsTag());
        }
        if(null !=wechatPayApplyRequest.getSupportFapiao() ){
            prepayRequest.setSupportFapiao(wechatPayApplyRequest.getSupportFapiao());
        }
        prepayRequest.setAmount(wechatPayApplyRequest.getAmount());
        prepayRequest.setPayer(wechatPayApplyRequest.getPayer());
        if(null !=wechatPayApplyRequest.getDetail() ){
            prepayRequest.setDetail(wechatPayApplyRequest.getDetail());
        }
        if(null !=wechatPayApplyRequest.getSceneInfo() ){
            prepayRequest.setSceneInfo(wechatPayApplyRequest.getSceneInfo());
        }
        if(null !=wechatPayApplyRequest.getSettleInfo() ){
            prepayRequest.setSettleInfo(wechatPayApplyRequest.getSettleInfo());
        }
        // 获取、初始化商户配置
        Config config = MerchantUtil.getInstance().handleMer(wechatPayApplyRequest.getMchid(),
                wechatPayApplyRequest.getPrivateFilePath(),wechatPayApplyRequest.getPrivateFileSn(),
                wechatPayApplyRequest.getApiPrivate());
        // 初始化服务
        JsapiService service = new JsapiService.Builder().config(config).build();
        // 调用处理接口,返回微信下单服务处理结果
        return service.prepay(prepayRequest);
    }

}
重要步骤:
(1)方法上部分为复制对象。
(2)初始化商户配置,博主也是创建了一个自定义Util来进行处理,这里需要注意的一点,项目启动后只需要初始化一次即可,所以要用单利来进行处理。
(3)初始化服务
(4)调用微信jar包中的方法,传入参数。

3.创建初始化商户配置类MerchantUtil

/**
 * 商户初始化工具类
 * 懒加载单利处理
 */
public class MerchantUtil {
    private static MerchantUtil merchantUtil =null;
    private static RSAAutoCertificateConfig config =null;

    public MerchantUtil() {
    }

    public static synchronized MerchantUtil getInstance(){
        if(merchantUtil ==null){
            synchronized (MerchantUtil.class){
                if(merchantUtil == null){
                    merchantUtil = new MerchantUtil();
                }
            }
        }
        return merchantUtil;
    }

    /**
     * 微信公众号支付商户数据处理方法
     * @param merchantId 直连商户的商户号,由微信支付生成并下发。
     * @param privateKeyPath 商户API私钥路径
     * @param merchantSerialNumber 商户证书序列号
     * @param apiV3key 商户APIV3密钥
     * @return config Config
     */
    public static RSAAutoCertificateConfig handleMer(String merchantId, String privateKeyPath, String merchantSerialNumber, String apiV3key){
        if(config ==null){
            config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKeyFromPath(privateKeyPath)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3key)
                    .build();
        }
        return config;
    }
}

这里肯定好多朋友会有疑问,为什么不在项目启动的时候初始化商户配置,我在这里说一下。我们的项目做了支付中心-》支付api-〉三方支付通道,做了接入隔离放到了支付api中,以jar的形式在支付中心引入,所以采用这种方式。各位朋友可以按照自己的需求和架构来设计。

商户配置初始化的两种方式:
(1)上面我们MerchantUtil中的这种,使用的是apiV3Key
在这里插入图片描述
(2)在上面讲微信官方sdk时提到的,用微信平台证书的方式
在这里插入图片描述
各位朋友根据自己的实际来
4.支付申请入参对象WechatPayApplyRequest

public class WechatPayApplyRequest {
    /**
     * 由微信生成的应用ID,全局唯一。请求基础下单接口时请注意APPID的应用属性,例如公众号场景下,需使用应用属性为公众号的服务号APPID
     * 示例值:wxd678efh567hg6787
     */
    private String appid;
    /**
     * 直连商户的商户号,由微信支付生成并下发。
     * 示例值:1230000109
     */
    private String mchid;
    /**
     * 商户API私钥路径
     */
    private String privateFilePath;
    /**
     * 商户证书序列号
     */
    public String privateFileSn;
    /**
     * 商户APIV3密钥
     */
    private String apiPrivate;

    /**
     * 商品描述
     * 示例值:Image形象店-深圳腾大-QQ公仔
     */
    private String description;
    /**
     * 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
     */
    private String outTradeNo;
    /**
     * 否
     * 订单失效时间,遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE,yyyy-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,
     * HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,
     * 北京时间2015年5月20日 13点29分35秒。
     * 示例值:2018-06-08T10:34:56+08:00
     */
    private String timeExpire;
    /**
     * 否
     * 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用,实际情况下只有支付完成状态才会返回该字段。
     * 示例值:自定义数据
     */
    private String attach;
    /**
     * 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 公网域名必须为https,如果是走专线接入,
     * 使用专线NAT IP或者私有回调域名可使用http
     * 示例值:https://www.weixin.qq.com/wxpay/pay.php
     */
    private String notifyUrl;
    /**
     * 否
     * 订单优惠标记
     * 示例值:WXG
     */
    private String goodsTag;
    /**
     * 否
     * 传入true时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效。
     * true:是
     * false:否
     * 示例值:true
     */
    private Boolean supportFapiao;
    /**
     * 订单金额信息(分)人民币
     */
    private Amount amount;
    /**
     * 支付者信息
     * 用户在直连商户appid下的唯一标识。 下单前需获取到用户的Openid,Openid获取详见
     * 示例值:oUpF8uMuAJO_M2pxb1Q9zNjWeS6o
     */
    private Payer payer;
    /**
     * 否
     * 优惠功能
     */
    private Detail detail;
    /**
     * 支付场景描述
     */
    private SceneInfo sceneInfo;
    /**
     * 结算信息
     */
    private SettleInfo settleInfo;
    }

具体参数各位朋友可以去看官方api接口文档
在这里插入图片描述
或者查看官方微信sdk中支付申请的入参对象
在这里插入图片描述
各位朋友可以自己尝试自己接入一下,其实在看过官方sdk后在接入还是比较简单的。
其他支付回调、退款申请、退款回调等接口也可以按照此方式进行,现查看官方sdk事例。

预祝各位朋友顺利接入成功!!!

六、代码实例DEMO

github地址:https://github.com/zjfg/pay-api.git

Demo中接入的支付申请,支付回调,退款申请,退款回调等微信支付的接口,可以为各位朋友提供参考:

1.添加配置信息即可使用:
配置相关参数,启动即可使用测试
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值