Skip to content

Instantly share code, notes, and snippets.

@mpoerwito
Last active November 8, 2022 16:28
Show Gist options
  • Save mpoerwito/28cfd0fd405c9ebc97f424c21185213a to your computer and use it in GitHub Desktop.
Save mpoerwito/28cfd0fd405c9ebc97f424c21185213a to your computer and use it in GitHub Desktop.
Stripe Webhook Minimalist API
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Mvc;
using NLog.Web;
using Stripe;
using System.Text.Json;
var builder = WebApplication.CreateBuilder(args);
// user secrets
//builder.Configuration.AddEnvironmentVariables().AddUserSecrets(Assembly.GetExecutingAssembly(), true);
string csname = builder.Environment.IsDevelopment() ? "DEVSQL" : "SQL";
builder.Services.AddDbContext<WebhookDBContext>(opt =>
opt.UseSqlServer(builder.Configuration.GetConnectionString(csname)));
builder.Services.AddHttpContextAccessor();
builder.Logging.ClearProviders();
builder.Logging.AddNLog("nlog.config");
var app = builder.Build();
app.Services.GetService<ILogger>();
app.UseHttpsRedirection();
//app.UseRouting();
app.MapGet("/", (IHttpContextAccessor ctxAccessor) =>
{
app.Logger.LogInformation($"Main page accessed from {ctxAccessor.HttpContext.Connection.RemoteIpAddress}");
return Results.Ok("Stripe Webhook Endpoint. This transmission is logged.");
});
app.MapPost("/", async ([FromHeader(Name = "Stripe-Signature")] string Signature
, [FromBody] JsonElement json, WebhookDBContext DB) =>
{
string endpointSecret = builder.Configuration[builder.Environment.IsDevelopment() ? "Stripe:DEVSecret" : "Stripe:Secret"];
StripeConfiguration.ApiKey = builder.Configuration[builder.Environment.IsDevelopment() ? "Stripe:DEVAPIKey" : "Stripe:APIKey"];
try
{
var stripeEvent = EventUtility.ConstructEvent(json.GetRawText(), Signature, endpointSecret);
IncomingEvent p = new()
{
id = stripeEvent.Id,
@object = stripeEvent.Object,
json = stripeEvent.Data.ToJson(),
type = stripeEvent.Type
};
DB.Posts.Add(p);
await DB.SaveChangesAsync();
switch (stripeEvent.Type)
{
case "invoice.paid":
Invoice inv = (Invoice)stripeEvent.Data.Object;
string sfcinv = inv.CustomFields != null ? inv.CustomFields[0].Value: "";
double amtPaid = inv.AmountPaid / 100.00;
DB.Database.ExecuteSqlRaw($"exec [dbo].[AA_STRIPE_PaymentReceived] '{inv.Id}', '{amtPaid}', '{inv.ReceiptNumber}','{sfcinv}'");
app.Logger.LogDebug($"invoice.paid ID: {inv.Id} | sfc inv: {sfcinv} | {amtPaid}");
break;
case "invoice.payment_failed":
break;
default:
DB.Database.ExecuteSqlRaw($"exec [dbo].[AA_STRIPE_EventReceived] '{stripeEvent.Id}'");
break;
}
return Results.Ok();
}
catch (StripeException e)
{
return Results.BadRequest(e);
}
});
app.Run();
class WebhookDBContext : DbContext
{
public WebhookDBContext(DbContextOptions<WebhookDBContext> options) : base(options)
{ }
public DbSet<IncomingEvent> Posts { get; set; } = null!;
}
[Table("AA_STRIPE_Events")]
class IncomingEvent
{
public string id { get; set; } = null!;
public string @object { get; set; } = null!;
public string json { get; set; } = null!;
public string type { get; set; } = null!;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment