1

我在 opencart 上做一个支付模块。问题是支付网关需要回调url,只能更新订单历史,浏览器刷新困难。我所做的是,在通过表单提交付款数据后,会加载 SweetAlert 窗口,显示处理时间为 40 秒。我认为这是足够的时间让用户根据他在电话上收到的提示进行付款以确认。

付款后,支付网关与我的系统通信以确认付款是否成功,如果成功则更新订单状态以确认付款失败。

我遇到的问题是 40 秒后,SweetAlert 关闭并且没有进行后续的 ajax 调用。这是我的代码:

<script>
    $(document).ready(function(){

    $(document).on('click', '#mpesaPay', function(e){

     var telephone = document.getElementById("lipanampesa_phone").value;

     SwalConfirm(telephone);
     e.preventDefault();
    });

   });

   function SwalConfirm(telephone){

      var telephone = telephone;
      var message = 'Proceed to make payment with ' + telephone + '?';
      swal({
       title: 'Confirm Mobile Number',
       text: message,
       type: 'warning',
       showCancelButton: true,
       confirmButtonColor: '#3085d6',
       cancelButtonColor: '#d33',
       confirmButtonText: 'Continue',
       showLoaderOnConfirm: true,

       preConfirm: function() {
         return new Promise(function(resolve) {

            $.ajax({
              url: 'index.php?route=extension/payment/mpesa/simulation',
              type: 'POST',
              data: $('#lipa-na-mpesa :input'),
              dataType: 'json',
              cache: false,
            })
            .done(function(response){
              swal({
                title: "Processing, Please Wait",
                text: "Check your phone NOW and enter your M-Pesa PIN to complete payment.",
                showConfirmButton: false,
                allowOutsideClick: false,
                timer: 40000,
                onOpen: function () {
                  swal.showLoading()
                }
              })
              .then(function(json){
                  $.ajax({
                          type: "post",
                          url: "index.php?route=extension/payment/mpesa/confirm",
                          data: $('#lipa-na-mpesa :input'),
                          dataType: 'json',
                          cache: false,
                      })
                      .done(function(json) {
                      if (json['success']) {
                        location = json['success'];
                      }
                      if (json['error']['warning']) {
                          swal({
                              type: 'warning',
                              title: 'Payment Failed',
                              text: 'Please restart the checkout process again or contact us if there is a problem'
                          })
                      }
                    });
                })
            })
            .fail(function(){
              swal('Oops...', 'Something went wrong with ajax !', 'error');
            });
         });
          },
       allowOutsideClick: false     
      }); 
   } 
</script>

后端代码正在成功运行以更新成功付款的订单状态。checkout/success在确认订单已付款后,我只需要一种将用户重定向到操作的方法。

这是应该在 40 秒后调用的函数,以检查订单状态并在成功时提供重定向链接

public function confirm() {

    $this->load->model('checkout/order');

    if (isset($this->request->post['order_id'])) {

        $order_info = $this->model_checkout_order->getOrder($this->request->post['order_id']);

        $order_status_id = $order_info['order_status_id'];

        if ($order_status_id == $this->config->get('payment_mpesa_order_status_id')) {
            $json['success'] = $this->url->link('checkout/success', '', true);
        } else {
            $json['error']['warning'] = 'Payment not received yet.';
        }
    } else {
        $json['error']['warning'] = 'Payment not received yet.';
    }
    return json_encode($json);
}
4

1 回答 1

0

我知道这是一个迟到的答案,但是......如果我正确理解了您的问题,那么问题在于获取服务器状态,以便您可以更新加载的网页。这是 web 开发者普遍面临的问题,问题在于 http 是一个请求响应协议,这意味着服务器必须等待客户端发出请求并响应该请求,然后才能连接关闭,服务器继续空闲等待下一个请求。结果是除非客户端请求,否则服务器无法将更新推送到客户端。

这对您来说基本上意味着您必须使用连续轮询来检查操作的状态,或者在客户端使用 websockets 并在服务器端使用发布者订阅者中间件,如 mqtt(或 AMQP?),以便服务器可以将状态更改推送到客户端将订阅的频道。

很抱歉冗长的答案和缺乏快速修复代码示例。在我看来,最快的方法是不断地使用轮询服务器直到你得到响应,但是与发布者/订阅者模型相比,这在客户端和服务器上都是资源密集型的。

于 2018-02-22T20:17:21.070 回答