torikatsu.dev

Flutterとかプログラミングとかガジェットとか書きます

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

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

はじめに

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


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

リポジトリ

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

Stripeの決済の流れ

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

payment intent

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

payment method

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

confirm payment

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

支払い方法をとてもざっくり捉えると、支払いのセッションID(payment intent)と支払い方法(payment method)を用いて支払いを確定(payemnt confirm)させます。 https://stripe.com/img/docs/payments/accept-a-payment-web.png stripe.com

Flutterでの実装

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

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-Typeapplication/jsonではなく、application/x-www-form-urlencodedだということです。 私はjsonと勘違いして時間を溶かしまくりました() jsonではないのでpayment_method_typespayment_method_types[]になることに注意です。

payment methodの作成

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

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

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

f:id:torikatsu923:20210417022857p:plain
いい感じのクレジットカード情報入力画面

以下はいい感じのクレジットカード情報入力画面を表示しつつ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はすごいなと改めて思いました。

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