SpringBoot集成微信小程序创建订单&支付&退款(保姆级教程)

SpringBoot集成微信小程序创建订单&支付&退款

概要

提示:个人小程序不能进行支付等操作,因为需要在微信小程序进行商户认证等一系列操作
1,小程序支付触发如下:
在这里插入图片描述
实现逻辑:
1.1,点击支付首先前端传后端需要的一系列参数,调用后端生成一个未支付的订单,并返回给前端订单id
1.2,前端根据订单id调用接口生成微信小程序的订单(核心是调用微信小程序接口),重点参数有1里的订单id和回调地址(用于4回调时会在传参里传到后端,然后通过解析找到订单id查询订单并修改订单状态),返回一系列res
1.3,前端调起输入密码窗口,根据2返回的res,组装并完成支付
1.4,在2中有一个req的一个参数是负责微信支付回调的忽略token的全路径的接口地址,用于通知后端支付情况。

2,小程序退款申请触发如下:
在这里插入图片描述
实现逻辑:
2.1 用户点击取消预定触发退款申请操作,传入微信订单的订单id【transactionId】和退款理由,最终调用微信退款申请发起退款
2.2 根据微信接口返回结果判断是PROCESSING(处理中),SUCCESS(退款成功),ABNORMAL(异常),CLOSED(退款关闭)通过transactionId查找对应的后端订单,然后修改对应订单状态
2.3 退款回调,同理支付回调,后端通过解析回调参数判断是否退款成功

1,创建微信小程序订单

前提:小程序已经调用后端创建订单接口并返回给了前端订单id

pm.xml配置

<!-- 微信小程序支付-->
<dependency>
     <groupId>com.github.wechatpay-apiv3</groupId>
     <artifactId>wechatpay-java</artifactId>
     <version>0.2.12</version>
</dependency>

1.1 yml 配置

# 微信小程序配置
wx:
  appId: 
  secret: 
  grant_type: client_credential
  #商户号
  merchantId: 
  # 私钥路径
  privateKeyPath: **/apiclient_key.pem
  # 商户号证书序列号
  merchantSerialNumber: 
  # 商户apiV3秘钥
  apiV3key: 
  #支付回调
  notifyUrl: https://..../payNotify
  #退款回调
  refundNotifyUrl: https://..../refundNotify

1.2 WxPayConfig 配置类

@Data
@Component
@ConfigurationProperties(prefix = "wx")
public class WxPayConfig {
   

    // appId
    private String appId;
    // secret
    private String secret;
    //
    private String grant_type;
    // 商户id
    private String merchantId;
    // 私钥地址
    private String privateKeyPath;
    // 商户序列号
    private String merchantSerialNumber;
    // apiV3key
    private String apiV3key;
    // 支付回调地址
    private String notifyUrl;
    // 退款回调地址
    private String refundNotifyUrl;
}

1.3 WxPayAutoCertificateConfig 配置类

@Configuration
public class WxPayAutoCertificateConfig {
   

    @Resource
    private WxPayConfig wxPayConfig;

    /**
     * 初始化商户配置
     * @return
     */
    @Bean
    public RSAAutoCertificateConfig rsaAutoCertificateConfig() {
   
    RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
        .merchantId(wxPayConfig.getMerchantId())
        .privateKey(PemUtil.loadPrivateKeyFromPath(wxPayConfig.getPrivateKeyPath()))
        .merchantSerialNumber(wxPayConfig.getMerchantSerialNumber())
        .apiV3Key(wxPayConfig.getApiV3key())
        .build();
    return config;
    }

}

1.4 Controller层

  @GetMapping("/createOrder")
    public R<PrepayWithRequestPaymentResponse> createOrder(@Validated Long orderId) {
   
        logger.info("微信小程序创建预支付订单", orderId.toString());
        try {
   
            return weChatService.createOrder(orderId);
        } catch (Exception e) {
   
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
    }

1.5 Impl层(Service自行补充)

    private final WxPayConfig wxPayConfig;

    private final WxPayAutoCertificateConfig certificateConfig;

    private static final String BASE_URL = "https://api.weixin.qq.com";
    
 @Override
    public R<PrepayWithRequestPaymentResponse> createOrder(Long orderId) throws Exception {
   
        // 通过订单id获取到订单信息
        R hotelOrder = hotelPcClient.detailHotelOrder(orderId);
        if (!hotelOrder.isSuccess()){
   
            throw new Exception("订单不存在,稍后重试");
        }
        HotelOrderVO order =JSONObject.parseObject(JSONObject.toJSONString(hotelOrder.getData()), HotelOrderVO.class);
        log.info("请求微信支付相关配置");
        JsapiServiceExtension service =
                new JsapiServiceExtension.Builder()
                        .config(certificateConfig.rsaAutoCertificateConfig())
                        .signType("RSA") // 不填默认为RSA
                        .build();
        PrepayWithRequestPaymentResponse response = new PrepayWithRequestPaymentResponse();
        try {
   
            PrepayRequest request = new PrepayRequest();
            request.setAppid(wxPayConfig.getAppId());
            request.setMchid(wxPayConfig.getMerchantId());
            request.setDescription(order.getRemark());
            request.setOutTradeNo(order.getSerialNumber());
            request.setNotifyUrl(wxPayConfig.getNotifyUrl());
            Amount amount = new Amount();
            // 以分为单位
            amount.setTotal(order.getPaymentAmount().multiply(new BigDecimal("100")).intValue());
            request.setAmount(amount);
            Payer payer = new Payer();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值