Stripe Billingの従量課金をNode.js (TypeScript)で実装する

Stripe Billingではクラウドサービスのような「使った分だけ請求する」従量課金が作れます。「ユーザー1人につき100円」のようなこともできます。 今回はNode.js(TypeScript)でこのあたりの諸々を […]

広告ここから
広告ここまで

目次

    Stripe Billingではクラウドサービスのような「使った分だけ請求する」従量課金が作れます。「ユーザー1人につき100円」のようなこともできます。

    今回はNode.js(TypeScript)でこのあたりの諸々を実装する方法をまとめました。

    プランを作る

    まずは従量課金のプランを作ります。

    今回作るプランは、「1単位10円の月額プラン」とします。

    import * as Stripe from 'stripe'
    
    const stripe = new Stripe(process.env.STRIPE_DEV_KEY as string)
    
    stripe.plans.create({
      amount: 10,
      currency: 'jpy',
      interval: 'month',
      interval_count: 1,
      product: {
        name: 'metor plan'
      },
      nickname: 'test',
      aggregate_usage: 'max',
      billing_scheme: 'per_unit',
      usage_type: 'metered',
    })
      .then(data => console.log(data))
      .catch(err => console.log(err))

    段階的に価格を変えたい場合については、QiitaにRubyで実装した記事がありますのでそちらを御覧ください。

    作成に成功すれば、Stripeのダッシュボードからプランが確認できます。

    余談ですが、現状従量課金プランはCheckout使えないみたいですね

    従量課金プランをsubscribeする

    続いて作ったプランを顧客に契約してもらいましょう。

    必要なのはcustomer idとplan idの2つです。

    stripe.subscriptions.create({
      customer: 'cus_xxxxx',
      plan: 'plan_xxxxx',
    }).then(data => console.log(data))
    .catch(err => console.log(err))

    これでOKです。ただし従量課金の場合、これだけでは1円も課金されません。なぜなら使用量をStripeに伝える必要があるからです。

    初期状態は0単位ですので1円も課金されません。

    使用量をStripeに伝える

    先程作成したsubscriptionに対して、usageRecords APIを使うことで使用量を伝えることができます。

    import * as Stripe from 'stripe'
    import moment from 'moment'
    
    const stripe = new Stripe(process.env.STRIPE_DEV_KEY as string)
    
    // 従量課金プランかどうかを判定するヘルパー関数
    const isMeteredPlan = (plan: Stripe.plans.IPlan): boolean => plan.usage_type === 'metered'
    
    // 従量課金プランをピックアップするヘルパー関数
    const findMeteredSubscriptionItem = (subscriptionItems: Stripe.subscriptionItems.ISubscriptionItem[]): Stripe.subscriptionItems.ISubscriptionItem | undefined => {
      return subscriptionItems.find(({plan}) => isMeteredPlan(plan))
    }
    
    
    const setUsage = async (subscriptionId: string, usage: number) => {
      // subscribeしているアイテムを取得
      const si = await stripe.subscriptionItems.list({
        subscription: subscriptionId
      })
      const subscriptionItems = si.data || []
      if (subscriptionItems.length < 0) throw new Error('No such subscription')
    
      // 従量課金プランをピックアップ
      const autoChargeSubscription = findMeteredSubscriptionItem(subscriptionItems)
      if (!autoChargeSubscription) throw new Error('No metered plan')
    
      // 使用量をセットする
      const result = await stripe.usageRecords.create(
        autoChargeSubscription.id,
        {
          timestamp: moment().unix(),
          quantity: usage,
          action: 'set'
        })
      
      // 使用状況を確認する
      const history = await stripe.usageRecordSummaries.list(autoChargeSubscription.id)
      console.log(history.data)
    }
    
    setUsage(subscriptionId, 6)

    ポイントはsubscriptionのidではなく、subscription itemのidが必要ということです。「定額プラン」+「従量課金のオプション」のようなsubscription体系になることもありますので、subscribeしているitemをちゃんと指定してねということでしょう。

    ちなみに上のサンプルは従量課金プランが1つであることを前提に作ってあります。なので複数の従量課金プランをsubscribeさせている場合は、findMeteredSubscriptionItem関数の判定文を「従量課金かどうか」+「追加したいplanかどうか」という判定になるように調整してください。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark