見出し画像

Stripeのサブスク機能をスプレッドシートをデータベースにGAS (Google Apps Script) で実装する方法

割引あり

Googleスプレッドシートをデータベースに、Stripe × GASというとっつきやすい開発ツールでサブスクリプション契約の機能の実装方法です!

Stripeのアカウントをお持ちでない方は事前にユーザ登録をお願いします!

プログラム

スプレッドシートを新規作成したら、上のメニューバーの「拡張機能」から「Apps Script」を作成してください。

今回は、2つのスクリプトファイルを使用します。「コード.gs」と「設定.gs」として、それぞれ下記のプログラムを貼り付けてください。

動画内で使用したスプレッドシートをコピーして使用しても大丈夫です!
https://docs.google.com/spreadsheets/d/1stnX942-kMrf1tsz5IFBeMPx91gRhQWACCBLag8qnRQ/copy

コード.gs

// Stripeのサブスクリプション登録情報とデータベースの整合性をとる https://stripe.com/docs/api/subscriptions
function checkSubscriptionStatus() {
  const options = {
    headers: {
      Authorization: "Bearer " + STRIPE_SECRET,
    },
    method: "get",
    muteHttpExceptions: true
  };
  for(i = 1; i < SUBSCRIBE_USER_ROW_NUM; i++) {
    const url = `https://api.stripe.com/v1/subscriptions/${SUBSCRIBE_USER_VALUES[i][3]}`;
    const response = UrlFetchApp.fetch(url, options); // レスポンス取得
    const subscription = JSON.parse(response.getContentText()); // ステータス取得
    const status = subscription.status || "error";
    const canseleStatus = subscription.cancel_at_period_end;
    const cell = SUBSCRIBE_USER_RANGE.getCell(i + 1, 5); // Subscription Status
    let result;
    if(status != "active") {
      result = "inactive"; // 解約済み or 何か問題があったらステータスを inactive に変更
    } else if (canseleStatus) {
      result = "canceled"; // cancel_at_period_end が true の時 canceled に変更
    } else {
      result = "active";
    }
    cell.setValue(result); // 解約済み or 何か問題があったらステータスを inactive に変更
  }
}

// Stripeのwebhook
function doPost(e) {  
  let body = JSON.parse(e.postData.contents);

  if(body.type) {
    const eventType = body.type; // Webhookの種類を判別
    const data = body.data.object; // 取得したデータの中身
    if (eventType == "checkout.session.completed")
      createSubscription(data) // 支払いが完了した場合の処理
    if (eventType == "customer.subscription.updated")
      updateSubscription(data); // サブスクリプションステータスが変更された場合の処理
    SUBSCRIBE_LOG_SHEET.appendRow([Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd HH:mm:ss"), eventType, data, body]); // ログを残す
  }
}

// 支払いが完了した場合の処理
function createSubscription(data) {
  const customerId = data.customer;
  const subscriptionId = data.subscription;
  const date = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd HH:mm:ss");
  
  // PAYMENT LINK が正しいかどうか
  const pLink = data.payment_link;
  if (!PAYMENT_LINKS.includes(pLink))
    return;

  // 既にユーザーが存在しているかどうかチェック
  for(i = 0; i < SUBSCRIBE_USER_ROW_NUM; i++)
    if((SUBSCRIBE_USER_VALUES[i][2] == customerId && SUBSCRIBE_USER_VALUES[i][3] == subscriptionId))
      return;
  const email = data.customer_details.email;
  SUBSCRIBE_USER_SHEET.appendRow(["", email, customerId, subscriptionId, "active", date, date, "", pLink]);
}

// サブスクリプションステータスが変更された場合の処理
function updateSubscription(data) {
  const customerId     = data.customer;
  const subscriptionId = data.id;
  const cancel_check   = data.cancel_at_period_end;
  const date = Utilities.formatDate(new Date(), "JST", "yyyy/MM/dd HH:mm:ss");

  for(i = 0; i < SUBSCRIBE_USER_ROW_NUM; i++) {
    if((SUBSCRIBE_USER_VALUES[i][2] == customerId && SUBSCRIBE_USER_VALUES[i][3] == subscriptionId)) {
      let statusCell = SUBSCRIBE_USER_RANGE.getCell(i + 1, 5); // 5行目 Subscription Status
      let updateDateCell   = SUBSCRIBE_USER_RANGE.getCell(i + 1, 6); //	6行目 updated_at
      let cancelDateCell   = SUBSCRIBE_USER_RANGE.getCell(i + 1, 8); // 8行目 canceled_at
      if (cancel_check) {
        statusCell.setValue("canceled");
        cancelDateCell.setValue(date);
      } else {
        statusCell.setValue("active");
      }
      updateDateCell.setValue(date);
      break;
    }
  }
}

設定.gs

// Stripeの設定
// テスト環境
const STRIPE_SECRET = 'sk_test_****************';
const PORTAL_SITE   = `https://billing.stripe.com/p/login/test_****************`;
const PAYMENT_LINKS = [`plink_****************`];
// 本番環境
// const STRIPE_SECRET = 'sk_live_****************';
// const PORTAL_SITE  = `https://billing.stripe.com/p/login/****************`;
// const PAYMENT_LINKS = [`plink_****************`];

// スプレッドシートとの連携部分
const SHEET_ID = "*********************************";
const SUBSCRIBE_USER_SHEET   = SpreadsheetApp.openById(SHEET_ID).getSheetByName("Stripeユーザリスト");
const SUBSCRIBE_USER_ROW_NUM = SUBSCRIBE_USER_SHEET.getLastRow();
const SUBSCRIBE_USER_RANGE   = SUBSCRIBE_USER_SHEET.getRange(1, 1, SUBSCRIBE_USER_ROW_NUM, 9);
const SUBSCRIBE_USER_VALUES  = SUBSCRIBE_USER_RANGE.getValues();
const SUBSCRIBE_LOG_SHEET    = SpreadsheetApp.openById(SHEET_ID).getSheetByName("Stripeログ");

スプレッドシートの設定

スプレッドシートのURL部分には、唯一無二の ID となっている部分があります。それを、SHEET_ID に定義してください。

また、「Stripeユーザリスト」と「Stripeログ」というシートを、同じスプレッドシート内に作る必要があります。

詳しくは、動画内でも解説していますので、お手数ですがこの説明でわからなければ、動画をご参照ください!

ストライプの設定

  1. シークレットキーの発行

下記URLからシークレットキーをコピーして、STRIPE_SECRET に定義してください。
テスト環境:https://dashboard.stripe.com/test/apikeys
本番環境:https://dashboard.stripe.com/apikeys

 2. ポータルサイトの発行

次に、下記URLからカスタマーポータルリンクを発行後、URLをコピーして、PORTAL_SITE に定義してください。
テスト環境:https://dashboard.stripe.com/test/settings/billing/portal
本番環境:https://dashboard.stripe.com/settings/billing/portal

 3. ペイメントリンクの発行

次に、下記URLの右上「商品を追加」からサブスクリプションの商品を保存します。
テスト環境:https://dashboard.stripe.com/test/products
本番環境:https://dashboard.stripe.com/products

保存後、商品画面も右下辺りにある「支払いリンクを表示」をクリックし、URLの plink_ 以降をコピーして、PAYMENT_LINKS に定義してください。ちなみに、この画面にある支払いリンクから、実際にクレジットカード番号を「4242 4242 4242 4242」にしてテスト決済することができます。

これで、プログラムは完成です。

デプロイ

Apps Script 画面の右上にある「デプロイ」から、URLを発行できます。
発行したURLを、ストライプの開発者ページにある Webhook のエンドポイントに追加します。
テスト環境:https://dashboard.stripe.com/test/webhooks
本番環境:https://dashboard.stripe.com/webhooks

また、送信イベントには、下記2つのイベントを追加してください。

これで設定は全て完了です。
支払いリンクから、クレジットカード番号を「4242 4242 4242 4242」にしてテスト決済をしてみて、スプレッドシートの「Stripeユーザリスト」に決済の情報が記載されれば成功です。

次のステップ

LINE × Stripe × GAS イベント(無料)

2023年10月27日(金)20:00〜、LINE Developers Community ( #linedc )にてマネタイズハンズオン、Stripe × GAS でサブスクリプション(月額課金)に挑戦します。
オフラインでも実施しますので、東京にいてお時間ある方は現地までお越しいただけると嬉しいです!

サブスク機能付きLINE公式アカウント『Liebe(リーベ)』

LINEだけで入会できる結婚相談所です。全てオンライン完結なので、国内最安値で婚活を始めることができるサービスです。決済は、Stripeを使用しています。まずは「恋人診断」だけでも楽しいと思うので、お気軽に友だち登録してください。

《PR》 Udemy講座『ChatGPT API で LINE BOTつくろう』

ChatGPT を使用したLINE公式アカウントに興味がある人におすすめの講座です。

▼無料クーポンコード記載してますので、お気軽に受講ください↓↓↓

ここから先は

46字

この記事が気に入ったらサポートをしてみませんか?