项目是springboot项目,调用best-pay-sdk sdk包(注意:微信支付只支持V2版本) 微信V2版本链接

整个调用是比较简单的,如果想用微信支付V3最新版的话,可以百度查找一下,这篇demo是用于PC端的,APP和小程序的话不推荐使用,APP掉坑爬不起来

pom.xml

<dependency>
    <groupId>cn.springboot</groupId>
    <artifactId>best-pay-sdk</artifactId>
    <version>1.3.0</version>
 </dependency>

Config

/**
 * 东泰 http://dt2008.cn
 * 2020-11
 */
@Component
public class BestPayConfig {

    @Bean
    public BestPayService bestPayService(){
        //微信官方参数
        WxPayConfig wxPayConfig = new WxPayConfig();
        wxPayConfig.setAppId("");
        wxPayConfig.setMchId("");
        wxPayConfig.setMchKey("");
        wxPayConfig.setNotifyUrl("https://dt2008.cn/pay/notify");       //微信支付后返回域名地址 pay/notify?notifyData  POST请求
        /*********************************************************************************/
        //支付宝官方参数
        AliPayConfig aliPayConfig = new AliPayConfig();
        aliPayConfig.setAppId("");
        aliPayConfig.setPrivateKey("");
        aliPayConfig.setAliPayPublicKey("");
        aliPayConfig.setReturnUrl("https://dt2008.cn/pay/notify");                  //支付宝支付后返回域名地址 pay/notify?notifyData  POST请求

        BestPayServiceImpl bestPayService = new BestPayServiceImpl();
        bestPayService.setWxPayConfig(wxPayConfig);
        bestPayService.setAliPayConfig(aliPayConfig);
        return bestPayService;
    }

}

Service层

主要是调用支付,支付过程中的逻辑就不写了,你们可以跟着自己的项目逻辑来写

    @Autowired
    private BestPayService bestPayService;

    /**
     * 发起支付
     * @param orderId       订单号
     * @param amount        金额
     * @param bestPayTypeEnum   支付类型 微信 支付宝
     * @return
     */
    public PayResponse create(String orderId, BigDecimal amount, BestPayTypeEnum bestPayTypeEnum) {
        //判断是微信还是支付宝
        if(bestPayTypeEnum != bestPayTypeEnum.WXPAY_NATIVE
        && bestPayTypeEnum != bestPayTypeEnum.ALIPAY_PC
        ){
            throw new RuntimeException("暂不支持的支付类型");
        }
        
        //这里可以写存储数据库的逻辑,比如存储订单号啥的,这里就不写了        
        
        PayRequest request = new PayRequest();
        request.setOrderName("5352785-练习册");             //订单名称
        request.setOrderId(orderId);                        //订单号(自定义)
        request.setOrderAmount(amount.doubleValue());       //金额
        request.setPayTypeEnum(bestPayTypeEnum);            //模式
        PayResponse response = bestPayService.pay(request);
        return response;
    }

    /**
     * 异步通知处理
     * @param notifyData
     */
    public String asyncNotify(String notifyData) {
        //1 签名校验
        PayResponse payResponse = bestPayService.asyncNotify(notifyData);

        //这里可以查询订单号或者查询金额等等
        //payResponse.getOrderAmount()		//金额方法

        //判断支付平台
        if(payResponse.getPayPlatformEnum() == BestPayPlatformEnum.WX){
            //返回微信
            //返回格式给微信不要再通知了
            return "<xml>\n" +
                    "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                    "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                    "</xml>";
        }else if(payResponse.getPayPlatformEnum() == BestPayPlatformEnum.ALIPAY){
            //返回支付宝
            return "success";
        }

        throw new RuntimeException("暂不支持的支付类型");
    }

controller层

采用异步和同步都可以,在pc端最好采用同步,因为支付宝是返回整个支付页面的,微信返回的是url连接(续生成二维码扫码)

/**
 * 东泰 http://dt2008.cn
 * 2020-11
 */
@Controller
@RequestMapping("pay")
public class PayController {

    @Autowired
    private PayService payService;

    @GetMapping("create")
    public ModelAndView create(
            @RequestParam("orderId")String orderId,
            @RequestParam("amount")BigDecimal amount,
            @RequestParam("payType") BestPayTypeEnum bestPayTypeEnum
    ){
        PayResponse response = payService.create(orderId, amount, bestPayTypeEnum);
        Map<String, Object> map = new HashMap<>();
        //支付方式不同,渲染就不同,WXPAY_NATIVE使用codeUrl,ALIPAY_PC使用body
        if(bestPayTypeEnum == bestPayTypeEnum.WXPAY_NATIVE){
            map.put("codeUrl", response.getCodeUrl());
            return new ModelAndView("createForWxNative", map);
        }else if(bestPayTypeEnum == bestPayTypeEnum.ALIPAY_PC){
            map.put("body", response.getBody());
            return new ModelAndView("createForAliPayPc", map);
        }
        throw new RuntimeException("暂不支持的支付类型");
    }

    /**
     * 异步通知处理
     * @param notifyData
     */
    @PostMapping("notify")
    @ResponseBody
    public String asyncNotify(@RequestBody String notifyData){
        return payService.asyncNotify(notifyData);
    }

}

注意:异步通知处理是返回给微信和支付宝是否成功的,成功之后再也不会接收到通知了

微信页面 createForWxNative

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>微信支付</title>
</head>
<body>
    <div id="code"></div>
</body>
<script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
<script>
    $(document).ready(function(){
        $('#code').qrcode("${codeUrl}");
    })
</script>
</html>

支付宝页面  createForAliPayPc

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>支付宝支付</title>
</head>
<body>
    ${body}
</body>
</html>

url请求

微信    域名/pay/create?orderId=订单号&amount=支付金额&payType=WXPAY_NATIVE

支付宝    域名/pay/create?orderId=订单号&amount=支付金额&payType=ALIPAY_PC

域名/pay/create?orderId=111111111&amount=0.01&payType=ALIPAY_PC

 

整体就这样了,如果不明白为什么有异步通知这块的话讲解一下,就是避免服务器出现问题所用到的,官方会定时返回通过,好像是15秒左右起步,返回时间是累计的,最长24小时

 

最后修改于 2021-09-18 06:38:00
上一篇