首页 > 解决方案 > 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 正在等待来自侦听器的某种握手以完成该过程。

标签: c#paypalpaypal-ipn

解决方案


推荐阅读