微信發起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;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM