PayPal Webhook事件未在沙盒模式下触发

时间:2016-02-22 11:47:06

标签: paypal paypal-sandbox paypal-rest-sdk paypal-webhooks

我正在使用PayPal Rest API,更具体的PayPal .Net SDK用于我的项目,我非常喜欢它。

我的问题是,到目前为止,我无法从PayPal收到任何webhook通知。

注意:webhook模拟器确实有效,我的处理程序从PayPal正确接收json帖子。

以下是我采取的步骤:

  1. 成功创建新发票(使用我的paypal应用程序中的沙箱凭据)后,我将其发送到测试买家帐户。

  2. 我打开通知中的网址查看发票,然后使用买方测试帐户付款。

  3. 协调人和买家都会收到通知已成功支付发票的通知。

  4. 我的服务器什么都没发生。我的侦听器端点没有收到任何webhook事件请求。

  5. 我在应用的沙盒配置中有一个活跃的webhook事件监听器,可以跟踪所有可能的事件。

    PayPal没有发生任何事件的原因是什么?

    我还不想切换到IPN,并且定期从搜索结果中迭代发票列表也不是一种有效的选择。

    更新

    由于沙箱webhook事件服务器已启动并再次运行,因此我使用以下代码(c#controller action)使其工作。注意从webhook模拟器发射的json体结构与支付发票后发送的结构不同。因此,我相应地从PayPal SDK扩展了WebHookEvt对象。

            /// <summary>
        /// PayPal Webhook handler
        /// </summary>
        /// <param name="evt"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult EventHandler(WebhookEvent evt) { // [System.Web.Http.FromBody]
    
            string json = null;
            Capture capture = null;
            InvoiceObject invoiceObject = null;
            InvoiceExt invoice = null;
            WebHookEventCapture captureEvent = null;
            WebHookEventInvoice invoiceEvent = null;
    
            if (evt == null) {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            } else {
                this.logger.Debug(string.Format("***** Webhook event type [{0}] received from PayPal *****", evt.event_type));
                logger.Debug(string.Format("Event id: {0}", evt.id));
                logger.Debug(string.Format("Event create time: {0}", evt.create_time));
                logger.Debug(string.Format("Event type: {0}", evt.event_type));
                logger.Debug(string.Format("Event resource: {0}", evt.resource));
                logger.Debug(string.Format("Event resource type: {0}", evt.resource_type));
                logger.Debug(string.Format("Event summary: {0}", evt.summary));
    
                using (Stream req = Request.InputStream) {
                    req.Seek(0, System.IO.SeekOrigin.Begin);
                    using (StreamReader sr = new StreamReader(req)) {
                        json = sr.ReadToEnd();
                    }
                }
    
                logger.Debug(string.Format("WebHook request json form PayPal: ***{0}***", json));
    
                // Validate webhook event
                bool isValid = WebhookEvent.ValidateReceivedEvent(new PayPalPaymentProvider(IPN_SANDBOX_MODE).Context, Request.Headers, json, WEBHOOK_ID_INVOICE_PAID);
                logger.Debug(string.Format("Validating webhook event... Is valid = {0}", isValid ? "TRUE" : "FALSE"));                
    
                try {
                    if ("capture".Equals(evt.resource_type)) {
                        captureEvent = JsonConvert.DeserializeObject<WebHookEventCapture>(json);
                        capture = captureEvent.resource;
                    } else if ("invoices".Equals(evt.resource_type)) {
                        invoiceEvent = JsonConvert.DeserializeObject<WebHookEventInvoice>(json);
                        invoiceObject = invoiceEvent.resource;
                        invoice = invoiceObject.invoice;
                    }
    
                    //if (capture != null) {
                    //    logger.Debug(string.Format("Capture amount: {0}", capture.amount));
                    //    logger.Debug(string.Format("Capture create time: {0}", capture.create_time));
                    //    logger.Debug(string.Format("Capture id: {0}", capture.id));
                    //    logger.Debug(string.Format("Capture is final: {0}", capture.is_final_capture.HasValue ? capture.is_final_capture : false));
                    //    logger.Debug(string.Format("Capture parent payment: {0}", capture.parent_payment));
                    //    logger.Debug(string.Format("Capture state: {0}", capture.state));
                    //    logger.Debug(string.Format("Capture transaction fee: {0}", capture.transaction_fee));
                    //    logger.Debug(string.Format("Capture update time: {0}", capture.update_time));
                    //}
    
                    if (isValid && invoice != null) {
                        logger.Debug(string.Format("Invoice [{0}]", invoice));
                        logger.Debug(string.Format("Invoice id: [{0}]", invoice.id));
                        logger.Debug(string.Format("Invoice merchant memo: [{0}]", invoice.merchant_memo));
                        logger.Debug(string.Format("Invoice date: [{0}]", invoice.invoice_date));
                        logger.Debug(string.Format("Invoice status: [{0}]", invoice.status));
                        logger.Debug(string.Format("Invoice total amount: [{0}]", invoice.total_amount != null ? invoice.total_amount.currency + invoice.total_amount.value : "??"));
                        if (invoice.billingInfo != null) { // billing_info
                            foreach (var billingInfo in invoice.billingInfo) {
                                logger.Debug(string.Format("Invoice billing info address: {0}", billingInfo.address ?? new InvoiceAddress()));
                                logger.Debug(string.Format("Invoice billing info business name: {0}", billingInfo.business_name ?? "??"));
                                logger.Debug(string.Format("Invoice billing info email: {0}", billingInfo.email ?? "??"));
                                logger.Debug(string.Format("Invoice billing info first name: {0}", billingInfo.first_name ?? "??"));
                                logger.Debug(string.Format("Invoice billing info last name: {0}", billingInfo.last_name ?? "??"));
                                logger.Debug(string.Format("Invoice billing info language: {0}", billingInfo.language ?? "??"));
                                logger.Debug(string.Format("Invoice billing info notification channel: {0}", billingInfo.notification_channel ?? "??"));
                                logger.Debug(string.Format("Invoice billing info phone: {0}", billingInfo.phone ?? new Phone()));
                            }
                        }
    
                        // Update clientproductpayment
                        SubscriptionRepository db = new SubscriptionRepository();
                        var subscription = db.Context.ClientProductPayments.Where(
                                    q => invoice.id.Equals(q.TransactionId)).FirstOrDefault();
                        if (subscription != null) {
                            logger.Debug(string.Format("Subscription (ClientProductPayment) with transaction_id = [{0}] found", invoice.id));
    
                            // Update subscription
                            db.RegisterPayment(subscription, invoice.id);
    
                            logger.Debug(string.Format(
                                "Subscription (ClientProductPayment) with id = [{0}] updated successfully with transaction id = [{1}]",
                                    subscription.Id, invoice.id));
    
                        } else {
                            logger.Warn(string.Format("Subscription (ClientProductPayment) with transaction_id = [{0}] not found", invoice.id));
                        }
    
                    }
    
                }
                catch (Exception e) {
                    logger.Error(e.Message, e);
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
    
            }
            logger.Debug("Sending Http status code 200 response...");
            return new HttpStatusCodeResult(HttpStatusCode.OK);            
        }
    

    扩展WebHookEvt

    using Newtonsoft.Json;
    using PayPal.Api;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace PaymentManager.Provider {
        public class WebHookEventCapture : WebhookEvent {
    
            [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "resource")]
            public new Capture resource { get; set; }
    
        }
    
        public class WebHookEventInvoice : WebhookEvent {
    
            [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "resource")]
            public new InvoiceObject resource { get; set; }
    
        }
    
        public class InvoiceObject {
    
            [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "invoice")]
            public InvoiceExt invoice { get; set; }
    
        }
    
        public class InvoiceExt : Invoice {
    
            [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "billingInfo")]
            public List<BillingInfo> billingInfo { get; set; }
    
        }
    
    }
    

1 个答案:

答案 0 :(得分:-2)

我们很抱歉。我们最后有一个临时问题已得到解决。您现在应该可以接收开票帐户通知了。请尝试一下,让我们知道它是怎么回事。

由于