【问题标题】:Implementing Paypal IPN with ASP vNext使用 ASP vNext 实施 Paypal IPN
【发布时间】:2015-11-01 09:10:30
【问题描述】:

我正在使用 IPN 模拟器发送请求: https://developer.paypal.com/developer/ipnSimulator

当我收到 IPN 时,我使用相同的数据向贝宝发送 POST,并在末尾添加 &cmd=_notify-validate。问题是我总是收到“无效”响应。是因为 IPN 模拟器还是我发布了错误的请求?

这是我的 IPN 控制器: [HttpPost] 公共字符串 IPN() { bool useSandbox = true;

            StringBuilder to_send = new StringBuilder();
            foreach (string key in Request.Form.Keys)
            {
                if (to_send.ToString().Equals(""))
                    to_send.AppendFormat("{0}={1}", key, Request.Form[key]);
                else
                    to_send.AppendFormat("&{0}={1}", key, Request.Form[key]);
            }

            string paypalUrl = useSandbox ? "https://www.sandbox.paypal.com/cgi-bin/webscr"
                : "https://www.paypal.com/cgi-bin/webscr";

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(paypalUrl);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";

            to_send.AppendFormat("&{0}={1}", "cmd", "_notify-validate");

            string strRequest = to_send.ToString();
            req.ContentLength = strRequest.Length;

            string response = "";
            using (StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII))
            {

                streamOut.Write(strRequest);
                streamOut.Close();
                using (StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream()))
                {
                    response = streamIn.ReadToEnd();
                }
            }
    }

这是我从贝宝收到的:

> payment_type: instant
payment_date: Sun Aug 09 2015 12:23:13 GMT+0300 (GTB Daylight Time)
payment_status: Completed
address_status: confirmed
payer_status: verified
first_name: John
last_name: Smith
payer_email: buyer@paypalsandbox.com
payer_id: TESTBUYERID01
address_name: John Smith
address_country: United States
address_country_code: US
address_zip: 95131
address_state: CA
address_city: San Jose
address_street: 123 any street
business: seller@paypalsandbox.com
receiver_email: seller@paypalsandbox.com
receiver_id: seller@paypalsandbox.com
residence_country: US
item_name: something
item_number: AK-1234
quantity: 1
shipping: 3.04
tax: 2.02
mc_currency: USD
mc_fee: 0.44
mc_gross: 12.34
mc_gross1: 12.34
txn_type: web_accept
txn_id: 363750782
notify_version: 2.1
custom: xyz123
invoice: abc1234
test_ipn: 1
verify_sign: AUxvCDK2PEEhNsHhVyUQ8Y-mDqfQARYxDdlEIxTy83GhdfASQp4iG0Rj

这是我要回复的内容:

 payment_type=instant&payment_date=Sun Aug 09 2015 12:23:13 GMT+0300 (GTB Daylight Time)&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Smith&payer_email=buyer@paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John Smith&address_country=United States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San Jose&address_street=123 any street&business=seller@paypalsandbox.com&receiver_email=seller@paypalsandbox.com&receiver_id=seller@paypalsandbox.com&residence_country=US&item_name=something&item_number=AK-1234&quantity=1&shipping=3.04&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross1=12.34&txn_type=web_accept&txn_id=363750782&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=AUxvCDK2PEEhNsHhVyUQ8Y-mDqfQARYxDdlEIxTy83GhdfASQp4iG0Rj&cmd=_notify-validate

编辑1:

我尝试按照 paypal 文档中的说明将编码更改为 UTF-8,但仍然无法正常工作: 确保对响应字符串使用与原始 IPN 消息的字符集字段中指定的编码相同的字符编码。使用 IPN 模拟器进行测试时,字符编码将始终为 UTF-8。

                byte[] byteArray = Encoding.UTF8.GetBytes(strRequest);

            string response = "";
            using (BinaryWriter streamOut = new BinaryWriter(req.GetRequestStream(), System.Text.Encoding.UTF8))
            {
                streamOut.Write(byteArray, 0, byteArray.Length);
                streamOut.Close();
                using (StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream()))
                {
                    response = streamIn.ReadToEnd();
                }
            }

是否有可能 Request.Form 中的变量不是按照它们发送的顺序?

【问题讨论】:

    标签: paypal paypal-ipn paypal-sandbox asp.net-core asp.net-core-mvc


    【解决方案1】:

    cmd=_notify-validate 必须在原始变量之前,而不是在它们之后,您可能需要在您的 to_send StringBuilder 代码块中进行一些调整,如下所示:

            StringBuilder to_send = new StringBuilder();
            to_send.Append("cmd=_notify-validate");
            foreach (string key in Request.Form.Keys)
            {
                to_send.AppendFormat("&{0}={1}", key, Request.Form[key]);
            }
            string strRequest = to_send.ToString();
    

    p.s 请参阅此处以获取 IPN trouble shooting tips,这将非常有帮助,因为其中已经涵盖了大多数问题

    【讨论】:

    • 还是不行。我什至按照贝宝页面上的说明将编码更改为 UTF-8。
    • 你的POST返回的日期格式很奇怪,通常模拟器消息没有那个格式的日期,你在解析密钥之前打印了请求吗?
    • 这些是存储在 Request.Form 中的变量,而不是实际的贝宝请求。我刚打印出来。
    • 原则是确保 PayPal POST 到您的 IPN 脚本的内容在您 POST 回来时保持完全不变,除了添加一个“cmd=_notify-validate”。您可以尝试使用简单的“立即购买”按钮进行真正的沙盒交易来测试您的 IPN 脚本,或者直接使用此处的 IPN 的 PayPal 示例代码:github.com/paypal/ipn-code-samples
    • 我尝试了示例,但在 ASP vNext 中我得到了这一行的一些异常: byte[] Param = Request.BinaryRead(HttpContext.Current.Request.ContentLength); .严重性代码描述项目文件行错误 CS1061“HttpRequest”不包含“BinaryRead”的定义,并且找不到接受“HttpRequest”类型的第一个参数的扩展方法“BinaryRead”(您是否缺少 using 指令或程序集引用?) 和严重性代码描述项目文件行错误 CS0117“HttpContext”不包含“当前”的定义
    猜你喜欢
    • 2013-03-05
    • 2017-08-28
    • 2021-07-13
    • 2013-06-19
    • 2017-01-18
    • 2021-03-01
    • 1970-01-01
    • 2010-12-01
    • 2010-11-06
    相关资源
    最近更新 更多