You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Stripe支付完成后页面不刷新/跳转问题求助

Stripe支付完成后无跳转且无支付记录问题排查

问题现象

点击Stripe支付按钮弹出窗口,输入银行卡信息并点击支付后,窗口显示绿色对勾,但页面无反应。Stripe后台无支付记录,银行卡未扣款,本该跳转到带$calback_url参数的URL,却仅显示灰色按钮,需手动刷新页面。

现有代码

Smarty模板嵌入的Stripe按钮代码

<div>
    <!-- Stripe -->
        <form action="/payment.php?custom=1&sum={$sum*100}" method="POST">
            <script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
                data-key="pk_live_xxxxxxxxx"
                data-amount="{$sum*100}"
                data-description="payment"
                data-locale="auto"
                data-zip-code="true">
            </script>
                                                                          
        </form>
        <div style="font-size: 10px; padding: 0 0 0 22px">powered by <a href="https://stripe.com/" target="_blank" rel="nofollow">stripe</a></div>
</div>

支付处理文件payment.php代码

if($_REQUEST['stripeToken']) {
    
    require_once('stripe_4/init.php');
    
    try {
      // Use Stripe's library to make requests...
      
        \Stripe\Stripe::setApiKey("sk_live_xxxxxxxxxx");

        $token = $_REQUEST['stripeToken'];

        if ($_GET['custom'] == 1) {
            $price = $_GET['sum'];
            $calback_url = 'ppdpam';
            $description = "Custom payment";
        }
        else {
            $_SESSION['stripe_error_message'] = "Wrong parameters!";
            header("Location: https://".SITE."/data.php?er=100$parameter");
            exit;
        }
        
        // Charge the user's card:
        $charge = \Stripe\Charge::create(array(
          "amount" => $price,
          "currency" => "usd",
          "description" => $description,
          "source" => $token,
        ));
        
    } catch(\Stripe\Error\Card $e) {
      // Since it's a decline, \Stripe\Error\Card will be caught
      $body = $e->getJsonBody();
      $err  = $body['error'];
    
      print('Status is:' . $e->getHttpStatus() . "\n");
      print('Type is:' . $err['type'] . "\n");
      print('Code is:' . $err['code'] . "\n");
      // param is '' in this case
      print('Param is:' . $err['param'] . "\n");
      print('Message is:' . $err['message'] . "\n");
      
      $_SESSION['stripe_error_message'] = $e->getMessage();
      header("Location: /data.php?er=1$parameter");
      exit;
    
    header("Location: https://".SITE."/data.php?".$calback_url);
    exit;
}

问题根源与修复方案

1. 跳转逻辑异常

  • 问题: 成功支付后的跳转语句被放在catch块之后,但仅捕获了\Stripe\Error\Card类错误,其他异常(如API密钥错误、参数非法、网络故障)会直接终止代码执行,无法触发跳转;同时catch块内的print语句会输出内容,导致后续header跳转失效(HTTP响应头必须在输出内容前发送)。
  • 修复:
    • 增加全局异常捕获,覆盖所有Stripe错误和PHP异常;
    • 删除catch块内的print语句,改用$_SESSION存储错误信息后直接跳转;
    • 将成功跳转语句移到try块内部,确保支付成功后立即执行。

2. 参数问题

  • 问题: 依赖URL中的$_GET参数易被篡改,且$parameter变量未定义,导致跳转URL拼接错误;未对$price做合法性校验,存在安全风险。
  • 修复:
    • 将自定义参数放入表单隐藏域,统一通过POST获取;
    • 移除未定义的$parameter变量;
    • 增加参数校验逻辑,确保$price为合法正整数。

3. 代码优化后的完整版本

优化后的Smarty模板代码

<div>
    <!-- Stripe -->
    <form action="/payment.php" method="POST">
        <!-- 隐藏域传递自定义参数,避免URL篡改 -->
        <input type="hidden" name="custom" value="1">
        <input type="hidden" name="sum" value="{$sum*100}">
        <script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
            data-key="pk_live_xxxxxxxxx"
            data-amount="{$sum*100}"
            data-description="payment"
            data-locale="auto"
            data-zip-code="true">
        </script>
    </form>
    <div style="font-size: 10px; padding: 0 0 0 22px">powered by <a href="https://stripe.com/" target="_blank" rel="nofollow">stripe</a></div>
</div>

优化后的payment.php代码

session_start(); // 确保开启Session,用于存储错误信息

if(isset($_REQUEST['stripeToken'])) {
    require_once('stripe_4/init.php');
    
    try {
        \Stripe\Stripe::setApiKey("sk_live_xxxxxxxxxx");
        $token = $_REQUEST['stripeToken'];
        
        // 获取并校验参数
        $custom = isset($_POST['custom']) ? intval($_POST['custom']) : 0;
        $price = isset($_POST['sum']) ? intval($_POST['sum']) : 0;
        
        if ($custom !== 1 || $price <= 0) {
            $_SESSION['stripe_error_message'] = "非法参数!";
            header("Location: https://".SITE."/data.php?er=100");
            exit;
        }
        
        $calback_url = 'ppdpam';
        $description = "Custom payment";
        
        // 创建Charge
        $charge = \Stripe\Charge::create([
            "amount" => $price,
            "currency" => "usd",
            "description" => $description,
            "source" => $token,
        ]);
        
        // 支付成功跳转
        header("Location: https://".SITE."/data.php?".$calback_url);
        exit;
        
    } catch(\Stripe\Error\Card $e) {
        // 银行卡相关错误处理
        $body = $e->getJsonBody();
        $_SESSION['stripe_error_message'] = $body['error']['message'];
        header("Location: /data.php?er=1");
        exit;
    } catch(\Stripe\Error\Base $e) {
        // 其他Stripe API错误处理
        $_SESSION['stripe_error_message'] = "支付接口错误:".$e->getMessage();
        header("Location: /data.php?er=2");
        exit;
    } catch(Exception $e) {
        // 全局异常处理
        $_SESSION['stripe_error_message'] = "系统错误:".$e->getMessage();
        header("Location: /data.php?er=99");
        exit;
    }
} else {
    // 无合法支付令牌,直接跳转错误页
    $_SESSION['stripe_error_message'] = "无效请求!";
    header("Location: /data.php?er=0");
    exit;
}

内容的提问来源于stack exchange,提问作者S.I.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 08:48:14