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

ASP.NET Core 3.1 Razor Pages集成PayU后无法跳转至结果页问题

解决PayU支付后跳转RegisterConfirm.cshtml及获取交易详情的方案

一、先排查回调地址配置问题

PayU跳转失败核心原因基本是回调地址(success/failure URL)配置错误,必须满足以下要求:

  • 提交给PayU的表单里,success_url和failure_url必须是完整的绝对路径(PayU不支持相对路径),示例:
    <input type="hidden" name="success_url" value="https://你的域名/RegisterConfirm" />
    <input type="hidden" name="failure_url" value="https://你的域名/RegisterConfirm" />
    
  • 本地调试时,要用ngrok这类工具把本地端口映射为公网地址,否则PayU无法访问你的localhost页面。
  • 确认RegisterConfirm页的路由正确:Razor Pages默认路由是/页面文件名,如果有自定义路由,要和回调地址完全匹配。

二、配置RegisterConfirm页接收PayU回调参数

PayU会通过POST请求把交易详情发送到回调地址,你需要在RegisterConfirm的PageModel中处理POST请求并验证签名(防止伪造请求)。

1. RegisterConfirm.cshtml.cs 核心代码

public class RegisterConfirmModel : PageModel
{
    public TransactionResult Transaction { get; set; }

    public async Task<IActionResult> OnPostAsync()
    {
        var formData = Request.Form;
        // 先验证签名,这一步必须做
        if (!ValidatePayUSignature(formData))
        {
            Transaction = new TransactionResult { Status = "无效请求" };
            return Page();
        }

        // 提取交易核心信息
        Transaction = new TransactionResult
        {
            TransactionId = formData["txnid"],
            Status = formData["status"],
            Amount = formData["amount"],
            ProductType = formData["productinfo"],
            UserEmail = formData["email"],
            UserName = formData["firstname"]
        };

        // 可选:把交易记录保存到数据库
        // await _dbContext.PaymentTransactions.AddAsync(Transaction);
        // await _dbContext.SaveChangesAsync();

        return Page();
    }

    private bool ValidatePayUSignature(IFormCollection formData)
    {
        string merchantKey = "你的商户Key";
        string merchantSalt = "你的商户Salt";
        string receivedSignature = formData["hash"];
        string status = formData["status"];

        // 严格按照PayU文档的签名规则拼接字符串
        string hashRawString = status.Equals("success", StringComparison.OrdinalIgnoreCase)
            ? $"{merchantSalt}|{status}||||||{formData["udf5"]}|{formData["udf4"]}|{formData["udf3"]}|{formData["udf2"]}|{formData["udf1"]}|{formData["email"]}|{formData["firstname"]}|{formData["productinfo"]}|{formData["amount"]}|{formData["txnid"]}|{merchantKey}"
            : $"{merchantKey}|{formData["txnid"]}|{formData["amount"]}|{status}||||||{formData["udf5"]}|{formData["udf4"]}|{formData["udf3"]}|{formData["udf2"]}|{formData["udf1"]}|{formData["email"]}|{formData["firstname"]}|{formData["productinfo"]}|{merchantSalt}";

        // 生成SHA512哈希并对比
        using var sha512 = System.Security.Cryptography.SHA512.Create();
        byte[] hashBytes = sha512.ComputeHash(System.Text.Encoding.UTF8.GetBytes(hashRawString));
        string generatedSignature = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();

        return generatedSignature.Equals(receivedSignature, StringComparison.OrdinalIgnoreCase);
    }
}

public class TransactionResult
{
    public string TransactionId { get; set; }
    public string Status { get; set; }
    public string Amount { get; set; }
    public string ProductType { get; set; }
    public string UserEmail { get; set; }
    public string UserName { get; set; }
}

2. RegisterConfirm.cshtml 页面展示

@page
@model RegisterConfirmModel

<h2>交易结果</h2>
@if (Model.Transaction != null)
{
    <div class="result-card">
        <p><strong>交易ID:</strong> @Model.Transaction.TransactionId</p>
        <p><strong>交易状态:</strong> @(Model.Transaction.Status.Equals("success", StringComparison.OrdinalIgnoreCase) ? "<span style='color:green'>成功</span>" : "<span style='color:red'>失败</span>")</p>
        <p><strong>交易金额:</strong> @Model.Transaction.Amount</p>
        <p><strong>产品类型:</strong> @Model.Transaction.ProductType</p>
        <p><strong>用户信息:</strong> @Model.Transaction.UserName (@Model.Transaction.UserEmail)</p>
    </div>
}
else
{
    <p>无法获取交易信息,请稍后重试</p>
}

三、调试与排查要点

  • 本地调试用ngrok生成公网地址,替换回调URL中的localhost部分,确保PayU能访问到你的页面。
  • 登录PayU商户后台查看交易日志,里面会明确标注跳转失败的原因(比如地址不可达、返回404等)。
  • 如果出现404:检查RegisterConfirm的文件命名是否规范(必须是RegisterConfirm.cshtml和RegisterConfirm.cshtml.cs),路由是否正确。
  • 如果签名验证失败:检查参数拼接顺序是否和PayU文档一致,udf参数如果未使用要填空字符串,注意大小写和特殊字符的编码。

内容的提问来源于stack exchange,提问作者devman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:55:26