c# - PayPal IPN 不发送通知
问题描述
我目前正在使用 PayPal 在线支付系统开发应用程序,并且 PayPal IPN 消息系统在单击“支付”按钮时未发送通知。
我使用“智能支付按钮”( https://developer.paypal.com/docs/checkout/# )实现了“PayPal Checkout” 。我创建了一个 PayPal 沙盒业务帐户,当我通过我的应用程序登录时我会使用该帐户进行测试。使用此帐户进行测试时,我从 PayPal 获取所需的数据(订单 ID、金额、帐户用户名等)并将其插入数据库中。到目前为止一切正常,但我需要确认以确保(以防网页因某种原因冻结或关闭)当用户通过 PayPal 支付交易时,数据库中的数据已正确更新。
我决定实施 PayPal IPN(即时付款通知),这是一个消息系统,用于通知您与 PayPal 交易相关的事件(https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/)。我使用了提供的示例代码并对其进行了修改以适合我的应用程序(https://github.com/paypal/ipn-code-samples/blob/master/C%23/paypal_ipn_mvc_core.cs)。我使用 Postman 应用程序并发送了一个示例 IPN 消息(https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/#ipn-protocol-and-architecture) 到我的 IPN 监听器,它起作用了。对于最后一步,我使用本地代码在开发环境中发布,并使用 Postman 对其进行了测试,它工作正常。现在问题就从这里开始了,我使用 PayPal 按钮使用之前创建的沙盒帐户支付交易,但我没有收到来自 PayPal 的 IPN。我还使用 IPN 模拟器 ( https://developer.paypal.com/developer/ipnSimulator/ ) 从 PayPal 发送消息,我收到了 PayPal 网站上显示的“IPN 已发送且握手已验证”但数据未在数据库中更新。当我检查 PayPal 网站中的 IPN 历史记录以检查是否在某个时间发送了 IPN 时,它是空的(没有发送 IPN 消息)。我的应用程序现在所在的这个开发环境位于 Azure 门户中。
[HttpPost]
public IActionResult Receive()
{
PayPalRaw payPalRaw = new PayPalRaw();
PayPalRaw payPalRaw1 = new PayPalRaw();
try
{
// Get the received request's headers
var requestheaders = HttpContext.Request.Headers["someKey"].ToString();
payPalRaw.HeadersRaw = requestheaders.ToString();
IPNContext ipnContext = new IPNContext()
{
IPNRequest = Request
};
//payPalRaw.HeadersRaw = ipnContext.Verification;
using (StreamReader reader = new StreamReader(ipnContext.IPNRequest.Body, Encoding.ASCII))
{
ipnContext.RequestBody = reader.ReadToEnd();
//payPalRaw.BodyRaw = ipnContext.IPNRequest.Body.ToString();
payPalRaw.BodyRaw = ipnContext.RequestBody.ToString();
}
_context.Add(payPalRaw);
_context.SaveChangesAsync();
//Store the IPN received from PayPal
LogRequest(ipnContext);
//Fire and forget verification task
Task.Run(() => VerifyTask(ipnContext));
//Reply back a 200 code
return Ok();
}
catch (Exception ex)
{
payPalRaw1.HeadersRaw = ex.Message.ToString();
payPalRaw1.BodyRaw = ex.Message.ToString();
}
_context.Add(payPalRaw1);
_context.SaveChanges();
return StatusCode(200);
}
private void VerifyTask(IPNContext ipnContext)
{
try
{
var verificationRequest = WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr");
//Set values for the verification request
verificationRequest.Method = "POST";
verificationRequest.ContentType = "application/x-www-form-urlencoded";
//Add cmd=_notify-validate to the payload
string strRequest = "cmd=_notify-validate&" + ipnContext.RequestBody;
verificationRequest.ContentLength = strRequest.Length;
//Attach payload to the verification request
using (StreamWriter writer = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII))
{
writer.Write(strRequest);
}
//Send the request to PayPal and get the response
using (StreamReader reader = new StreamReader(verificationRequest.GetResponse().GetResponseStream()))
{
ipnContext.Verification = reader.ReadToEnd();
}
}
catch (Exception exception)
{
//Capture exception for manual investigation
}
ProcessVerificationResponse(ipnContext);
}
private void LogRequest(IPNContext ipnContext)
{
// Persist the request values into a database or temporary data store
}
private void ProcessVerificationResponse(IPNContext ipnContext)
{
if (ipnContext.Verification.Equals("VERIFIED"))
{
// check that Payment_status=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
}
else if (ipnContext.Verification.Equals("INVALID"))
{
//Log for manual investigation
}
else
{
//Log error
}
}
我想我错过了我的 PayPal 帐户中的一些配置或设置,或者 PayPal IPN 正在等待来自侦听器的某种握手以完成该过程。
解决方案
推荐阅读
- reactjs - 如何加载 .xlsx 文件并显示其数据?
- apache-spark - 如何处理(Apache Beam)高 IO 瓶颈?
- sql - 如何从 DAM 中获取 AEM 页面中使用的所有图像的列表
- java - Azure CosmosDB Java Springboot 中的无服务器帐户不支持在容器上设置优惠吞吐量或自动驾驶仪
- wordpress - 使用 WP Rocket 优化后,我的滑块革命无法正常工作
- sql-server - 由于 DELETE 语句(SQL Server)上的索引而导致死锁
- python - 匹配不包含点且不是 IP 正则表达式的单词
- mysql - 在 SQL SELECT 查询中包含字符串是什么意思
- node.js - 从 Express 中间件在整个节点应用程序中共享令牌
- java - Spring Data Elasticsearch 4.2.x:DateFormat 抛出空指针