Build a Subscription-Based Service with Stripe and Appwrite Functions in Flutter
Tags: flutter, dart, stripe, serverlessfunctions
Published: 2023-01-20 11:28:13

---
title: Build a Subscription-Based Service with Stripe and Appwrite Functions in Flutter
published: true
description: Learn how to create a newspaper subscription service in Flutter using Stripe and Appwrite Functions.
tags: #flutter #dart #stripe #serverlessFunctions
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f52rltznlf8e3wush9zv.png
# Use a ratio of 100:42 for best results.
# published_at: 2023-01-20 10:56 +0000
---


A subscription is an agreement where a customer agrees to pay a recurring fee to a vendor for delivered goods or rendered services periodically. It is a business model adopted by many businesses and websites to better serve their customers.

In this post, we will learn how to create a newspaper subscription service in Flutter using Stripe and Appwrite Functions.

## Technology Overview

[Appwrite Function](https://appwrite.io/docs/functions?utm_source=hackmamba&utm_medium=hackmamba-blog) is a service that lets us use the Appwrite server functionality by executing a custom code using a language of choice like Node.js, Python, PHP, Dart, or Java.

[Stripe](https://stripe.com/) is a software-as-a-service platform that offers sets of APIs for processing payments globally.

## GitHub Links

The project source codes are below:

- [Appwrite Function with Dart](https://github.com/Mr-Malomz/function_stripe)
- [Flutter App](https://github.com/Mr-Malomz/appwrite_stripe)


## Prerequisites

The following requirements apply to follow along:


- Basic understanding of Dart and Flutter
- Flutter [SDK](https://flutter.dev/docs/get-started/install) installed
- [Appwrite CLI](https://appwrite.io/docs/command-line?utm_source=hackmamba&utm_medium=hackmamba-blog) installed
- [Xcode](https://developer.apple.com/xcode/) with a developer account (for Mac users)
- Either [IOS Simulator](https://developer.apple.com/xcode/), [Android Studio](https://developer.android.com/studio), or [Chrome web browser](https://support.google.com/chrome/answer/95346?hl=en-GB&co=GENIE.Platform%3DDesktop) to run our application
- An Appwrite instance; check out this [article](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba) on how to set up an instance locally or one-click install on [DigitalOcean](https://marketplace.digitalocean.com/apps/appwrite) or [Gitpod](https://gitpod.io/#https://github.com/appwrite/integration-for-gitpod)
- A Stripe account ([**s**](https://marketplace.zoom.us/)[**ignup**](https://dashboard.stripe.com/register) for a trial account, it is completely free)


## Set up a Stripe Account to Process Payment

To get started, we need to log into our Stripe account to get our **Secret Key**. The **Secret Key** will come in handy for processing payments in our application. To do this, navigate to the **Developers** tab and copy the **Secret Key**.

![Stripe overview](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671367895626_Screenshot+2022-12-17+at+21.02.30.png)

## Integrate Appwrite Function with Stripe

**Enabling Dart runtime in Appwrite**
By default, Dart is not included as part of the Appwrite runtime. To enable Dart as a supported runtime, we first need to navigate to the directory that was created when we installed Appwrite and edit the `.env` file by adding `dart-2.17` under the `appwrite` service as shown below:


![Appwrite folder with .env file](https://paper-attachments.dropboxusercontent.com/s_D82BCAF4FA806DDC66086296DB729575AF10BA7E5A187F3ABEBD28438E2912BE_1666298051688_Screenshot+2022-10-20+at+21.32.42.png)


```env
//remaining env variable goes here
    
_APP_FUNCTIONS_RUNTIMES=dart-2.17
```


![Updated runtime with Dart support](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671368438914_Screenshot+2022-12-17+at+19.32.39.png)


Lastly, we need to sync the changes we made on the `.env` file with our Appwrite server. To do this, we must run the command below inside the `appwrite` directory.

```bash
docker compose up -d --force-recreate
```

**Create Appwrite project**
With our Appwrite instance up and running, we can now create a project that our function will use to process payments using Stripe. To do this, we first need to navigate to the desired directory and run the command below:

```bash
mkdir function_stripe && cd function_stripe
```

The command creates a project folder called `function_stripe` and navigates into the folder.

Secondly, we need to log into the Appwrite server using the CLI.

```bash
appwrite login
```

We will be prompted to input our `email` and `password` which need to be the credentials we used to sign up for the Appwrite console.

Lastly, we need to create a new Appwrite project using the command below:

```bash
appwrite init project
```

We will be prompted with some questions on how to set up our project, and we can answer as shown below:

    How would you like to start? <select "Create a new project">
    What would you like to name your project? <input "appwrite_stripe">
    What ID would you like to have for your project? (unique()) <press enter>

**Create** **Appwrite Function inside the** **p****roject**
With our project setup, we can proceed to create a function by running the command below:

```bash
appwrite init function
```

We will also be prompted with some questions about how to set up our function; we can answer as shown below:

```bash
What would you like to name your function? <input "function_stripe">
What ID would you like to have for your function? (unique()) <press enter>
What runtime would you like to use? <scroll to dart-2.17 and press enter>
```
 
 The command will create a starter Dart project.

![Starter project](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671375729908_Screenshot+2022-12-18+at+16.01.25.png)


Secondly, we need to install the required dependency by navigating to `pubspec.yaml` file and add the `http` package to the `dependencies` section.

```bash
http: ^0.13.5
```
![Install dependency](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671375881183_Screenshot+2022-12-17+at+22.40.39.png)


We also need to install the specified dependency by running the command below:

```bash
cd functions/function_stripe/
dart pub get
```

Thirdly, we need to modify the `main.dart` file inside the `lib` folder as shown below:

```dart
import 'package:dart_appwrite/dart_appwrite.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

Future<void> start(final req, final res) async {
  final client = Client();
  var uname = 'STRIPE SECRET KEY GOES HERE';
  var pword = '';
  var authn = 'Basic ' + base64Encode(utf8.encode('$uname:$pword'));

  var headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': authn,
  };

  var data = {
    'amount': '100',
    'currency': 'usd',
    'payment_method': 'pm_card_visa',
  };

  var url = Uri.parse('https://api.stripe.com/v1/payment_intents');
  var response = await http.post(url, headers: headers, body: data);
  if (response.statusCode != 200) {
    res.json({
      "status": response.statusCode,
      "message": "Error processing subscription"
    });
  } else {
    res.json({
      "status": response.statusCode,
      "message": "Subscription processed successfully!"
    });
  }
}
```

The snippet above does the following:

- Imports the required dependencies
- **Line 7-14**: Creates an API `headers` object using the **Secret Key** to setup `Authorization`
- **Line 16-20**: Creates an API body that consists of `amount`, `currency`, and `payment_method` of type card and using a test card (**pm_card_visa**)
- **Line 22-34**: Makes an API call to Stripe by passing the `headers`, `body`, and returning the appropriate response

**Note**: We hardcoded the amount and the payment method in this post. However, Stripe supports multiple payment methods and options we can adopt in a production environment.

Lastly, we must navigate to the project terminal and deploy our function.

```
cd ../..
appwrite deploy function
```

We will also be prompted about the function we would like to deploy. We must select the `appwrite_sendgrid` function by pressing the **spacebar key** to mark and the **enter key** to confirm the selection.

![Select function to deploy](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671379947363_Screenshot+2022-12-18+at+17.11.27.png)

![Sample of a deployed function](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671380009441_Screenshot+2022-12-18+at+17.11.45.png)


We can also confirm the deployment by navigating to the **Function** tab on the Appwrite console.

![Deployed function](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671380136068_Screenshot+2022-12-17+at+22.19.18.png)


Lastly, we must update the deployed function permission as we need to call it from our Flutter application. To do this, we need to navigate to the **Settings** tab, scroll to the **Execute Access** section, select `Any`, and click **Update**.

![Update execute access](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671387459544_Screenshot+2022-12-18+at+02.40.59.png)

## Create a Flutter App

With our function deployed and ready to accept payment via Stripe, we can set up a Flutter project. 

To get started, we need to clone the project by navigating to the desired directory and running the command below:

```bash
git clone https://github.com/Mr-Malomz/appwrite_stripe.git && cd appwrite_stripe
```

**Running the** **P****roject**
First, we need to install the project dependencies by running the command below:

```bash
flutter pub get
```

Then, run the project using the command below:

```bash
flutter run
```

The command above will run the application on the selected device.

![Running app](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1673276228891_unCVxmoI+1+2.png)


**Create a Database and Add Sample Data**
First, we need to create a database with the corresponding collection, document, and add sample data as shown below:

| **name**      | **is_subscribed** |
| ------------- | ----------------- |
| John Travolta | false             |

![Collection](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671383987097_Screenshot+2022-12-18+at+18.19.13.png)


Lastly, we need to update our database permission to manage them accordingly. To do this, we need to navigate to the **Settings** tab, scroll to the **Update Permissions** section, select `Any`, and mark accordingly.

![Select Any](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671384434901_Screenshot+2022-12-18+at+02.24.27.png)
![Mark permission](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671384434914_Screenshot+2022-12-18+at+02.25.38.png)


**Add Platform** **S****upport**
To add support for our Flutter app, navigate to the **Home** menu and click the **Flutter App** button.

![Add platform](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671388788364_Screenshot+2022-12-18+at+01.25.06.png)


Depending on the device we are using to run our Flutter application, we can modify it as shown below.

**iOS**
To obtain our Bundle ID, we can navigate using the path below:
**ios > Runner.xcodeproj > project.pbxproj**

Open the `project.pbxproj` file and search for `PRODUCT_BUNDLE_IDENTIFIER`.

![Select new Flutter app](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671388862700_Screenshot+2022-12-18+at+01.30.54.png)


Next, open the project directory on [Xcode](https://developer.apple.com/xcode/), open the `Runner.xcworkspace` folder in the app's iOS folder, select the **Runner** project in the Xcode project navigator, select the **Runner** target in the primary menu sidebar, and then select **i****OS 11** in the deployment info’s target.

![Change deployment target](https://paper-attachments.dropboxusercontent.com/s_9C6F95223612512F2BFCBBAA719BAF62E5E51518F8EC1B3A16905A2D91336244_1650208061820_Screenshot+2022-04-17+at+16.05.22.png)


**Android**
To get our package name, we can navigate to an XML file using the path below:
**android > app > src > debug > AndroidManifest.xml**

Open the `AndroidManifest.xml` file and copy the `package` value.

![Android](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671389594719_Screenshot+2022-12-18+at+01.25.50.png)


Next, we need to modify the `AndroidManifext.xml` as shown below:

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.real_time_comm">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application ...>
    <activity android:name="com.linusu.apppwrite_stripe.CallbackActivity" android:exported="true">
      <intent-filter android:label="apppwrite_stripe">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="appwrite-callback-[PROJECT_ID]" />
      </intent-filter>
    </activity>
  </application>
</manifest>
```

We must also replace the highlighted `[PROJECT_ID]` with our actual Appwrite project ID.

# Building the Subscription-Based Service

To get started, we need to create a model to convert the response sent from Appwrite to a Dart object. The model will also cater to JSON serialization. To do this, we need to create a `utils.dart` file in the `lib` folder and add the snippet below:

```dart
class AppConstant {
  final String databaseId = "REPLACE WITH DATABASE ID";
  final String projectId = "REPLACE WITH PROJECT ID";
  final String collectionId = "REPLACE WITH COLLECTION ID";
  final String functionId = "REPLACE WITH FUNCTION ID";
  final String userId = "REPLACE WITH SAMPLE ID";
  final String endpoint = "ENDPOINT";
}

class User {
  String name;
  bool is_subscribed;

  User({required this.name, required this.is_subscribed});

  Map<dynamic, dynamic> toJson() {
    return {"name": name, "is_subscribed": is_subscribed};
  }

  factory User.fromJson(Map<dynamic, dynamic> json) {
    return User(name: json['name'], is_subscribed: json['is_subscribed']);
  }
}
```

For the `endpoint` property, we need to modify it to work with our system's local network address. We can adjust accordingly:

**iOS**
Navigate to the **Network** section and copy the IP address:

![IP address](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cha2n4wd8jvyvd380mrx.png)


**Android**
We can connect our Android emulator to the system’s IP using the `10.0.2.2` IP address.

      final String endpoint = "http://10.0.2.2/v1";

**Note**: We can get the `databaseId`, `projectId`, `collectionId`, `functionId`, and `userId` by navigating through the Appwrite console.

Next, we need to create a service file to separate the application core logic from the UI. To do this, create a `user_service.dart` file inside the `lib` directory, and first, add the snippet below:

```dart
import 'package:appwrite/appwrite.dart';
import 'package:appwrite_stripe/utils.dart';

class UserService {
  Client client = Client();
  Databases? db;

  UserService() {
    _init();
  }

  //initialize the application
  _init() async {
    client
        .setEndpoint(AppConstant().endpoint)
        .setProject(AppConstant().projectId);

    db = Databases(client);

    //get current session
    Account account = Account(client);

    try {
      await account.get();
    } on AppwriteException catch (e) {
      if (e.code == 401) {
        account
            .createAnonymousSession()
            .then((value) => value)
            .catchError((e) => e);
      }
    }
  }
}
```

The snippet above does the following:

- Imports the required dependencies
- Creates a `UserService` class with `client`, `db` properties to connect to the Appwrite instance, and the database
- Creates an `_init` method that configures the Appwrite using the properties and also conditionally creates an anonymous user to access the Appwrite database

Lastly, we need to modify `Userservice` class by adding `createSubscription`, `getUserDetails`, `subscribeUser`, and `unSubscribeUser` methods to manage subscriptions accordingly.

```dart
//imports go here

class UserService {
  Client client = Client();
  Databases? db;

  UserService() {
    _init();
  }

  //initialize the application
  _init() async {
    //init code goes here
  }

  Future createSubscription() async {
    Functions functions = Functions(client);
    try {
      var result =
          await functions.createExecution(functionId: AppConstant().functionId);
      return result;
    } catch (e) {
      throw Exception('Error creating subscription');
    }
  }

  Future<User> getUserDetails() async {
    try {
      var data = await db?.getDocument(
          databaseId: AppConstant().databaseId,
          collectionId: AppConstant().collectionId,
          documentId: AppConstant().userId);
      var user = data?.convertTo((doc) => User.fromJson(doc));
      return user!;
    } catch (e) {
      throw Exception('Error getting user details');
    }
  }

  Future subscribeUser(String name) async {
    try {
      User updateUser = User(name: name, is_subscribed: true);
      var data = await db?.updateDocument(
        databaseId: AppConstant().databaseId,
        collectionId: AppConstant().collectionId,
        documentId: AppConstant().userId,
        data: updateUser.toJson(),
      );
      return data;
    } catch (e) {
      throw Exception('Error subscribing user');
    }
  }

  Future unSubscribeUser(String name) async {
    try {
      User updateUser = User(name: name, is_subscribed: false);
      var data = await db?.updateDocument(
        databaseId: AppConstant().databaseId,
        collectionId: AppConstant().collectionId,
        documentId: AppConstant().userId,
        data: updateUser.toJson(),
      );
      return data;
    } catch (e) {
      throw Exception('Error unsubscribing user');
    }
  }
}
```

**Consuming the Service**
With that done, we can start using the service to perform the required operation. To get started, we need to open the `main.dart` file in the same `lib` directory and update it by doing the following:

First, we need to import the required dependencies and create a method to get users' details

```dart
import 'package:appwrite_stripe/user_service.dart';
import 'package:appwrite_stripe/utils.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  //app code goes here
  }
}

class MyHomePage extends StatefulWidget {
  //homepage code goes here
}

class _MyHomePageState extends State<MyHomePage> {
  late User user;
  bool _isLoading = false;
  bool _isFetching = false;
  bool _isError = false;

  @override
  void initState() {
    _getUserDetails();
    super.initState();
  }

  _getUserDetails() {
    setState(() {
      _isLoading = true;
    });
    UserService().getUserDetails().then((value) {
      setState(() {
        user = value;
        _isLoading = false;
      });
    }).catchError((e) {
      setState(() {
        _isLoading = false;
        _isError = true;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    //UI code goes here
  }
}
```

The snippet above does the following:

- **Line 1-3**: Imports the required dependencies
- **Line 18-21**: Creates the `user`, `_isLoading`, `_isFetching`, and `_isError` properties to manage application state
- **Lines** **23-44**: Creates a `_getUserDetails` method to get the user details using the `UserService().getUserDetails` service, set states accordingly, and use the `initState` method to call the `_getUserDetails`

Secondly, we need to add methods to manage subscriptions as shown below:

```dart
//import goes here

void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  //app code goes here
  }
}

class MyHomePage extends StatefulWidget {
  //homepage code goes here
}

class _MyHomePageState extends State<MyHomePage> {
  //properties go here

  @override
  void initState() {
    _getUserDetails();
    super.initState();
  }

  _getUserDetails() {
    //code goes here
  }

  _subscribe(String name) {
    setState(() {
      _isFetching = true;
    });
    UserService().createSubscription().then(
      (value) {
        UserService().subscribeUser(name).then((value) {
          setState(() {
            _isFetching = false;
            user.is_subscribed = true;
          });
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Subscribed successfully!')),
          );
        }).catchError((e) {
          setState(() {
            _isFetching = false;
          });
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Error processing payment!')),
          );
        });
      },
    ).catchError((e) {
      setState(() {
        _isFetching = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Error processing payment!')),
      );
    });
  }

  _unsubscribe(String name) {
    setState(() {
      _isFetching = true;
    });
    UserService().unSubscribeUser(name).then((value) {
      setState(() {
        _isFetching = false;
        user.is_subscribed = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Unsubscribed successfully!')),
      );
    }).catchError((e) {
      setState(() {
        _isFetching = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Error unsubscribing!')),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    //UI code goes here
  }
}
```

The snippet above does the following:

- **Lines** **28-59**: Creates a `_subscribe` that takes in `name` as a parameter, uses the `UserService().createSubscription` and `UserService().subscribeUser` to process the payment using the Appwrite function, and updates the details of the subscription on the database.
- **Lines** **61-81**: Creates an `_unsubscribe` that takes in `name` as a parameter, uses the `UserService().unSubscribeUser` service to cancel the subscription, and updates the details of the subscription on the database

Lastly, we need to modify the UI to conditionally show the subscribe and unsubscribe and use the appropriate method.

```dart
//import goes here

void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  //app code goes here
  }
}

class MyHomePage extends StatefulWidget {
  //homepage code goes here
}

class _MyHomePageState extends State<MyHomePage> {
  //properties go here

  @override
  void initState() {
    _getUserDetails();
    super.initState();
  }

  _getUserDetails() {
    //code goes here
  }

  _subscribe(String name) {
    //code goes here
  }

  _unsubscribe(String name) {
    //code goes here
  }

  @override
  Widget build(BuildContext context) {
    return _isLoading
        ? const Center(
            child: CircularProgressIndicator(
            color: Colors.blue,
          ))
        : _isError
            ? const Center(
                child: Text(
                  'Error getting users details',
                  style: TextStyle(
                    color: Colors.red,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              )
            : Scaffold(
                body: Center(
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      const Image(image: AssetImage('images/subscription.png')),
                      const SizedBox(height: 20),
                      const Text(
                        'Manage subscription',
                        style: TextStyle(
                            fontSize: 20.0, fontWeight: FontWeight.bold),
                      ),
                      const SizedBox(height: 20),
                      const Text(
                        'By subscribing to our service, we will deliver newspaper to you weekly',
                        style: TextStyle(fontSize: 16),
                        textAlign: TextAlign.center,
                      ),
                      const SizedBox(height: 20),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: SizedBox(
                          height: 45,
                          width: double.infinity,
                          child: user.is_subscribed
                              ? const SizedBox()
                              : TextButton(
                                  onPressed: _isLoading
                                      ? null
                                      : () {
                                          _subscribe(user.name);
                                        },
                                  style: ButtonStyle(
                                    backgroundColor:
                                        MaterialStateProperty.all<Color>(
                                            Color(0xff1C4ED8)),
                                  ),
                                  child: const Text(
                                    'Subscribe to newspaper',
                                    style: TextStyle(
                                      color: Colors.white,
                                      fontWeight: FontWeight.bold,
                                      fontSize: 14.0,
                                    ),
                                  ),
                                ),
                        ),
                      ),
                      const SizedBox(height: 5),
                      user.is_subscribed
                          ? TextButton(
                              onPressed: _isLoading
                                  ? null
                                  : () {
                                      _unsubscribe(user.name);
                                    },
                              child: const Text(
                                'Unsubscribe',
                                style: TextStyle(
                                    fontSize: 16,
                                    color: Colors.black87,
                                    fontWeight: FontWeight.bold),
                              ))
                          : const SizedBox()
                    ],
                  ),
                ),
              );
  }
}
```

With that done, we restart the application using the code editor or run the command below:

```bash
flutter run
```


![](https://media.giphy.com/media/LBWeGYmcmfAF7AhaRI/giphy.gif)


[https://media.giphy.com/media/LBWeGYmcmfAF7AhaRI/giphy.gif](https://media.giphy.com/media/LBWeGYmcmfAF7AhaRI/giphy.gif)

We can validate the subscription by checking the Appwrite Function **Executions** tab and Stripe **Log** tab.

![Appwrite Execution tab](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671401262533_Screenshot+2022-12-17+at+22.24.04.png)
![Stripe Log tab](https://paper-attachments.dropboxusercontent.com/s_1F2738109066A0A5582E754A3908A7FD06BE17296D17A867AFE208C1CA00E9C0_1671401262502_Screenshot+2022-12-17+at+22.22.47.png)



# Conclusion

This post discussed how to create a newspaper subscription service in Flutter using Stripe and Appwrite Functions. Appwrite Function offers developers the flexibility of building applications in an isolated environment.

These resources may be helpful:

- [Appwrite official documentation](https://appwrite.io/docs?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Flutter SDK](https://appwrite.io/docs/getting-started-for-flutter?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Function](https://appwrite.io/docs/functions?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Stripe payment intent](https://stripe.com/docs/payments/payment-intents)
- [Stripe payment guide](https://stripe.com/docs/payments)