PAYATHON 2026

Paylike popup 支付成功后如何 redirect 用户

支付小周

结论

重定向代码没有执行,是因为回调函数只声明了 err,后面却使用了未定义的变量 r:

console.log(r);

这行代码会抛出 ReferenceError: r is not defined,当前函数也会随之终止,所以后面的 location.href 不会运行。把支付结果参数加入回调函数即可解决。

修改后的代码

var paylike = Paylike('f0301d1f-db00-4dc6-9df3-29f8822d56f6');

function pay() {
    paylike.popup({
        currency: 'HUF',
        amount: 10000
    }, function (err, r) {
        if (err) {
            console.warn(err);
            return;
        }

        console.log(r); // { transaction: { id: ... } }

        window.location.href = 'payment-ok.php';
    });
}

如果不想让用户在跳转后通过浏览器的“后退”按钮返回支付页,可以改用:

window.location.replace('payment-ok.php');

为什么原代码没有生效

JavaScript 会按顺序执行回调函数中的语句。原代码执行到:

console.log(r);

时,r 并未在回调参数或其他作用域中定义。浏览器因此报错并停止执行当前函数,下一行重定向代码也就没有机会运行。

可以打开浏览器开发者工具的 Console 面板,查看是否出现类似错误:

Uncaught ReferenceError: r is not defined

建议先检查返回结果

跳转前,最好先确认交易结果中包含交易 ID:

paylike.popup({
    currency: 'HUF',
    amount: 10000
}, function (err, r) {
    if (err) {
        console.error('Payment failed or popup was closed:', err);
        return;
    }

    if (!r || !r.transaction || !r.transaction.id) {
        console.error('Missing transaction data:', r);
        return;
    }

    var transactionId = r.transaction.id;

    window.location.href =
        'payment-ok.php?transaction_id=' +
        encodeURIComponent(transactionId);
});

但不能仅凭前端传入的 transaction_id 判断订单已经安全付款,因为用户可以修改查询参数。

支付状态应由服务端确认

更稳妥的处理流程如下:

  1. Paylike popup 返回交易 ID。
  2. 前端把交易 ID 发送给自己的服务端。
  3. 服务端通过 Paylike 提供的服务端接口核验或处理交易。
  4. 服务端确认成功后更新订单状态。
  5. 前端跳转到支付成功页面。

示意代码:

paylike.popup({
    currency: 'HUF',
    amount: 10000
}, async function (err, r) {
    if (err) {
        console.warn(err);
        return;
    }

    if (!r?.transaction?.id) {
        console.error('Invalid transaction response:', r);
        return;
    }

    try {
        var response = await fetch('confirm-payment.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                transactionId: r.transaction.id
            })
        });

        if (!response.ok) {
            throw new Error('Server confirmation failed');
        }

        var result = await response.json();

        if (result.success) {
            window.location.replace('payment-ok.php');
        } else {
            console.error('Payment was not confirmed:', result);
        }
    } catch (error) {
        console.error(error);
    }
});

confirm-payment.php 的具体写法取决于所用的 Paylike API 版本和服务端语言,请以相应版本的接口文档为准。私钥或服务端凭据不能放在浏览器端的 JavaScript 中。

注意事项

  • 回调返回交易结果后,仍应由服务端确认订单的最终状态。
  • 如果用户关闭窗口、支付失败或出现网络错误,err 可能会有值,此时不应跳转到成功页。
  • amount: 10000 通常采用货币的最小单位,但具体规则可能因货币和接口而异,需要根据当前 Paylike 配置确认。
  • 如果示例中的公开 key 属于真实生产环境,建议检查它的用途和暴露范围。所有私密凭据都必须保存在服务端。
  • 最小改动是把回调改成 function (err, r)。问题不在 location.href,而在它前面的未定义变量错误。

备注:内容仅供参考。