springboot整合微信二维码支付

我们需要做的是:

/**
     * 作用:统一下单<br>
     * 场景:公共号支付、扫码支付、APP支付
     * @param reqData 向wxpay post的请求数据
     * @return API返回数据
     * @throws Exception
     */
public Map<String, String> unifiedOrder(Map<String, String> reqData) throws Exception {
    return this.unifiedOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}

这里的请求参数是:Map<String, String> reqData,就是官方API说明中的请求参数了,不过并不需要我们填写所有参数,而只需要下面的:

    body:商品描述 out_trade_no:订单编号 total_fee:订单应支付金额 spbill_create_ip:设备IP notify_url:回调地址 trade_type:交易类型

剩下的:appid、mch_id、nonce_str、sign_type和sign参数都有WXPay对象帮我们设置,那么问题来了:这些参数数据WXPay是怎么拿到的呢?

其中,

    nonce_str:是随机字符串,因此由WXPay随机生成, sign_type:是签名算法,由WXPay指定,默认是HMACSHA256; sign:是签名,有签名算法结合密钥加密而来,因此这里的关键是密钥:key appid、mch_id是商家信息,需要配置

也就是说,这例需要配置的包括:appid、mch_id、密钥key。这些从哪里来呢?

看下WXPay的构造函数:

public WXPay(final WXPayConfig config) throws Exception {
    this(config, null, true, false);
}

这里需要一个WXPayConfig对象,显然是配置对象。

WXPayConfig配置

WXPay依赖于WXPayConfig进行配置,那么WXPayConfig是什么呢?

看下源码中的关键部分:

public abstract class WXPayConfig {
    /**
     * 获取 App ID
     *
     * @return App ID
     */
    abstract String getAppID();
    /**
     * 获取 Mch ID
     *
     * @return Mch ID
     */
    abstract String getMchID();
    /**
     * 获取 API 密钥
     *
     * @return API密钥
     */
    abstract String getKey();
    
    // 。。。省略
}

这不就是WXPay中需要配置的3个属性嘛,当我们实现这个类,并且给出其中的值,把WXPayConfig传递给WXPay时,WXPay就会获取到这些数据:

当我们利用WXPay发送请求时,WXPay就会帮我们封装到请求参数中:

而在我提供给大家的SDK中,就编写了一个WXPayConfig的实现:

package com.github.wxpay.sdk;

import lombok.Data;

import java.io.InputStream;

/**
 * @author 黑马程序员
 */
@Data
public class WXPayConfigImpl extends WXPayConfig {
    /**
     * 公众账号ID
     */
    private String appID;
    /**
     * 商户号
     */
    private String mchID;
    /**
     * 生成签名的密钥
     */
    private String key;
    /**
     * 支付回调地址
     */
    private String notifyUrl;
    /**
     * 支付方式
     */
    private String payType;

    public InputStream getCertStream(){
        return null;
    }

    public IWXPayDomain getWXPayDomain(){
        return WXPayDomainSimpleImpl.instance();
    }
}

将来我们只需要new出这个实现类对象,并且给这3个参数赋值即可。

话不多说,开撸

首先,把下载的SDK打包并安装到本地的maven仓库,方便在项目中使用。

直接对SDK进行打包,在项目maven中执行如下命令:

mvn source:jar install -Dmaven.test.skip=true

如图所示:

打包完成后

引入依赖(除了wxpay的依赖,还需要一个转换xml的依赖)

<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>wxpay-sdk</artifactId>
    <version>3.0.9</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

在yml中配置 (如果服务运行在本地,那么回调接口就无法回调成功,需要使用内网穿透工具)

将这些属性注入到PayProperties中:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "pay.wx")
public class PayProperties {
    private String appId;
    private String mchId;
    private String key;
    private String notifyUrl;
    private String payType;
}

封装支付工具类

以下以供参考

controller调用生成支付链接:

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;
/**
     * 生成支付链接
     *
     */
    @GetMapping("/order/url/{id}")
    public ResponseEntity<String> buildPayUrl(@PathVariable("id") Long id){
        String payUrl = orderService.buildPayUrl(id);
        return ResponseEntity.ok(payUrl);
    }
}

service代码:

可以设置支付链接的有效时间,可以使用redis缓存:

页面响应结果:

使用qrious.js将该链接转成二维码

controller:

service

到这里整个支付流程就完成了

经验分享 程序员 微信小程序 职场和发展