stripeでプロモーションコード割引を実装する
Flutter大学で割引を行いたい時に、プロモーションコードを配布する試みを最近スタートしました。
実はこれまでは割引用の商品を新たにつくって切り替えていたんですが、どんどん商品数が増えて複雑になったり、切り替えの機構をコーディングする必要があったりと、何かと運用的に微妙だなと思い、プロモーションコード機能を使う運用に切り替えました。
結論としては、非常に使いやすいです。実装も楽です。
プロモーションコードを作成方法
stripeの管理画面で、商品>クーポンと進んで、新規作成します。

クーポンを作った後に、その下にプロモーションコードを作るイメージです。
ここの新規作成のフローは難しくないので、説明を省きます。
決済の実装
2つの例を紹介します。Stripe Checkoutの場合とsubscription.updateの場合です。
Stripe Checkoutを使う場合
Stripe CheckoutのURL作成方法は、以下の記事にもまとめました。
使うAPIは以下です。
プロモーションコードを適用するために必要なことは、このcheckoutSessionのparamに         'allow_promotion_codes': true を追加するだけです。
      final checkoutSession = {
        'customer': customerId,
+       'allow_promotion_codes': true,
        'billing_address_collection': 'auto',
        'success_url': successUrl,
        'cancel_url': cancelUrl,
        'mode': mode,
        'line_items': [
          {
            'price': priceId,
            'quantity': 1,
          },
        ],
      };
これをやると、以下のように、stripe checkoutを開いた時にプロモーションコードを入れる欄が出てきます。

このようにStripe Checkoutの方で対応するのは簡単です。
APIでsubscription.updateする場合
難しいのは、subscriptionを日割りも適用してアップグレードしたりする際です。
差額の計算については以下記事に書いてあります。
この場合、Stripe Checkoutで 'allow_promotion_codes': true を追加するみたいにしてparameterに 'promotion_code': 'GW2023', と追加して適用できたらいいのですが、promotion_codeというprameterはありません。
以下のAPIを見たらわかるかと思います。
しかし、promotion_codeがないかわりにcouponというprameterが渡せます。
前述の通り、直接promotion_codeを渡して、割引を適用するというのができないので、「まずはpromotion_codesの一覧のAPIを使って一覧を取得した後に、その中に渡されたpromotion_codeと一致するかを確認し、あったらそのpromotion_codeのobjectに入っているcoupon.idを返してあげるAPI」を作ってフロントから呼び出し、一致してたらそのcoupon.idを使うというアプローチを今回取りました。
Flutter大学の場合は、以下のようなfunctionをfirebase functionsにデプロイして、Flutter Webで呼び出すようにしています。
export const searchPromotionCode = functions.region('asia-northeast1').https.onCall(async (data, context) => {
    const promotionCodePassed = data.promotionCode;
    const promotionCodes = await stripe.promotionCodes.list();
    const searchedCode = promotionCodes.data.find((promoCode) => promoCode.code === promotionCodePassed);
    return searchedCode?.coupon.id;
});
呼び出し側のFlutterのコードはこんな感じ。
  Future<String> searchPromotionCode(String code) async {
    final result = await _functionsRepository.call(
      functionName: 'stripe-searchPromotionCode',
      parameters: {
        'promotionCode': code,
      },
    );
    return result.data; // couponId
  }
  
  // このcouponIdをsubscription.updateのparamに渡して割引を適用してプランのアップグレードを行う
  final couponId = await searchPromotionCode(code);
  
こんな流れで最終的には以下のAPIでプランをアップデートさせてます。
まとめ
以上、stripeを使ったサービスでプロモーションコードを適用させる方法でした。
ということで、Flutter大学では、ゴールデンウィーク限定で、「GW2023」というプロモーションコードを入れると対象プランが1100円安くなるキャンペーンをやってますの。GWにFlutterを頑張る方はぜひご利用ください!
今回の方法で実装されてます!コード見たい方もFlutter大学はいると見れますので是非!
Discussion