AstroCloudflareEventJavaScriptSaaS / FaaSStripe

JP_Stripes & Cloudflare Meet-up 岡山でAstro / Stripe / Cloudflare Pagesのワークショップを開催しました

AWS Samurai 2023を受賞した古里さんからのお声掛けで、StripeとCloudflareを学べるイベントに参加しました。ワークショップでは、Astro / Stripe / Cloudflare Pagesについて学びました。StripeとCloudflareの連携については、決済とメールの連携があると紹介されました。具体的なコード例も提供されました。また、サブスクリプションの申込後にユーザーアカウントを作成する方法や、決済が完了するまでの処理についても説明されました。ワークショップは好評で、AstroやStripe、Cloudflareに興味がある方は是非参加してみてください。

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

AWS Samurai 2023を受賞された古里さんからお声がけを頂きまして、StripeとCloudflareを一度に学べるイベントに参加してきました。

いつものJP_Stripesポーズ

当日のツイートまとめはTogetterにて

Astro / Stripe / Cloudflare Pagesの山盛りワークショップを開催

イベントでは、2時間の枠を頂いてワークショップを行いました。

ワークショップ資料は、Zennにて無料公開しています。

-> [Stripe x Cloudflareワークショップ] Astroを使って、サブスクリプション申し込みページを作ろう

ワークショップ内容のその先へ

Zennの資料からは諸事情で外したのですが、「こんなこともできますよ」を2-3本用意していました。

せっかくなので、こちらの記事でフォローアップとして紹介します。

CloudflareのMailChannelsを使って、顧客作成時などにメールを送信する

サブスクリプションの契約完了時にウェルカムメールを送信するなど、決済とメールの連携はよくあるケースの1つです。

例えば次のサンプルコードでは、「Stripeに顧客データが作成された(Checkout / Payment Linksなどでサブスク契約が完了した)時点で、MailChannelでメールを送信する」動きを実装しています。


            // 顧客の作成が成功した場合にトリガーされる
            case 'customer.created': {
                const customer = event.data.object
                await fetch('https://api.mailchannels.net/tx/v1/send', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        personalizations: [{
                            to: [{
                                email: customer.email,
                                name: customer.name,
                            }]
                        }],
                        from: {
                            email: import.meta.env.FROM_EMAIL,
                            name: 'XXXサービス'
                        },
                        subject: 'ようこそXXXサービスへ!',
                        content: [
                            {
                                type: 'text/plain',
                                value: `オンボーディングのためのコンテンツ`,
                            },
                        ],
                    })
                })
                break
            }

MailChannelsの使い方は、Qiitaに公開されている記事「Cloudflare Workers から MailChannels でメール送信するついでに Cloudflare Pages でコンタクトフォームを作る」をご覧ください。

Payment Links / Checkout / 料金表での注文内容・数量を取得する

料金表やPayment Links・Checkoutなどのリンク型・リダイレクト型決済フォームを利用した場合、「クロスセルによる商品の追加提案」や「決済ページでの注文数量の変更」などが行えます。

参考: Stripe Checkoutを利用した注文ページで、顧客が商品の個数を変更できるようにする

この場合、Webhookを利用して「実際に顧客が注文した商品と数量」を把握する必要があります。

料金表・Payment Links・Checkoutいずれの場合でも、checkout.session.completedcheckout.session.async_payment_succeededを利用します。

        const body = event
        switch (event.type) {
+            case 'checkout.session.completed': {
+                const session = event.data.object
+                const lineItems = await stripe.checkout.sessions.listLineItems(session.id)
+                lineItems.data.forEach(item => {
+                    const productId = typeof item.price.product === 'string' ? item.price.product : item.price.product.id
+                    console.log([
+                        `商品ID: ${productId}`,
+                        `注文数量: ${item.quantity}`,
+                        `金額: ${item.amount_total}`
+                    ].join('\n'))
+                })
                break
            }

顧客データが作成されました。
Email: test@example.com
新しいサブスクリプション申し込みがありました。
開始日: 1682574904
true: 1400 * 1
商品ID: prod_LFzTo8Pi8xirKs
注文数量: 1
金額: 1400
商品ID: prod_LFzdDEOEwRtuRw
注文数量: 1
金額: 2000

3DSによる追加の認証やコンビニ決済など、「決済が完了するまで少し時間がかかるケース」が存在します。

決済完了が非同期の場合は、checkout.session.async_payment_succeededイベントで改めて決済完了後にイベントが送信されます。

checkout.session.completedにて、payment_statuspaidかどうかを判定しましょう。

-            case 'checkout.session.completed': {
+            case 'checkout.session.completed':
+            case 'checkout.session.async_payment_succeeded': {
                const session = event.data.object
+                if (session.payment_status !== 'paid') {
+                    break
+                }

サブスクリプション申込後に、システム側のユーザーアカウントを作成する

サブスクリプションの申し込みが完了してから、ユーザーアカウントを発行する方法では、Webhookを利用します。

このケースでは、customer.createdcustomer.subscription.createdcheckout.session.completedのWebhookイベントから、顧客やサブスクリプションの作成時・Checkoutのセッション完了時にユーザーアカウントを発行しましょう。

        switch (event.type) {
            // 顧客の作成が成功した場合にトリガーされる
            case 'customer.created': {
                const customer = event.data.object
+                const payload = {
+                    name: customer.name,
+                    email: customer.email,
+                    phone_number: customer.phone,
+                }
+                await AnyUserService.createNewUser(payload)
                console.log([
                    `顧客データが作成されました。`,
                    `Email: ${customer.email}`
                ].join('\n'))
                break
            }

この方法を採用すると、Webhook APIを用意せずにZapierやAWS Step Functionsなどでワークフローを構築できるメリットもあります。

おわりに

盛りだくさんな内容のワークショップでしたが、概ね高評価を頂けたので、すごくホッとしています。

デモサイトを作ったり、他の地域でもこのワークショップを開催できたりすると嬉しいなと思いますので、「AstroやStripe、Cloudflareが気になる!」という方は、お気軽に岡本やJP_Stripesコミュニティにご相談ください。

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

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

Related Category posts