• 微信发起h5支付(公众号支付)步骤


    1.查看微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

    2. 使用sdk获取预订单信息,通过预订单信息发起支付

      a.引用sdk依赖,该支付sdk文档:https://github.com/Pay-Group/best-pay-sdk

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

      b. 给sdk的bestPayService添加配置:

    @Component
    public class WechatPayConfig {
    
        @Autowired
        private WechatAccountConfig wechatAccountConfig;
    
        @Bean
        public BestPayServiceImpl bestPayService(){
            BestPayServiceImpl bestPayService=new BestPayServiceImpl();
            bestPayService.setWxPayH5Config(wxPayH5Config());
            return  bestPayService;
        }
    
    
        private WxPayH5Config wxPayH5Config(){
            WxPayH5Config wxPayH5Config = new WxPayH5Config();
            //wechatAccountConfig是通过
            // @ConfigurationProperties(prefix = "wechat")读取yml文件的配置文件对象
            wxPayH5Config.setAppId(wechatAccountConfig.getMpAppId());     
            wxPayH5Config.setAppSecret(wechatAccountConfig.getMpAppSecret());
            wxPayH5Config.setMchId(wechatAccountConfig.getMchId());
            wxPayH5Config.setMchKey(wechatAccountConfig.getMchKey());
            wxPayH5Config.setKeyPath(wechatAccountConfig.getKeyPath());
            wxPayH5Config.setNotifyUrl(wechatAccountConfig.getNotifyUrl());
            return wxPayH5Config;
        }
    }

      c.编写本地的payservice

    @Service
    public class PayServiceImpl implements PayService {
    
        private static final String ORDER_NAME = "微信点餐订单";
        @Autowired
        BestPayServiceImpl bestPayService;
    
        @Override
        public PayResponse create(OrderDTO orderDTO) {
            PayRequest request=new PayRequest();
            //通过查询出的order信息,设置支付的必填项
            request.setOpenid("oTgZpwU8hDPxbUjXmwLXp6TiBqK4");
            request.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
            request.setOrderId(orderDTO.getOrderId());
            request.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
            request.setOrderName(ORDER_NAME);
            PayResponse payResponse = bestPayService.pay(request);
            return payResponse;
        }
    }

      d.编写controller获取payResponse,里面包含信息如下

    @Controller
    @Slf4j
    @RequestMapping("/pay")
    public class PayController {
        
        @Autowired
        OrderService orderService;
        @Autowired
        PayService payService;
    
        @GetMapping("/create")
        public ModelAndView create(@RequestParam("orderId") String orderId,
                                   @RequestParam("returnUrl") String returnUrl) {
            //1. 查询订单
            OrderDTO orderDTO = orderService.findOne(orderId);
            if (orderDTO == null) {
                throw new SellException(ResultEnum.ORDER_NOT_EXIST);
            }
            //发起支付
            PayResponse payResponse = payService.create(orderDTO);   //通过查询的订单创建支付
            log.info("payResponse={}", JsonUtil.toJson(payResponse));
            Map<String,Object> result=new HashMap<>();
            result.put("payResponse",payResponse);
            result.put("returnUrl",returnUrl);
            return new ModelAndView("pay/create",result);   //将数据传输至freemark文件(前端)
        }
    
    }

       e.通过payResponse获取的信息传输给前端,在前端发起支付(只有在微信才可支付)

    <script>
        function onBridgeReady(){
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId":"${payResponse.appId}",     //公众号名称,由商户传入
                    "timeStamp":"${payResponse.timeStamp}",         //时间戳,自1970年以来的秒数
                    "nonceStr":"${payResponse.nonceStr}", //随机串
                    "package":"${payResponse.packAge}",
                    "signType":"${payResponse.signType}",         //微信签名方式:
                    "paySign":"${payResponse.paySign}" //微信签名
                },
                function(res){
                    if(res.err_msg == "get_brand_wcpay_request:ok" ){
                        // 使用以上方式判断前端返回,微信团队郑重提示:
                        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
                    }
                });
        }
        if (typeof WeixinJSBridge == "undefined"){
            if( document.addEventListener ){
                document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
            }else if (document.attachEvent){
                document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
            }
        }else{
            onBridgeReady();
        }
    </script>

       f.支付成功,微信异步通知:

        配置接收异步信息的service:

        public void notify(String notifyData){
            //验证签名 sdk已验证
            //支付的状态 sdk已验证
            //支付金额
            PayResponse payResponse = bestPayService.asyncNotify(notifyData);  //解析微信返回的xml文件
            OrderDTO orderDTO = orderService.findOne(payResponse.getOrderId());
            if(orderDTO==null){
                log.error("异步通知,订单不存在 orderId={}",payResponse.getOrderId());
                throw  new SellException(ResultEnum.ORDER_NOT_EXIST);
            }
            if(!MathUtil.equals(payResponse.getOrderAmount(),orderDTO.getOrderAmount().doubleValue())){
                log.error("异步通知,金额不相等 payResponse={}", JsonUtil.toJson(payResponse));
                throw  new SellException(ResultEnum.WXPAY_NOTIFY_MONEY_VERIFY_ERROR);
            }
            orderService.paid(orderDTO);
        }

        配置相应的controller层

        @PostMapping("/notify")
        public ModelAndView notify(@RequestBody String notifyData){//获取微信服务器传来的xml文件
            payService.notify(notifyData);
            return new ModelAndView("pay/success");
            //给微信服务器返回成功的接收的信息,不再发送通知信息
        }

      g.退款操作

        配置相应的service层,需退款调用即可:

        @Override
        public RefundResponse refund(OrderDTO orderDTO) {
            RefundRequest refundRequest = new RefundRequest();
            refundRequest.setOrderAmount(orderDTO.getOrderAmount().doubleValue());
            refundRequest.setOrderId(orderDTO.getOrderId());
            refundRequest.setPayTypeEnum(BestPayTypeEnum.WXPAY_H5);
            log.info("【微信退款】request={}",JsonUtil.toJson(refundRequest));
            RefundResponse refund = bestPayService.refund(refundRequest);
            log.info("【微信退款】response={}",JsonUtil.toJson(refund));    //收到outRefundNo表示退款成功
            return refund;
        }
  • 相关阅读:
    单用户模式启动SQL Server实例总结
    MySQL下perror工具查看System Error Code信息
    ERROR 1050 (42S01): Table xxx already exists
    RMAN-06172 Troubleshooting
    [翻译]LVM中逻辑卷的最大大小限制
    如何定位那些SQL产生了大量的redo日志
    MySQL的自动提交模式
    MySQL服务读取参数文件my.cnf的规律研究探索
    SQL Server等待事件—RESOURCE_SEMAPHORE_QUERY_COMPILE
    Azure SQL Virtual Machine报Login failed for user 'NT ServiceSqlIaaSExtension'. Reason: Could not find a login matching the name provided
  • 原文地址:https://www.cnblogs.com/shouyaya/p/13181395.html
Copyright © 2020-2023  润新知