ASP.NET Core中PayPal IPN无法获取交易ID等信息求助
解决ASP.NET Core中PayPal IPN回调无法获取参数的问题
我之前把PayPal IPN从ASP.NET MVC5迁移到Core的时候也踩过一模一样的坑!核心原因其实很简单:PayPal的IPN回调是POST请求,你用Request.Query去拿参数肯定拿不到——Request.Query是用来读取URL上的查询字符串的,而IPN的所有参数都放在POST请求的表单体里,和MVC5里Request["键名"]对应的应该是ASP.NET Core里的Request.Form或者模型绑定。
下面给你两种可行的解决方法:
方法一:直接读取Form表单数据
在你的IPN回调Action里,直接通过Request.Form获取对应的参数,代码示例如下:
[HttpPost] [IgnoreAntiforgeryToken] // 重要:PayPal IPN不带CSRF令牌,必须禁用验证 public async Task<IActionResult> PayPalIPN() { // 从POST表单中提取IPN参数 var txnId = Request.Form["txn_id"].FirstOrDefault(); var mcGross = Request.Form["mc_gross"].FirstOrDefault(); var customOrderId = Request.Form["custom"].FirstOrDefault(); // 这里保留你已有的IPN验证逻辑(你已经能拿到VERIFIED响应) if (/* 你的验证逻辑返回VERIFIED */) { // 处理交易逻辑,比如更新订单状态、记录交易信息 if (!string.IsNullOrEmpty(txnId) && !string.IsNullOrEmpty(mcGross)) { // 你的业务代码... } } // PayPal要求必须返回空的200响应,否则会重复发送IPN return Ok(); }
注意:Request.Form返回的是IFormCollection,每个键可能对应多个值,所以用FirstOrDefault()来获取单个参数值更安全,避免空引用异常。
方法二:使用模型绑定(更优雅的方式)
如果需要获取的IPN参数比较多,推荐创建一个专门的模型类,让ASP.NET Core自动帮你绑定参数,代码更整洁:
首先定义IPN模型:
public class PayPalIPNRequest { public string txn_id { get; set; } public string mc_gross { get; set; } public string custom { get; set; } // 可以根据需求添加其他IPN字段,比如payment_status、payer_email等 }
然后在Action中直接接收模型:
[HttpPost] [IgnoreAntiforgeryToken] public async Task<IActionResult> PayPalIPN(PayPalIPNRequest ipnRequest) { if (ModelState.IsValid) { // 直接从模型中读取参数 var txnId = ipnRequest.txn_id; var mcGross = ipnRequest.mc_gross; var customOrderId = ipnRequest.custom; // 验证和业务逻辑... } return Ok(); }
关键注意事项
- 务必给Action标记
[HttpPost]:ASP.NET Core默认不会自动映射POST请求到无特性的Action,必须明确指定。 - 禁用CSRF验证:PayPal的IPN回调不会携带你的站点CSRF令牌,所以必须给该Action添加
[IgnoreAntiforgeryToken],否则会返回400错误。 - 返回正确响应:处理完成后一定要返回
Ok()(空的200状态码响应),PayPal如果收不到这个响应,会在接下来的几天内重复发送IPN回调。
内容的提问来源于stack exchange,提问作者pitaridis
相关产品推荐
相关产品推荐

