Step 1. Register with Stripe and Get Credentials
Before starting the integration, you need to sign up for a Stripe account and obtain your API keys. Follow these steps.
- Sign up or log in to Stripe at stripe.com
- Navigate to the API section in the Dashboard.
- Copy your Secret Key and Publishable Key. These keys will be used to authenticate your application with Stripe.
Step 2. Create a .NET API Application
Create a new ASP.NET Core API application to integrate Stripe. If the .NET SDK is not installed on your machine, download it from the .NET website.
- Open a command prompt or terminal.
- Run the following command to create a new API project.
dotnet new webapi -n SubscriptionSystem
- Navigate to the project directory.
cd SubscriptionSystem
Step 3. Set Up Stripe in .NET
To use Stripe, install the Stripe NuGet package in your .NET application.
- Install the Stripe package.
dotnet add package Stripe.net
- Add your Stripe secret key to the configuration.
- Open appsettings.json and add the following.
{
"Stripe": {
"SecretKey": "your_stripe_secret_key"
}
}
Step 4. Implement Subscription Functionality
Now, let's implement the subscription functionality. We will create a StripeController to handle the subscription process.
Creating the DTOs
First, create the necessary DTOs for handling Stripe data.
PaymentDto.cs
namespace SubscriptionSystem.Dtos
{
public class PaymentDto
{
public string PaymentMethodId { get; set; }
public string CustomerId { get; set; }
}
}
StripePaymentRequestDto.cs
namespace SubscriptionSystem.Dtos
{
public class StripePaymentRequestDto
{
public string Email { get; set; }
public string PaymentMethodId { get; set; }
}
}
StripeProductDto.cs
namespace SubscriptionSystem.Dtos
{
public class StripeProductDto
{
public string Id { get; set; }
public string Name { get; set; }
public long Amount { get; set; }
public string Currency { get; set; }
public string Interval { get; set; }
}
}
SubscriptionDto.cs
namespace SubscriptionSystem.Dtos
{
public class SubscriptionDto
{
public string SubscriptionId { get; set; }
public string CustomerId { get; set; }
public string ProductId { get; set; }
}
}
Creating the Service Interface and Implementation
Create an interface for the Stripe service and its implementation.
IStripeService.cs
using SubscriptionSystem.Dtos;
namespace SubscriptionSystem.Interfaces
{
public interface IStripeService
{
Task<string> CreateCustomerAsync(string email, string paymentMethodId);
Task<string> CreateSubscriptionAsync(string customerId, string priceId);
Task CancelSubscriptionAsync(string subscriptionId);
Task<StripeProductDto> CreateProductAsync(string name, long amount, string currency, string interval);
}
}
StripeService.cs
using Stripe;
using SubscriptionSystem.Dtos;
using SubscriptionSystem.Interfaces;
namespace SubscriptionSystem.Services
{
public class StripeService : IStripeService
{
public async Task<string> CreateCustomerAsync(string email, string paymentMethodId)
{
var options = new CustomerCreateOptions
{
Email = email,
PaymentMethod = paymentMethodId,
InvoiceSettings = new CustomerInvoiceSettingsOptions
{
DefaultPaymentMethod = paymentMethodId
}
};
var service = new CustomerService();
var customer = await service.CreateAsync(options);
return customer.Id;
}
public async Task<string> CreateSubscriptionAsync(string customerId, string priceId)
{
var options = new SubscriptionCreateOptions
{
Customer = customerId,
Items = new List<SubscriptionItemOptions>
{
new SubscriptionItemOptions { Price = priceId }
},
Expand = new List<string> { "latest_invoice.payment_intent" }
};
var service = new SubscriptionService();
var subscription = await service.CreateAsync(options);
return subscription.Id;
}
public async Task CancelSubscriptionAsync(string subscriptionId)
{
var service = new SubscriptionService();
await service.CancelAsync(subscriptionId);
}
public async Task<StripeProductDto> CreateProductAsync(string name, long amount, string currency, string interval)
{
var productOptions = new ProductCreateOptions
{
Name = name,
};
var productService = new ProductService();
var product = await productService.CreateAsync(productOptions);
var priceOptions = new PriceCreateOptions
{
UnitAmount = amount,
Currency = currency,
Recurring = new PriceRecurringOptions { Interval = interval },
Product = product.Id,
};
var priceService = new PriceService();
var price = await priceService.CreateAsync(priceOptions);
return new StripeProductDto
{
Id = price.Id,
Name = product.Name,
Amount = price.UnitAmount.Value,
Currency = price.Currency,
Interval = price.Recurring.Interval
};
}
}
}
Creating the Controller
Create a StripeController to handle the subscription process.
StripeController.cs
using Microsoft.AspNetCore.Mvc;
using SubscriptionSystem.Dtos;
using SubscriptionSystem.Interfaces;
namespace SubscriptionSystem.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class StripeController : ControllerBase
{
private readonly IStripeService _stripeService;
public StripeController(IStripeService stripeService)
{
_stripeService = stripeService;
}
[HttpPost("create-customer")]
public async Task<IActionResult> CreateCustomer([FromBody] StripePaymentRequestDto paymentRequest)
{
var customerId = await _stripeService.CreateCustomerAsync(paymentRequest.Email, paymentRequest.PaymentMethodId);
return Ok(new { CustomerId = customerId });
}
[HttpPost("create-subscription")]
public async Task<IActionResult> CreateSubscription([FromBody] SubscriptionDto subscriptionDto)
{
var subscriptionId = await _stripeService.CreateSubscriptionAsync(subscriptionDto.CustomerId, subscriptionDto.ProductId);
return Ok(new { SubscriptionId = subscriptionId });
}
[HttpPost("cancel-subscription")]
public async Task<IActionResult> CancelSubscription([FromBody] SubscriptionDto subscriptionDto)
{
await _stripeService.CancelSubscriptionAsync(subscriptionDto.SubscriptionId);
return NoContent();
}
[HttpPost("create-product")]
public async Task<IActionResult> CreateProduct([FromBody] StripeProductDto productDto)
{
var product = await _stripeService.CreateProductAsync(productDto.Name, productDto.Amount, productDto.Currency, productDto.Interval);
return Ok(product);
}
}
}
Step 5. Handling Stripe Webhooks
Stripe webhooks allow your application to receive notifications about changes to your customer's subscription status. To handle webhooks.
- Create a Webhook Endpoint: This endpoint will receive webhook events from Stripe.
- Verify the Webhook Signature: Ensure that the event is from Stripe by verifying the signature.
Setting Up the Webhook
StripeController.cs
[HttpPost("webhook")]
public async Task<IActionResult> Webhook()
{
var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
try
{
var stripeEvent = EventUtility.ConstructEvent(
json,
Request.Headers["Stripe-Signature"],
"your_stripe_webhook_secret"
);
// Handle the event
if (stripeEvent.Type == Events.CustomerSubscriptionCreated)
{
var subscription = stripeEvent.Data.Object as Subscription;
// Handle the subscription creation
}
else if (stripeEvent.Type == Events.CustomerSubscriptionDeleted)
{
var subscription = stripeEvent.Data.Object as Subscription;
// Handle the subscription cancellation
}
return Ok();
}
catch (StripeException e)
{
return BadRequest();
}
}
Update the Dependency Injection in the Program.cs
Make sure to register the Stripe service in the dependency injection container.
Program.cs
builder.Services.AddScoped<IStripeService, StripeService>();
builder.Services.AddScoped<ProductService>();
builder.Services.AddScoped<SubscriptionService>();
Conclusion
In this article, we went through the steps to integrate Stripe for subscription payments in an ASP.NET Core API application. This includes setting up Stripe, creating the necessary DTOs, implementing the service interface, and creating a controller to handle subscription functions. This template allows you to easily manage customer creation, product development, and subscription lifecycles. Stripe’s integration enhances your application by providing secure and reliable payment processing.