# Introduce Stripe for .NET MAUI

## Overview

[Stripe](https://stripe.com) is a very well known payment service to let your end users pay easily and beautifully for your product/service(s) within your mobile apps and websites.

This article will guide you steps to integrate Stripe SDK into a newly created .NET MAUI app step by step.

## **Prerequisites**

* .NET 8
    
* Java SDK 17
    
* Visual Studio on Windows or Visual Studio for Mac, alternatively
    
    * JetBrains Rider alternatively
        
    * Visual Studio Code with .NET MAUI extension
        
* .NET workloads for .NET MAUI
    
* Download [the get-started source code](https://github.com/tuyen-vuduc/dotnet-stripe-quickstart/archive/refs/heads/feat/get-started-starting-point.zip)
    

## Steps

### 0/ Open the downloaded solution `dotnet-maui-stripe-get-started.sln`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719160657520/112a6f29-9a09-4586-a56a-e8727177fdf0.png align="center")

#### 0.a/ Create `Shared.dev.cs` file by making a copy of `Shared.dev.cs.sample`

```plaintext
|--src
    |-- QuickStart.Dotnet.StripeHost
        |-- Shared.cs
        |-- Shared.dev.cs        <------      YOUR_FILE_HERE
```

#### 0.b/ Replace placeholders with your secrets

```csharp
partial class ClientHelper
{
    public const string API_KEY = "YOUR_API_KEY";
    public const string DEFAULT_PUBLISHABLE_KEY = "YOUR_DEFAULT_PUBLISHABLE_KEY";
}
```

> HINTS: You can copy these secrets quickly from [the official quick start by Stripe](https://docs.stripe.com/payments/quickstart?platform=ios).

#### 0.c/ Run the API host

```bash
cd your-path-to-source-code/src/QuickStart.Dotnet.StripeHost
dotnet run -c debug
```

### 0.d/ Expose your API endpoint with [ngrok](https://ngrok.com)

```bash
ngrok http http://localhost:4242
```

> NOTE: [ngrok](https://ngrok.com) is a tool that allows us to expose a development endpoint publicly via the network with ease.

#### 0.e/ Amend `Shared.dev.cs` with the generated URL

```csharp
partial class ClientHelper
{
    public const string BACKEND_URL= "https://generated-subdomain.ngrok-free.app";
}
```

### 1/ Create a new .NET MAUI app from Visual Studio

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719160709286/c53865d3-b740-4a43-87ef-ba06741b92d7.png align="center")

> NOTE: Follow step by step with all default options

### 2/ Install Stripe SDK for .NET MAUI

#### 2.a/ Upgrade all .NET MAUI packages before installing `Stripe.MAUI` package

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719160874147/55fab0bb-bb85-4589-bb13-8da79f87db96.png align="center")

#### 2.b/ Search for `Stripe.Maui` package and install

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719160957305/28861e3d-b2ec-4f7b-bd7e-d882f69cc197.png align="center")

> NOTE:
> 
> * Before going next
>     
>     * Close the solution
>         
>     * Remove bin/obj folders of the .NET MAUI project
>         
>     * Reopen the solution
>         
> * **IMPORTANT!!!** If you faced any issues of project loading failed, please repeat these steps :D
>     

### 3/ Enable Stripe in `MauiProgram.cs`

#### 3.a/ Add shared files to the .NET MAUI project

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719162229996/f102e634-a16c-40f1-bc0f-a30d3890ce8d.png align="center")

> NOTE: We will add these files as links to share code across projects.

#### 3.b/ Add Stripe to `MauiAppBuilder`

```csharp
builder
    .UseStripe(
        QuickStart.Dotnet.Stripe.ClientHelper.DEFAULT_PUBLISHABLE_KEY
    );
```

### 4/ Inject `IPaymentSheet` into `MainPage.xaml.cs`

```csharp
public partial class MainPage : ContentPage
{
    private readonly IPaymentSheet paymentSheet;

    public MainPage(IPaymentSheet paymentSheet)
    {
        InitializeComponent();
        this.paymentSheet = paymentSheet;
    }
}
```

**NOTE:** To get the DI to work, we need to register `MainPage` as a scoped dependency through `MauiAppBuilder`.

```csharp
// In MauiProgram.cs
builder.Services.AddScoped<MainPage>();
```

### 5/ Try paying with payment intent

5.a/ Override `MainPage.xaml` file with the below content

```xml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="GetStartedWithStripe.MainPage">
    <StackLayout
        Padding="30,24"
        Spacing="25">
        <Button
            x:Name="PayNowButton"
            Text="Pay now"
            SemanticProperties.Hint="Pay with Stripe"
            Clicked="OnPayNow"
            IsEnabled="False"
            VerticalOptions="EndAndExpand"
            HorizontalOptions="Fill" />
    </StackLayout>
</ContentPage>
```

#### 5.b/ Fetch payment intent client secret from the above API endpoint

```csharp
private string paymentIntentClientSecret;
protected override async void OnAppearing()
{
    base.OnAppearing();
    
    // The helper method comes from the downloaded source code
    await QuickStart.Dotnet.Stripe.ClientHelper.FetchPaymentIntent()
        .ContinueWith(t =>
        {
            var (ok, msg) = t.Result;
            if (!ok)
            {
                MainThread.BeginInvokeOnMainThread(() => DisplayAlert("API Error", msg, "OK"));
                return;
            }

            paymentIntentClientSecret = msg;

            MainThread.BeginInvokeOnMainThread(() => PayNowButton.IsEnabled = true);
        })
        .ConfigureAwait(false);
}
```

> NOTE:
> 
> * By default, `Pay now` button is disabled
>     
> * It will only be enabled if we can fetch the client secret successfully from the API
>     

#### 5.c/ Add `OnPayNow` handler

```csharp
    private async void OnPayNow(object sender, EventArgs e)
	{
        var configuration = new Configuration("TuyenTV.dev Co.Ltd.");

        var (result, msg) = await paymentSheet.PresentWithPaymentIntentAsync(paymentIntentClientSecret, configuration)
            .ContinueWith(t =>
            {
                if (t.IsCompletedSuccessfully) return (t.Result, null);

                return (PaymentSheetResult.Canceled, "Cannot pay for a reason...");
            });

        switch(result)
        {
            case PaymentSheetResult.Completed:
                await DisplayAlert("Payment Result", "Payment completed successfully!", "OK");
                break;
            case PaymentSheetResult.Canceled:
                if (!string.IsNullOrWhiteSpace(msg))
                {
                    await DisplayAlert("Payment Result", "Payment completed failed!", "Try again");
                }
                break;
        }

        Debug.WriteLine("Payment complete.");
	}
```

### 6/ Run up and check out

Till now, you're ready to check out the result on both Android and iOS.

* **Android**: You can try either on a emulator or on a real device by plugging it in directly to your PC
    
* **iOS**:
    
    * If you have an Apple paid developer account, you can plug your iPhone directly to your PC and try out
        
    * Otherwise, you will need a MacOS device to run the simulator
        

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1719163925457/23a88aee-f1a6-4c47-a4d5-0711cf59b4ef.png align="center")

## Wrap-ups

I just guided you on how to integrate Stripe SDK into a newly created .NET MAUI project. You can follow these steps to add it to your project(s) easily.

[Documents from Stripe](https://docs.stripe.com) are also very helpful, please always take a look to understand a feature you desire to add to your app.

If you want to check out the source code of the binding libraries, you can check it [**here**](https://github.com/tuyen-vuduc/dotnet-binding-utils). If you want to check out the source code of the .NET MAUI library (along with a sample app), you can check it [**here**](https://github.com/tuyen-vuduc/dotnet-maui-stripe).

Happy Coding!!!
