C# Paypal IPN恢复为无效,不知道为什么

C# Paypal IPN恢复为无效,不知道为什么,c#,asp.net-mvc,paypal,paypal-ipn,C#,Asp.net Mvc,Paypal,Paypal Ipn,这是我的设置,我会尽量保持代码简短。这是一个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(

这是我的设置,我会尽量保持代码简短。这是一个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"
    alt="PayPal - The safer, easier way to pay online">
<img alt="" border="0" width="1" height="1"
    src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif">
然后我有一个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);
    }

让我恼火的是我被路由到paypal沙箱,我与测试用户一起登录,确认支付金额,然后单击返回站点。返回命中我的IPN操作,但我得到的响应是无效的。我是不是遗漏了一个变量?我对api还比较陌生。

您试图在本地测试这个,但是paypal不知道localhost。您必须上传代码并使用实时url进行测试。如果您试图在本地进行测试,那么paypal不知道localhost。您必须上传代码并使用实时url测试它。另一个,cmd=\u notify-validate应该是需要发送的第一个参数值

根据官方文件

验证您的响应是否包含完全相同的IPN变量和值
order,前面带有cmd=\u notify-validate。

另一个,cmd=\u notify-validate应该是需要发送的第一个参数值

根据官方文件

验证您的响应是否包含完全相同的IPN变量和值
order,前面带有cmd=\u notify-validate.

所以我要传入cmd\u xclick-subscriptions,我是否同时传入这两个,如果是,我是否放入相同的字符串?像xclick-subscriptions和notify-validate一样,您的returnURL和notifyURL是相同的。因此,当用户登录到paypal时,他们返回到与IPN ActionResult相同的URL,而您试图发回不正确的响应。请始终注意,IPN就像一个webhook,它将在稍后发送,返回URL是即时的,它提供给您在您的应用程序中结帐购物车等。Indely有两个独立的returnURL和notifyURL端点,您在returnURL端点处得到的响应不需要发布回PayPal,这只需要用于可以是notifyURL端点的IPN。因此,我正在传递cmd xclick-subscriptions,我是否同时传递这两个端点,如果是,我是否输入相同的字符串?像xclick-subscriptions和notify-validate一样,您的returnURL和notifyURL是相同的。因此,当用户登录到paypal时,他们返回到与IPN ActionResult相同的URL,而您试图发回不正确的响应。请始终注意,IPN就像一个webhook,它将在稍后发送,返回URL是即时的,它提供给您在您的应用程序中结帐购物车等。Indely有两个独立的returnURL和notifyURL端点,您在returnURL端点处得到的响应无需发布回PayPal,这仅适用于可以是notifyURL端点的IPN。返回不应影响IPN操作。只有notifyUrl应该访问IPN。return命令应该指向什么?我要将逻辑保存到数据库的视图?是否只有在IPN成功返回时才会命中返回URL?返回URL在确认付款之前命中,因此无需验证-它始终无效。您可以返回“感谢订阅”页面,但在保存任何内容之前请等待通知。哦,好的,谢谢更有意义。你说保存前等待通知?我怎样才能在我的web应用程序中订阅该通知?PayPal应该向notifyUrl发送一个单独的请求,其中包含订阅注册和付款详细信息。因此,它需要是外部可见的,而不是本地主机。我会向控制器添加更多日志记录,以便您可以查看接收到的内容。返回不应影响IPN操作。只有notifyUrl应该访问IPN。return命令应该指向什么?我要将逻辑保存到数据库的视图?是否只有在IPN成功返回时才会命中返回URL?返回URL在确认付款之前命中,因此无需验证-它始终无效。您可以返回“感谢订阅”页面,但在保存任何内容之前请等待通知。哦,好的,谢谢更有意义。你说保存前等待通知?我怎样才能在我的web应用程序中订阅该通知?PayPal应该向notifyUrl发送一个单独的请求,其中包含订阅注册和付款详细信息。因此,它需要是外部可见的,而不是本地主机。我会向控制器添加更多日志记录,以便您可以查看接收到的内容。
//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);
    }