我无法让 paypal 通过 webhooks 模拟器验证 webhook 请求。我的VerifyTask 和示例之间的唯一区别是我从webclient 转换为HttpClient。此代码与 paypal 站点中的示例 ipn 侦听器非常接近。以下是c# asp.net代码:
public class IPNSendBack
{
public HttpRequest? IPNRequest { get; set; }
public string? RequestBody { get; set; }
public string? Verification { get; set; }
}
[AllowAnonymous]
[HttpPost()]
public async Task<IActionResult> ReceiveWebHook()
{
var headers = HttpContext.Request.Headers;
string transmissionid = headers["Paypal-Transmission-Id"].ToString();
IPNSendBack ipnContext = new IPNSendBack()
{
IPNRequest = Request
};
using (StreamReader reader = new StreamReader(ipnContext.IPNRequest.Body, Encoding.ASCII))
{
ipnContext.RequestBody = await reader.ReadToEndAsync();
}
await Task.Run(() => VerifyTask(ipnContext, transmissionid));
}
private async Task VerifyTask(IPNSendBack ipnContext, string? transmissionid)
{
string url = isSandbox
? "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr"
: "https://ipnpb.paypal.com/cgi-bin/webscr";
using (HttpClient client = new HttpClient())
{
// Set values for the verification request
var content = new StringContent($"cmd=_notify-validate&{ipnContext.RequestBody}", Encoding.ASCII, "application/x-www-form-urlencoded");
// Send the request to PayPal and get the response
HttpResponseMessage response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode(); // Ensure successful response
if (response.IsSuccessStatusCode)
{
string verificationResult = await response.Content.ReadAsStringAsync();
ipnContext.Verification = verificationResult;
}
}
await ProcessVerificationResponse(ipnContext, transmissionid);
}
除了总是得到无效响应之外,我还能够获得我需要的内容并且可以正确处理响应正文,所以我知道请求正文是好的,至少从模拟器来看是这样。
PayPal Webhooks 和 IPN(即时付款通知)是两种不同的服务。两者之间没有任何联系。区分它们的一个简单方法是,Webhook 始终采用 JSON 格式,而 IPN 消息始终采用 NVP 或名称-值对格式 (
&name=value
)。
假设您有兴趣验证 JSON 格式的 PayPal Webhook 消息,有两种方法。