我在我的应用程序中实现 CoinPayments IPN,我无法将数据传递给接受回调的方法。我已经尝试了所有我能找到的东西:TempData、SessionVariables,试图在表单的某个地方实现它,也许请求它,但这对我不起作用。所以我也尝试用全局静态变量来实现它。它奏效了!但随之而来的另一个问题是:如果多个用户同时从网站上购买东西,或者甚至在任何回调之间,他们的数据就会混杂在一起。所以我在这里,再次尝试使会话变量工作并且不知道为什么它们不像我以前使用它们那样工作。可能我能想到的是,因为它是来自 CoinPayments 的回调,而我处理错误。
这是我现在拥有的代码:尽管我尝试了不同的变体,例如在 Get Payment 方法中实现 Session。现在我结束了它,它在 POST METHOD 中仍然显示为空。
处理会话变量的类:
public static class MyGlobalVariables
{
public static int TokenChoice
{
get
{
if (System.Web.HttpContext.Current.Session["TokenChoice"] == null)
{
return -1;
}
else
{
return (int)System.Web.HttpContext.Current.Session["TokenChoice"];
}
}
set
{
System.Web.HttpContext.Current.Session["TokenChoice"] = value;
}
}
public static int PaymentChoice
{
get
{
if (System.Web.HttpContext.Current.Session["PaymentChoice"] == null)
{
return -1;
}
else
{
return (int)System.Web.HttpContext.Current.Session["PaymentChoice"];
}
}
set
{
System.Web.HttpContext.Current.Session["PaymentChoice"] = value;
}
}
public static string CurrentUser
{
get
{
System.Web.HttpContext.Current.Session["CurrentUser"] = System.Web.HttpContext.Current.User.Identity.Name;
return (string)System.Web.HttpContext.Current.Session["CurrentUser"];
}
}
}
返回单击 CoinPayments 按钮的视图的类:
public ActionResult Payment(int tokenChoice, int paymentChoice)
{
ViewBag.Payment = paymentChoice;
MyGlobalVariables.PaymentChoice = paymentChoice;
MyGlobalVariables.TokenChoice = tokenChoice;
return View();
}
处理来自 CoinPayments 的回调的回调类:
[HttpPost]
public ActionResult Payment()
{
NameValueCollection nvc = Request.Form;
var merchant_id = id;
var ipn_secret = secret;
var order_total = MyGlobalVariables.PaymentChoice;
if (String.IsNullOrEmpty(nvc["ipn_mode"]) || nvc["ipn_mode"] != "hmac")
{
Trace.WriteLine("IPN Mode is not HMAC");
return View();
}
if (String.IsNullOrEmpty(HTTP_HMAC))
{
Trace.WriteLine("No HMAC signature sent");
return View();
}
if (String.IsNullOrEmpty(nvc["merchant"]) || nvc["merchant"] != merchant_id.Trim())
{
Trace.WriteLine("No or incorrect Merchant ID passed");
return View();
}
//var hmac = hash_hmac("sha512", request, ipn_secret.Trim());
var txn_id = nvc["txn_id"];
var item_name = nvc["item_name"];
var item_number = nvc["item_number"];
var amount1 = nvc["amount1"];
var amount2 = float.Parse(nvc["amount2"], CultureInfo.InvariantCulture.NumberFormat);
var currency1 = nvc["currency1"];
var currency2 = nvc["currency2"];
var status = Convert.ToInt32(nvc["status"]);
var status_text = nvc["status_text"];
Trace.WriteLine(status);
if (currency1 != "USD") {
Trace.WriteLine("Original currency mismatch!");
return View();
}
if (Convert.ToInt32(amount1) < Convert.ToInt32(order_total))
{
Trace.WriteLine("Amount is less than order total!");
return View();
}
if (status >= 100 || status == 2) {
using (MyDatabaseEntities1 dc = new MyDatabaseEntities1())
{
var account = dc.Users.Where(a => a.Username == MyGlobalVariables.CurrentUser).FirstOrDefault();
if (account != null && account.Paid == 0)
{
Trace.WriteLine("Payment Completed");
Trace.WriteLine("Tokens to add: " + MyGlobalVariables.TokenChoice);
account.Tokens += MyGlobalVariables.TokenChoice;
account.Paid = 1;
dc.Configuration.ValidateOnSaveEnabled = false;
dc.SaveChanges();
}
}
} else if (status < 0)
{
Trace.WriteLine(
"payment error, this is usually final but payments will sometimes be reopened if there was no exchange rate conversion or with seller consent");
} else {
using (MyDatabaseEntities1 dc = new MyDatabaseEntities1())
{
var account = dc.Users.Where(a => a.Username == MyGlobalVariables.CurrentUser).FirstOrDefault();
if (account != null)
{
account.Paid = 0;
dc.Configuration.ValidateOnSaveEnabled = false;
dc.SaveChanges();
}
}
Trace.WriteLine("Payment is pending");
}
return View();
}
如您所见,我只需要处理 3 个变量。也有人可能会问为什么我为 Current.User 使用会话变量?好吧,由于某种原因,回调方法无法读取 Current.User,因为它返回 null。嗯……现在没有什么真正改变。
如果您曾经经历过类似的事情或可以找到问题,我将非常感激,因为我已经在该问题上浪费了 2 天多的时间。
编辑:经过一些测试,我发现如果我自己运行 Post 方法,变量可以正常工作。所以问题在于处理来自 CoinPayments 的回调。有没有具体的方法来处理这个问题?