Search code examples
firebaseflutterstripe-paymentse-commerce

Is there a way to create monthly subscription via flutter and stripe?


I am creating an app for my practice with monthly subscriptions and each subscription. I have already combined it with firebase. The regular purchase part is done, however I've no idea about how to handle monthly subscriptions in flutter-stripe. There is already code available in stripe-docs here in node, C#, Go, python etc. Here's the link: https://stripe.com/docs/billing/subscriptions/checkout/fixed-price; genuinely speaking, I'm not understanding these codes. That's why I want to know that is there anyway to make recurring payment via the flutter-stripe duo. If there is, then please tell me. Here's the code for only one time purchase:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:stripe_payment/stripe_payment.dart';
import 'package:cloud_functions/cloud_functions.dart';

class StripeService{
  final HttpsCallable intent = FirebaseFunctions.instance.httpsCallable('createPaymentIntent');
  User user;
  DocumentReference userDocReference;

  StripePayments(this.user) {
    user != null ? userDocReference = FirebaseFirestore.instance.collection("User").doc(user.uid)
    : user = FirebaseAuth.instance.currentUser;
    userDocReference = FirebaseFirestore.instance.collection("User").doc(user.uid);
  }

  startPaymentProcess(double amount) {
    StripePayment.paymentRequestWithCardForm(CardFormPaymentRequest()).then((paymentMethod) {
      amount *= 100.0; // multipliying with 100 to change $ to cents
      intent.call(<String, dynamic>{'amount': amount, 'currency': 'usd'}).then(
          (response) {
            _cnfrmPayment(response.data["client_secret"],
            paymentMethod); //function for confirmation for payment
      });
    });
  }

  _cnfrmPayment(String clientSecret, PaymentMethod paymentMethod, context) {
    StripePayment.confirmPaymentIntent(PaymentIntent(
      clientSecret: clientSecret,
      paymentMethodId: paymentMethod.id,
   )
  ).then((intentResult) {
      userDocReference.set({
        "status": intentResult.status,
        "paymentMethodId": intentResult.paymentMethodId,
        "paymentIntentId": intentResult.paymentIntentId
      });
      Scaffold.of(context).showSnackBar(
        SnackBar(
          content: Text("Payment done successfully")
        )
      );
    });
  }

  confirmDialog(String clientSecret, PaymentMethod paymentMethod, context) {
    var confirm = AlertDialog(
      title: Text("Confirm Payement"),
      content: Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text(
              "Make Payment",
              style: TextStyle(fontSize: 25),
            ),
            Text("Charge amount:\$100")
          ],
        ),
      ),
      actions: <Widget>[
        RaisedButton(
          child: Text('CANCEL'),
          onPressed: () {
            Navigator.of(context).pop();
            final snackBar = SnackBar(
              content: Text('Payment Cancelled'),
            );
            Scaffold.of(context).showSnackBar(snackBar);
          },
        ),
        RaisedButton(
          child: new Text('Confirm'),
          onPressed: () {
            Navigator.of(context).pop();
            _cnfrmPayment(
            clientSecret, paymentMethod); // function to confirm Payment
          },
        ),
      ],
    );
    showDialog(
        context: context,
        barrierDismissible: false,
        builder: (BuildContext context) {
          return confirm;
        }
     );
  }
}

My firebase function which I've copied from this https://medium.com/@hamza39460/stripe-payments-in-flutter-cb2f9cb053d1 medium post. I've deployed this function in node 8, since node >= 10 run only on blaze plan in firebase and I am a student. Here's full code:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

const firestore = admin.firestore();
const settings = { timestampInSnapshots: true };
firestore.settings(settings)
const stripe = require('stripe')('MY_STRIPE_SECRET_KEY');
exports.createPaymentIntent = functions.https.onCall((data, context) => {
    return stripe.paymentIntents.create({
        amount: data.amount,
        currency: data.currency,
        payment_method_types: ['card'],
    });
});

Solution

  • I believe there is an existing package that you can use to implement this kind of function.

    flutter_stripe:

    The Stripe Flutter SDK allows you to build delightful payment experiences in your native Android and iOS apps using Flutter. We provide powerful and customizable UI screens and elements that can be used out-of-the-box to collect your users' payment details.

    You can also follow this blog for some helpful guide on implementing payments using the package.