首页 > 解决方案 > 与支付网关联系时延迟 PHP 代码一段时间

问题描述

我正在开发一个 Laravel PHP 项目,通过该项目我联系支付 API 以检查用户是否已支付的状态并将用户重定向到支付确认页面。

默认情况下,支付网关的支付状态为 0。当用户支付时,状态变为 1。用户点击网站上的支付按钮后,我需要延迟 PHP 代码的执行(让用户有时间进行交易通过他/她的电话付款)。

15 秒后,我联系支付网关检查状态是否已更改为 1,如果为真,则将用户重定向到支付确认页面。

我曾尝试使用睡眠,但它不起作用......我还在支付时使用沙盒帐户进行了测试,但在 15 秒后它没有按预期重定向。

我从 API 获得的示例 JSON 对象,具体取决于付款状态

//When not paid
{
    status: 0,
    message: 'Not Paid',
    amount: 20
}

//When paid
{
    status: 1,
    message: 'Paid',
    amount: 20
}

//When cancelled
{
    status: 2,
    message: 'Cancelled',
    amount: 20
}

AJAX 代码用于将数据发布到控制器

<script type="text/javascript">
  //Mpesa Payment code
$('.mpesa').on('click', function () {

    //Gets the MPESA type
    var type = $('.mpesa').prop('id');
    var quote = $('#quote').val();
    var phone = $('#phone').val();
    //Converts to a JSON object
    var type ={
      'type': type,
      'quote' : quote,
      'phone' : phone,
    };

    console.log(type);

    $.ajax({
        //Contains controller of payment
        type: 'POST',
        url: 'paymentFinal',
        data: JSON.stringify(type),
        contentType: 'application/json',
        dataType: "json",
        success: function success(response) {
            window.location.href="success" ;
        },
        error: function error(data) {
            console.log(data);
        }
    });
});
//End Payment API

Laravel 控制器正在从上面的 AJAX 代码发布数据

 public
    function payFinal(Request $request)
    {
        // dd($request->all());

         //Convert to a JSON object the request 
        $data =(object)$request->all();

        //Session get of some data fetched from another controller
        $quote = $request->session()->get('quoteID');

        //Store all the data in an array
         $all = array(
            'phone' => $data->phone,
            'quote_id' => $quote,
            'payment_type' => $data->type,
        );

        //Posts data to Payment Checkout using curl
        $response = $this->global_Curl($all, 'api/payment/checkout');
        //dd($response);

        //Get checkoutresponseId from response
        $checkID = $response->data->CheckoutRequestID;

        //Payment type
        $type = $data->type;

        $data = array(
            'payment_reference' => $checkID,
            'payment_type' => $type
        );

        //1st call to the Payment API before sleep
        $paySt = $this->global_Curl($data, 'api/payment/status')->data;

        sleep(15);

        //Second call to the API after sleep to check if status has changed
        $payStat = $this->global_Curl($data, 'api/payment/status')->data;

        if($payStat->status == '1'){
            return 'true';   
        }
    }

正在使用新的 AJAX 代码

$('.mpesa').on('click', function () {
    setInterval(function() {
       alert('clicked');
      //Gets the MPESA type
       var type = $('.mpesa').prop('id');
      var quote = $('#quote').val();
      var phone = $('#phone').val();
      //Converts to a JSON object
      var type ={
        'type': type,
        'quote' : quote,
        'phone' : phone,
      };

    console.log(type);
    $.ajax({
        //Contains controller of payment
        type: 'POST',
        url: 'paymentFinal',
        data: JSON.stringify(type),
        contentType: 'application/json',
        dataType: "json",
        success: function success(response) {
          if(response) {
              window.location.href="success";
          }
        },
        error: function error(data) {
            console.log(data);
        }
    });
}, 15000); // Execute every 15 seconds
});

标签: phplaravelsleeppayment-processing

解决方案


好的,让我们分解你的问题。首先,您希望延迟 AJAX 代码每 15 秒执行一次。为此,您将 AJAX 包装在setInterval()javascript 方法中。所以它最终应该看起来像这样:

setInterval(function() {
    $.ajax({
        //Contains controller of payment
        type: 'POST',
        url: 'paymentFinal',
        data: JSON.stringify(type),
        contentType: 'application/json',
        dataType: "json",
        success: function success(response) {
            window.location.href="success" ;
        },
        error: function error(data) {
            console.log(data);
        }
    });
}, 15000); // Execute every 15 seconds

接下来,您想根据代码返回的状态做一些事情。为此,您需要将 AJAX 方法的成功案例更改为以下内容:

    success: function success(response) {
        if(response) {
            window.location.href="success"
        }
    }

这就是javascript方面的内容。对于 PHP 端,您可以删除它,因为您现在正在前端处理间隔:

    sleep(15);

    //Second call to the API after sleep to check if status has changed
    $payStat = $this->global_Curl($data, 'api/payment/status')->data;

并将返回类型从字符串更改为布尔值:

if($payStat->status == 1){
        return response()->json(true);   // Sends back a JSON response to your AJAX
    }

那应该做你想做的事。

现在,对您的代码提出一些建议:

  • 您可能希望为更多的案例做出规定,而不仅仅是成功的 AJAX 案例
  • 确保在用户单击付款按钮时禁用该按钮,否则每次按下它都会开始一个新的 15 秒间隔
  • 尝试将您的 PHP 代码包装在 try-catch 块中以允许优雅的错误处理
  • 为成功案例做准备

推荐阅读