【发布时间】: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"
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">
我在控制器中设置变量:
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 发送单独的请求,其中包含订阅注册和付款详细信息。所以它需要是外部可见的,而不是本地主机。我会向控制器添加更多日志记录,以便您查看收到的内容。
标签: c# asp.net-mvc paypal paypal-ipn