torikatsu923.dev

サイト内検索

    flutter+Stripeでクレジットカード決済をさくっと作る

    個人開発をしていると、自身のプロダクトを収益化したい欲に駆られることがあります。お金を扱う関係上、決済システムには高い厳密さとセキュリティ要件が求められます。

    こんにちは、とりかつ@torikatsu923です。 今回はFlutter+Stripeでサクッとクレジットカード決済を実装する方法を紹介したいと思います

    はじめに

    個人開発をしていると、自身のプロダクトを収益化したい欲に駆られることがあります。 お金を扱う関係上、決済システムには高い厳密さとセキュリティ要件が求められます。 それゆえ、決済システムを自前で実装しようとした場合、決済の導入はハードルが高いものとなります。


    世の中には決済システムを提供してくれるサービス(PaaS)が存在します。 PaaSを使用することで、プロダクトへ決済を導入するハードルを大きく下げることができます。 今回の記事では、Stripeを使用してFlutter製アプリに決済を導入する方法を紹介していきます。 本記事ではわかりそうでわからない、でもわかった気になれるぐらいにざっくりと解説をしていきます。 正確な解説を求める方は以下の公式ドキュメントを参照することをお勧めします。

    Stripe API reference – Errors

    リポジトリ

    サンプルは以下のリポジトリです。

    torikatsupg/stripe_payment_sample

    Stripeの決済の流れ

    Stripeの登場人物は以下の3つです。

    payment intent

    とても雑に理解すると、様々な情報を含んだ決済のセッションIDのようなやつです。

    payment method

    クレジットカードや銀行振り込みなど具体的な支払い方法です。

    confirm payment

    payment intentとpayment methodを用いて決済を確定させます。

    支払い方法をとてもざっくり捉えると、支払いのセッションID(payment intent)と支払い方法(payment method)を用いて支払いを確定(payemnt confirm)させます。 stripe.com

    Flutterでの実装

    FlutterでStripeの決済を実装する際は以下のコミュニティ公式パッケージを使用します。

    stripe_payment | Flutter Package

    Stripe SDKの初期化

    初めにStripeの公開可能キーを使用してStripeのSDKを初期化します。

    ここではStripeがテスト用に用意している以下の公開可能キーを使用します。

    pk_test_51IflCeLOGgN8A203ILklq6uYJPxz2bB2gH1IavQ9C1SEg9sU1cCCYJRlJzt3ZbIF6jJ6zvFwebYNvHvwz4BZVOs400iX7GJNBn
    const publishableKey =
            'pk_test_51IflCeLOGgN8A203ILklq6uYJPxz2bB2gH1IavQ9C1SEg9sU1cCCYJRlJzt3ZbIF6jJ6zvFwebYNvHvwz4BZVOs400iX7GJNBn';
        StripePayment.setOptions(
          StripeOptions(
            publishableKey: publishableKey,
            merchantId: 'Test',
            androidPayMode: 'test',
          ),
        );

    payment intentの取得

    まず、https://api.stripe.com/v1/payment_intentsへpostし、payment intentを取得します。 payment intentの取得にはheaderにStripeのシークレットキーを含める必要があります。 今回はテスト用に用意された以下のシークレットキーを使用します。

    sk_test_51IflCeLOGgN8A203RTe6H6aYhGl5drdcPpZJ9B936U3QRHCDuUUWtjQdi4Kud3HWXXpg3YJjdRrVpNem9aNYOacr00uWaWRM6p

    以下はpostしてpayment intentを取得するコードです。

        final paymentEndpoint = Uri.https('api.stripe.com', 'v1/payment_intents');
        const secretKey =
            'sk_test_51IflCeLOGgN8A203RTe6H6aYhGl5drdcPpZJ9B936U3QRHCDuUUWtjQdi4Kud3HWXXpg3YJjdRrVpNem9aNYOacr00uWaWRM6p';
    
        final headers = <String, String>{
          'Authorization': 'Bearer $secretKey',
          'Content-Type': 'application/x-www-form-urlencoded',
        };
    
        final body = <String, dynamic>{
          'amount': '2000',
          'currency': 'jpy',
          'payment_method_types[]': 'card',
        };
    
        final response = await http.post(
          paymentEndpoint,
          headers: headers,
          body: body,
        );
    
        final paymentIntent = jsonDecode(response.body);

    ここでハマったのが、Content-Typeがapplication/jsonではなく、application/x-www-form-urlencodedだということです。 私はjsonと勘違いして時間を溶かしまくりました() jsonではないのでpayment_method_typesはpayment_method_types[]になることに注意です。

    payment methodの作成

    payment methodを作成する際は、Stripe SDKに用意されたメソッドを使用します。

    その場でクレジットカード情報を入力してpayment methodを作成する場合はStripePayment.paymentRequestWithCardFormを、既存のクレジットカード情報(CreditCardクラス)を利用する場合はStripePayment..createPaymentMethodを使用します。

    StripePayemnt.paymentRequestWithCardFormを利用するといい感じのクレジットカード情報入力画面を表示してくれます。

    いい感じのクレジットカード情報入力画面

    以下はいい感じのクレジットカード情報入力画面を表示しつつpayment methodを作成するコードです。

    final paymentMethod = await StripePayment.paymentRequestWithCardForm(
      CardFormPaymentRequest(),
    );

    以下は既存のクレジットカード情報を利用してpayment methodを作成するコードです。

    final paymentMethod = await StripePayment.createPaymentMethod(
          PaymentMethodRequest(card: creditCard),
    );

    必要に応じて使い分けてください。

    決済の確定

    決済を確定させるにはStripePayment.confirmPaymentを使用します。 以下はそのコードです。

    final confirmResult = await StripePayment.confirmPaymentIntent(
      PaymentIntent(
        clientSecret: paymentIntent['client_secret'],
        paymentMethodId: paymentMethod.id,
      ),
    );

    決済周りの処理は以上になります。 あとはエラーハンドリングや決済中にローディング画面を表示したり、決済結果を知らせるスナックバーの表示をしたりして完成になります。

    おわりに

    今回の記事ではFlutterにStripeの決済を導入する方法を紹介しました。 シンプルな形のものしか実装していませんが、数ステップで安心に決済を導入できるPaaSはすごいなと改めて思いました。

    それでは良い開発ライフを

    -––