【Stripe】ダッシュボードで作成した商品のCheckout決済を実装する

決済サービスのStripeでは様々な方法で決済を導入できますが、ここではダッシュボードで作成した商品をCheckoutで決済させるパターンの実装をいろいろ検討します。

    ダッシュボードで商品を作成

    事前にダッシュボード上で商品→料金を作成しておきます。

    Checkout クライアント専用組み込み のCheckout スニペットジェネレータを使う

    最も簡単な方法。出力されるコードをコピペするだけ。

    Checkout クライアント専用組み込み で redirectToCheckout の line_items[price] に 商品→料金の API ID を渡す

    ボタンをカスタマイズしたり、redirectToCheckoutに投げる値をいろいろやりたい場合はスニペットジェネレータで出力されるコードに手を加えるか、ドキュメントを参考にJavaScriptを書きます。商品はIDを設定するだけで簡単に設定できます。

    JavaScript
    <script src="https://js.stripe.com/v3"></script>
      <button id="checkout-button">購入</button>
      <div id="error-message"></div>
      <script>
      (function() {
        var stripe = Stripe('public_key');
        var checkoutButton = document.getElementById('checkout-button');
        checkoutButton.addEventListener('click', function () {
          stripe.redirectToCheckout({
            lineItems: [{price: 'PRICE_ID', quantity: 1}],
            mode: 'payment',
            successUrl: 'https://example.com/success',
            cancelUrl: 'https://example.com/canceled',
          })
          .then(function (result) {
            if (result.error) {
              var displayError = document.getElementById('error-message');
              displayError.textContent = result.error.message;
            }
          });
        });
      })();
      </script>
    

    ところでジェネレーターでsuccessUrl/cancelUrlのデフォルト設定が https://your-website.com になってるのは大丈夫なのか…?調べるとオークションで売りに出されていた(500万円~!)

    Checkout Session を作成する(Checkout クライアントおよびサーバ組み込み)

    Checkout クライアントおよびサーバ組み込みのドキュメントで案内されている Checkout Session を作成する際、line_items[price] に PRICE_ID を渡す方法です。

    サーバー側でCheckout Session を作成する場合は、クーポン利用の設定などができます。

    PHP
    <?php
    $public_key = XXXX;
    $secret_key = XXXX;
    $price_id   = XXXX;
    $mode       = 'payment';
    
    \Stripe\Stripe::setApiKey($secret_key);
    $session = \Stripe\Checkout\Session::create([
      'payment_method_types' => ['card'],
      'line_items' => [[
      		'price' => $price_id,
      		'quantity' => 1,
      ]],
      'mode' => $mode,
      'success_url' => 'https://example.com/success',
      'cancel_url' => 'https://example.com/cancel',
    ]);
    
    $session_id = $session->id;
    }
    ?>
    
    <script src="https://js.stripe.com/v3"></script>
    <button id="checkout-button">購入</button>
    <div id="error-message"></div>
    <script>
    (function() {
      var stripe = Stripe('<?php echo $public_key ?>');
      var checkoutButton = document.getElementById('checkout-button');
      checkoutButton.addEventListener('click', function () {
        stripe.redirectToCheckout({ sessionId: '<?php echo $session_id; ?>' })
        .then(function (result) {
          if (result.error) {
            var displayError = document.getElementById('error-message');
            displayError.textContent = result.error.message;
          }
        });
      });
    })();
    </script>
    

    入会金(初期費用)+月額の決済

    Stripe Checkout では複数の料金をセッションに含めることができます。

    例えば一括払いの商品と継続払いの商品の両方をセットすることで、入会金(初期費用)+月額のような料金体系を作ることができます。

    決済画面には料金のタイトルではなく商品名が表示されるので、商品を分けて登録するほうが見た目には分かりやすいのかなと思います。

    なお、複数の定額課金をセットすることもできますが、支払期間が異なる場合はエラーになるようです。

    jsでセットする場合(Checkout クライアント専用組み込み)

    JavaScript
    lineItems: [
      {price: '{ PRICE ID 1 }', quantity: 1},
      {price: '{ PRICE ID 2 }', quantity: 1},
    ]
    

    セッションを作る場合(Checkout クライアントおよびサーバ組み込み)

    PHP
    $line_items = [
      [
        'price' => { PRICE ID 1 },
        'quantity' => 1,
      ],
      [
        'price' => { PRICE ID 2 },
        'quantity' => 1,
      ]
    ];
    

    クーポンを適用する

    クーポンコードの入力欄を追加する

    セッション作成時にallow_promotion_codesをtrueにすると、checkoutの画面にクーポンコード入力欄を表示することができます。

    PHP
    <?php
    \Stripe\Stripe::setApiKey($secret_key);
    $session = \Stripe\Checkout\Session::create([
      'payment_method_types' => ['card'],
      'line_items' => [[
      		'price' => $price_id,
      		'quantity' => 1,
      ]],
      'mode' => 'payment',
      'allow_promotion_codes' => true,
      'success_url' => 'https://example.com/success',
      'cancel_url' => 'https://example.com/cancel',
    ]);
    

    セッション作成時にクーポンを設定する

    定期課金の場合はセッションにクーポンを含めることができます。modesubscriptionにする必要があり、その他の値の時にsubscription_dataを指定するとエラーになりました。比較的新しい機能なのか、APIのドキュメントには載っていませんでした。

    PHP
    $session = $stripe->checkout->sessions->create([
      'payment_method_types' => ['card'],
      'line_items' => [[
        'price' => { PRICE ID 1 },
        'quantity' => 1,
      ]],
      'mode' => 'subscription',
      'success_url' => 'https://example.com/success',
      'cancel_url' => 'https://example.com/cancel',
      'subscription_data' => ['coupon' => 'XXXX'],
    ]);
    

    セッション作成時のエラーを受け取る

    PHP
    try {
      $session = $stripe->checkout->sessions->create([
          'payment_method_types' => ['card'],
          'line_items' => $line_items,
          'mode' => 'payment',
          'success_url' => 'https://example.com/success',
          'cancel_url' => 'https://example.com/cancel',
      ]);
      $session_id =  $session->id;
    } catch (\Stripe\Exception\ApiErrorException $e) {
      $error = $e->getError();
    }
    

    注意

    「標準的な料金体系」のみ対応

    「標準的な料金体系」以外はCheckoutに対応してないようなので、Stripe Elementsを使って自前でフォームを実装する必要がありそうです。

    If you want to use tiers, you need to use Stripe Elements to collect payment information (Checkout doesn’t support metered billing or tiers). See the metered billing or per-seat guides for more details.

    Tiers

    税率設定

    非対応と聞いていたのですが、いつの間にかドキュメントがアップデートされてベータ版で税率設定の項目が追加されていました。

    Webhookで押さえておくイベント

    管理画面の「開発者」→「Webhook」でエンドポイントを定義すると、指定したイベントが発火したタイミングで登録したURLにイベントが飛びます。

    checkout.session.completed

    Checkout決済完了時に発火。セッション作成時にclient_reference_idを設定しておくと、遷移元のページのID等を受け取ることができる。

    invoice.payment_failed

    サブスクリプション課金で決済に失敗した際に発火。該当のinvoiceオブジェクトが通知される。

    シェア
    野良人 代表
    新免祥太
    1988年岡山生まれ。外食企業のWEB・EC担当を経験したのち、2013年12月より「野良人(のらんど)」の屋号で独立しWEBデザイン・プログラミングなどWEBサイト制作の工程全般を請け負っています。お気軽にご相談ください。
    広告
    <次の記事(2020/12/31)
    【WordPress】コメントのカスタマイズ
    前の記事>(2020/12/31)
    reCAPTCHA v3の認証エラー(timeout-or-duplicate)対応
    記事一覧