Stripe-dotnet: Question: .NET Core and Receiving Events from Stripe (Handlers -> Middleware)

Created on 28 Mar 2017  路  6Comments  路  Source: stripe/stripe-dotnet

I haven't fully implemented this library, so I haven't tested it yet.

But, I know that HTTP Handler's have been replaced with .NET Core Middleware (https://docs.microsoft.com/en-us/aspnet/core/migration/http-modules) classes.

Does this completely prevent event handling from working with .NET Core, or is there some sort of backwards compatibility?

Thanks!

Most helpful comment

This is the code I use in my Webhook Handler in .Net Core 1.1.2. You are welcome to adapt it as necessary:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.IO;
using Stripe;
using Microsoft.Extensions.Logging;
using WebApp.Data;
using Entities;

namespace WebApp.Middleware
{
    public class StripeWebhookHandler
    {
        private readonly ILogger _log;
        private readonly ApplicationDataContext _ctx;

        public StripeWebhookHandler(RequestDelegate next, ILoggerFactory logger, ApplicationDataContext ctx)
        {
            _log = logger.CreateLogger<StripeWebhookHandler>();
            _ctx = ctx;
        }

        public async Task Invoke(HttpContext httpContext)
        {            
            bool handled = true;

            var json = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();

            var stripeEvent = StripeEventUtility.ParseEvent(json);

            if (!_ctx.ServiceEvents.Any(evt => evt.ServiceEventId == stripeEvent.Id))
            {
                switch (stripeEvent.Type)
                {

                    case StripeEvents.AccountApplicationDeauthorized:
                    case StripeEvents.AccountExternalAccountCreated:
                    case StripeEvents.AccountExternalAccountDeleted:
                    case StripeEvents.AccountExternalAccountUpdated:
                    case StripeEvents.AccountUpdated:
                        var stripeAccount = Stripe.Mapper<StripeAccount>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.ApplicationFeeCreated:
                    case StripeEvents.ApplicationFeeRefunded:
                    case StripeEvents.ApplicationFeeRefundUpdated:
                        var fee = Stripe.Mapper<StripeApplicationFee>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.BalanceAvailable:
                        var bal = Stripe.Mapper<StripeBalance>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.BitcoinReceiverCreated:
                    case StripeEvents.BitcoinReceiverFilled:
                    case StripeEvents.BitcoinReceiverTransactionUpdated:
                    case StripeEvents.BitcoinReceiverUpdated:
                        var btcrcv = Stripe.Mapper<StripeReceiver>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.ChargeCaptured:
                    case StripeEvents.ChargeFailed:
                    case StripeEvents.ChargePending:
                    case StripeEvents.ChargeRefunded:
                    case StripeEvents.ChargeSucceeded:
                    case StripeEvents.ChargeUpdated:
                        var charge = Stripe.Mapper<StripeCharge>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.ChargeDisputeClosed:
                    case StripeEvents.ChargeDisputeCreated:
                    case StripeEvents.ChargeDisputeFundsReinstated:
                    case StripeEvents.ChargeDisputeFundsWithdrawn:
                        var dispute = Stripe.Mapper<StripeDispute>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CouponCreated:
                    case StripeEvents.CouponDeleted:
                    case StripeEvents.CouponUpdated:
                        var cpn = Stripe.Mapper<StripeCoupon>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerCreated:
                    case StripeEvents.CustomerDeleted:
                    case StripeEvents.CustomerUpdated:
                        var cst = Stripe.Mapper<StripeCustomer>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerDiscountCreated:
                    case StripeEvents.CustomerDiscountDeleted:
                    case StripeEvents.CustomerDiscountUpdated:
                        var dsc = Stripe.Mapper<StripeDiscount>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerSourceCreated:
                        var src = Stripe.Mapper<StripeSource>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerSubscriptionCreated:
                        break;
                    case StripeEvents.InvoiceCreated:
                        break;
                    case StripeEvents.InvoicePaymentSucceeded:
                        break;
                    case StripeEvents.InvoicePaymentFailed:
                        break;
                    case StripeEvents.Ping:
                        break;
                    case StripeEvents.PlanCreated:
                        break;
                    case StripeEvents.PayoutCreated:
                        break;
                    case StripeEvents.PayoutPaid:
                        break;
                    default:
                        _log.LogWarning("Received unhandled webhook: {0}", json);
                        handled = false;
                        break;
                }

                if (handled)
                {
                    WebhookEvent evt = new WebhookEvent()
                    {
                        ServiceName = "Stripe",
                        ServiceEventType = stripeEvent.Type.ToString(),
                        ServiceEventId = stripeEvent.Id,
                        Processed = DateTime.Now,
                        EventText = json
                    };

                    await _ctx.ServiceEvents.AddAsync(evt);

                    await _ctx.SaveChangesAsync();

                    httpContext.Response.StatusCode = 200;
                }
                else
                    httpContext.Response.StatusCode = 400;
            }
            else
                httpContext.Response.StatusCode = 200;
        }
    }

    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class StripeWebhookHandlerExtensions
    {
        public static IApplicationBuilder UseStripeWebhookHandler(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<StripeWebhookHandler>();
        }
    }
}

Then in the Startup.cs, I add the following line to the Configure method:

app.Map(new PathString("/webhooks/stripe"), a => a.UseStripeWebhookHandler());

All 6 comments

Good question!

The example in the mspec test project could be converted to use middleware (i think). This is something that needs to be figured out. I'll leave this open - someone out there has probably done it. If not, it's worth some investigation. Thanks!

This is the code I use in my Webhook Handler in .Net Core 1.1.2. You are welcome to adapt it as necessary:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.IO;
using Stripe;
using Microsoft.Extensions.Logging;
using WebApp.Data;
using Entities;

namespace WebApp.Middleware
{
    public class StripeWebhookHandler
    {
        private readonly ILogger _log;
        private readonly ApplicationDataContext _ctx;

        public StripeWebhookHandler(RequestDelegate next, ILoggerFactory logger, ApplicationDataContext ctx)
        {
            _log = logger.CreateLogger<StripeWebhookHandler>();
            _ctx = ctx;
        }

        public async Task Invoke(HttpContext httpContext)
        {            
            bool handled = true;

            var json = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();

            var stripeEvent = StripeEventUtility.ParseEvent(json);

            if (!_ctx.ServiceEvents.Any(evt => evt.ServiceEventId == stripeEvent.Id))
            {
                switch (stripeEvent.Type)
                {

                    case StripeEvents.AccountApplicationDeauthorized:
                    case StripeEvents.AccountExternalAccountCreated:
                    case StripeEvents.AccountExternalAccountDeleted:
                    case StripeEvents.AccountExternalAccountUpdated:
                    case StripeEvents.AccountUpdated:
                        var stripeAccount = Stripe.Mapper<StripeAccount>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.ApplicationFeeCreated:
                    case StripeEvents.ApplicationFeeRefunded:
                    case StripeEvents.ApplicationFeeRefundUpdated:
                        var fee = Stripe.Mapper<StripeApplicationFee>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.BalanceAvailable:
                        var bal = Stripe.Mapper<StripeBalance>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.BitcoinReceiverCreated:
                    case StripeEvents.BitcoinReceiverFilled:
                    case StripeEvents.BitcoinReceiverTransactionUpdated:
                    case StripeEvents.BitcoinReceiverUpdated:
                        var btcrcv = Stripe.Mapper<StripeReceiver>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.ChargeCaptured:
                    case StripeEvents.ChargeFailed:
                    case StripeEvents.ChargePending:
                    case StripeEvents.ChargeRefunded:
                    case StripeEvents.ChargeSucceeded:
                    case StripeEvents.ChargeUpdated:
                        var charge = Stripe.Mapper<StripeCharge>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.ChargeDisputeClosed:
                    case StripeEvents.ChargeDisputeCreated:
                    case StripeEvents.ChargeDisputeFundsReinstated:
                    case StripeEvents.ChargeDisputeFundsWithdrawn:
                        var dispute = Stripe.Mapper<StripeDispute>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CouponCreated:
                    case StripeEvents.CouponDeleted:
                    case StripeEvents.CouponUpdated:
                        var cpn = Stripe.Mapper<StripeCoupon>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerCreated:
                    case StripeEvents.CustomerDeleted:
                    case StripeEvents.CustomerUpdated:
                        var cst = Stripe.Mapper<StripeCustomer>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerDiscountCreated:
                    case StripeEvents.CustomerDiscountDeleted:
                    case StripeEvents.CustomerDiscountUpdated:
                        var dsc = Stripe.Mapper<StripeDiscount>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerSourceCreated:
                        var src = Stripe.Mapper<StripeSource>.MapFromJson(stripeEvent.Data.Object.ToString());
                        break;
                    case StripeEvents.CustomerSubscriptionCreated:
                        break;
                    case StripeEvents.InvoiceCreated:
                        break;
                    case StripeEvents.InvoicePaymentSucceeded:
                        break;
                    case StripeEvents.InvoicePaymentFailed:
                        break;
                    case StripeEvents.Ping:
                        break;
                    case StripeEvents.PlanCreated:
                        break;
                    case StripeEvents.PayoutCreated:
                        break;
                    case StripeEvents.PayoutPaid:
                        break;
                    default:
                        _log.LogWarning("Received unhandled webhook: {0}", json);
                        handled = false;
                        break;
                }

                if (handled)
                {
                    WebhookEvent evt = new WebhookEvent()
                    {
                        ServiceName = "Stripe",
                        ServiceEventType = stripeEvent.Type.ToString(),
                        ServiceEventId = stripeEvent.Id,
                        Processed = DateTime.Now,
                        EventText = json
                    };

                    await _ctx.ServiceEvents.AddAsync(evt);

                    await _ctx.SaveChangesAsync();

                    httpContext.Response.StatusCode = 200;
                }
                else
                    httpContext.Response.StatusCode = 400;
            }
            else
                httpContext.Response.StatusCode = 200;
        }
    }

    // Extension method used to add the middleware to the HTTP request pipeline.
    public static class StripeWebhookHandlerExtensions
    {
        public static IApplicationBuilder UseStripeWebhookHandler(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<StripeWebhookHandler>();
        }
    }
}

Then in the Startup.cs, I add the following line to the Configure method:

app.Map(new PathString("/webhooks/stripe"), a => a.UseStripeWebhookHandler());

this is awesome @txdotnetdev! I edited your comment a little just for formatting. thanks!

how to get customerID from StripeEvents if ChargeSucceeded in C#

@afollestad This is a really old issue I would recommend contacting our support team directly: https://support.stripe.com/contact?email=true

@remi-stripe well it's so old it's not really relevant anymore. 馃檪

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pradt picture pradt  路  9Comments

jfrueh picture jfrueh  路  3Comments

Seichis picture Seichis  路  4Comments

goodyes picture goodyes  路  8Comments

drod516 picture drod516  路  12Comments