Paypal IPN 无效返回,不知道为啥

Posted

技术标签:

【中文标题】Paypal IPN 无效返回,不知道为啥【英文标题】:Paypal IPN is coming back as invalid and don't know whyPaypal IPN 无效返回,不知道为什么 【发布时间】:2012-12-01 20:05:55 【问题描述】:

这是我的设置,我会尽量保持代码简短。这是一个 ASP.NET MVC4 应用程序

我在这里设置信息:

    @html.Hidden("cmd", Model.PayPal.Cmd)
@Html.Hidden("business", Model.PayPal.Business)
@Html.Hidden("return", Model.PayPal.Return)
@Html.Hidden("cancel_return", Model.PayPal.CancelUrl)
@Html.Hidden("notify_url", Model.PayPal.NotifyUrl)
@Html.Hidden("currency_code", Model.PayPal.CurrencyCode)
@Html.Hidden("item_name", Model.PayPal.PlanName)
@Html.Hidden("item_number", Model.Id)

@Html.Hidden("src", Model.PayPal.AutoRecurring)
@Html.Hidden("a3", Model.PayPal.Price)
@Html.Hidden("p3", Model.PayPal.Interval)
@Html.Hidden("t3", Model.PayPal.IntervalType)
@Html.Hidden("txn_type", "subscr_signup")
<input type="image" name="submit"
    src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribe_LG.gif"
    >
<img  border="0"  
    src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif">

我在控制器中设置变量:

PayPal paypal = new PayPal();
        bool useSanbox = true;

        if (useSanbox)// for test
            paypal.ActionUrl = "https://www.sandbox.paypal.com/cgi-bin/webscr";
        else//real
            paypal.ActionUrl = "https://www.paypal.com/cgi-bin/webscr";

        paypal.Cmd = "_xclick-subscriptions";
        paypal.Business = "david_1355300634_biz@domain.com";
        paypal.CancelUrl = "http://localhost:25914/home/";
        paypal.Return = "http://localhost:25914/home/ipn";
        paypal.NotifyUrl ="http://localhost:25914/home/ipn";
        paypal.AutoRecurring = "1";
        paypal.Price = ctx.SubscriptionPlans.First(x => x.Name == signInModel.SubscritionPlan).Price.ToString();
        paypal.Interval = "1";
        paypal.IntervalType = "M";
        paypal.CurrencyCode = "USD";
        paypal.PlanName = signInModel.SubscritionPlan;
        paypal.Amount = ctx.SubscriptionPlans.First(x => x.Name == signInModel.SubscritionPlan).Price.ToString();

然后我有这个 IPN 控制器操作:

//Answer from PayPal
    public ActionResult IPN()
    
        var signInModel = Session["SignUp"] as SignUp;
        //Post back to either sandbox or live
        string strSandbox = "https://www.sandbox.paypal.com/cgi-bin/webscr";
        //string strLive = "https://www.paypal.com/cgi-bin/webscr";
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strSandbox);

        //Set values for the request back
        req.Method = "POST";
        req.ContentType = "application/x-www-form-urlencoded";
        byte[] param = Request.BinaryRead(this.Request.ContentLength);
        string strRequest = Encoding.ASCII.GetString(param);
        strRequest += "&cmd=_notify-validate";
        req.ContentLength = strRequest.Length;

        //Send the request to PayPal and get the response
        StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
        streamOut.Write(strRequest);
        streamOut.Close();
        StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
        string strResponse = streamIn.ReadToEnd();
        streamIn.Close();

        if (strResponse == "VERIFIED")
        
            //any param from form
            var text = Request.Form["custom"];
            ctx.SignIns.Add(signInModel);
            ctx.SaveChanges();
            //check the payment_status is Completed
            //check that txn_id has not been previously processed
            //check that receiver_email is your Primary PayPal email
            //check that payment_amount/payment_currency are correct
            //process payment
            return View("RegistrationConfirmation", signInModel);
        
        else if (strResponse == "INVALID")
        
            //log for manual investigation
            return View("SignUp", signInModel);
        
        else
        
            //log response/ipn data for manual investigation
        
        //change view
        return View("SignUp", signInModel);
    

让我失望的是我很好地被路由到了贝宝沙箱,我用一个测试用户登录,确认支付金额,然后点击返回网站。返回会命中我的 IPN 操作,但我得到的响应是“无效”。我在这里错过了一个变量还是什么?我对 api 比较陌生。

【问题讨论】:

返回不应该点击 IPN 操作。只有 notifyUrl 应该访问 IPN。 return 命令应该去哪里?我有我的逻辑保存到数据库的视图?如果 IPN 返回成功,它是否只命中返回 URL? 在确认付款之前点击返回网址,因此无需验证 - 它总是无效的。您可以返回“感谢您的订阅”页面,但在保存任何内容之前等待通知。 哦,好的,谢谢更有意义。所以你说在保存前等待通知?如何在我的 Web 应用程序中订阅该通知? PayPal 应向 notifyUrl 发送单独的请求,其中包含订阅注册和付款详细信息。所以它需要是外部可见的,而不是本地主机。我会向控制器添加更多日志记录,以便您查看收到的内容。 【参考方案1】:

另外一个,cmd=_notify-validate 应该是需要发送的第一个参数值。

根据官方文档

"验证您的响应是否包含完全相同的 IPN 变量和值 顺序,以 cmd=_notify-validate 开头。”

【讨论】:

所以我传入了 cmd _xclick-subscriptions,我是否同时传入两者,如果是,我是否输入相同的字符串?像 _xclick-subscriptions&_notify-validate? 你的 returnURL 和 notifyURL 是一样的。因此,当他们登录到贝宝的用户时,他们会返回与 IPN (ActionResult) 相同的 URL,并且您正在尝试发回不正确的响应。请始终注意,IPN 就像一个 webhook,它将在稍后发送,因为返回 URL 是即时的,并且它提供给您在您的应用程序中结帐购物车等。实际上,returnURL 和 notifyURL 有 2 个单独的端点,并且您在 returnURL 端点获得的响应不需要发回 PayPal,这仅需要 IPN(可以是 notifyURL 端点)。【参考方案2】:

您正在尝试在本地进行测试,好吧,paypal 不知道本地主机。您必须上传代码并使用实时 url 对其进行测试

【讨论】:

以上是关于Paypal IPN 无效返回,不知道为啥的主要内容,如果未能解决你的问题,请参考以下文章

无论我做啥,PayPal IPN 都会不断返回“无效”代码

Paypal 沙盒 IPN 返回无效

nodejs - 无法让 paypal-ipn 工作。 Paypal 不断返回“无效”

PayPal IPN 在沙箱中返回无效

Paypal ipn 未验证:无效

Paypal IPN 总是返回 INVALID