Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Stripe & Next.js + AWS Amplify で会員 + 定期課金機能 / ...
Search
Hidetaka Okamoto
September 03, 2021
Programming
3.3k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Stripe & Next.js + AWS Amplify で会員 + 定期課金機能 / JP_Stripes20210903
Hidetaka Okamoto
September 03, 2021
More Decks by Hidetaka Okamoto
See All by Hidetaka Okamoto
OpenAI APIで API Changelogを要約してみた話 / chatgpt-osaka-1
hideokamoto
0
730
コミュニティ運営から 中の人に変わって感じたこと
hideokamoto
0
160
Developerが Developer Advocateになった話 / dev-rel-meetup-tokyo-71
hideokamoto
0
400
Jamstack開発者のための App Runner入門
hideokamoto
1
560
WordPressでの webサイト制作2022 / ngk2022s
hideokamoto
0
500
JavaScript(TypeScript)で メディアサイトを インフラから構築する方法 / jsconf-jp-2021
hideokamoto
2
4.5k
AWS上でStripeを利用したアプリをより安全にデプロイする方法 /jaws-pankration-2021
hideokamoto
1
250
Shifter Headlessと Headless WordPressの紹介
hideokamoto
0
2.3k
後付けで 従量課金プランの 提供を開始した話 / 20210609-jp_stripes
hideokamoto
0
250
Other Decks in Programming
See All in Programming
気持ちぃ〜角丸 Squircle
ryu1013
0
260
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
170
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
200
phperだってパンチカードでコーディングしたい
o0h
PRO
0
270
R8 の設定見直しでアプリサイズ削減
andpad
0
210
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
380
Are APIs Still Relevant in the AI Era?
soyuka
0
450
最近”作らせてる” ローカルAIアプリの話
akit37
0
440
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.2k
難しいけど、読めた。- OSSの入口に立った話。
sts11142
0
150
速習iPhone Duo対応
yuukiw00w
2
980
Featured
See All Featured
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
2
6.3k
Evolving SEO for Evolving Search Engines
ryanjones
0
320
Automating Front-end Workflow
addyosmani
1369
210k
Chasing Engaging Ingredients in Design
codingconduct
0
350
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Darren the Foodie - Storyboard
khoart
PRO
4
4k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
First, design no harm
axbom
PRO
2
1.3k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
620
The Cost Of JavaScript in 2023
addyosmani
55
10k
Transcript
Stripe & Next.js + AWS Amplify Ͱձһ + ఆظ՝ۚػೳ JP_Stripes
Online Hidetaka Okamoto #JP_Stripes
H i d e t a k a O k
a m o t o • Digitalcube Co. Ltd. • JavaScript Developer • WordPress 4.7 / 5.0 / 5.3 Core contributor
H i d e t a k a O k
a m o t o • Digitalcube Co. Ltd. • JavaScript Developer • WordPress 4.7 / 5.0 / 5.3 Core contributor https://zenn.dev/hideokamoto/books/e961b4bad92429
Agenda • ࠷খݶͷ։ൃͰ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮͢Δ
• ઃܭɾ։ൃ࣌ͷҙ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
Agenda • ࠷খݶͷ։ൃͰ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮͢Δ
• ઃܭɾ։ൃ࣌ͷҙ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
ؾʹͳΔπʔϧ ৽ػೳͰ༡Ϳॴ͕ཉ͍͠
ݸਓαΠτʹ શ෦ϒνࠐΜͩ #JP_Stripes https://wp-kyoto.net Ͱ 9݄தެ։༧ఆ
• AWS Amplify: Authentication • AWS CDK: IaC • Stripe:
Subscription • Algolia: Advanced Search • Next.js: Framework • Ionic: UI library • WordPress: Headless CMS • Capacitor / Sentry / etc… #JP_Stripes ٕज़ελοΫ
༗ྉձһαΠτ։ൃͷγϣʔτΧοτίʔε • ෳࡶͳػೳͯ͢SaaS / FrameworkʹͤΔ • ΞϓϦʮAPIΛΑͼͩ͢ʯʮAPIͷ݁ՌΛදࣔ͢ΔʯʹಛԽ • ʮܾࡁʯͱʮೝূೝՄʯΛͲΕ͚ͩ࠷ڑͰ࡞ΕΔ͔͕伴 •
ೝূೝՄ: Auth0 / Cognito / Firebase / Superbase / etc… • ܾࡁ: Stripe / pay.jp / PayPal / Paidy / etc… #JP_Stripes
Stripeͷ Low codeܥػೳΛ׆༻ #JP_Stripes
#JP_Stripes SpeakerDeck
SaaS APIΛ׆༻ͯ͠ɺίʔυͷྔΛ͑Δ • ܾࡁͱܾࡁཧ΄΅ඞͣඞཁʹͳΔػೳཁ݅ • StripeͰܾࡁ͢Δ߹ɺҎԼͷ2͕Low CodeԽͰ͖Δ • จϑΥʔϜ(Χʔυ /
ߪೖऀใೖྗ) -> Checkout • ఆظ՝ۚใཧ -> Customer Portal • ʮࣗ༝ͱޮʯͲͬͪΛॏࢹ͢Δ͔ͰಓΛબ΅͏ #JP_Stripes
Agenda • ࠷খݶͷ։ൃͰ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮͢Δ
• ઃܭɾ։ൃ࣌ͷҙ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
Next.js & AWS AmplifyʹStripeΛΈࠐΉ • React AppଆʹStripe JS SDK •
REST APIଆʹStripe Nodejs SDK • CheckoutͱCustomer Portal͚ͩͳΒReact SDKෆཁ • React SDKStripe ElementΛ͏ͨΊͷSDK • APIΩʔͷऔΓѻ͍ʹҙʢޙड़ʣ #JP_Stripes
SSM·ͨSecret Manager͔ΒAPIΩʔΛऔಘ export const createStripeClient = async () => {
const data = await new SSM({ region: “us-east-1"ɹ}) .getParameter({ Name: !!process.env.AWS_LAMBDA_FUNCTION_NAME ? "STRIPE_LIVE_SECRET_KEY": "STRIPE_TEST_SECRET_KEY", WithDecryption: true, }).promise(); const stripe = new Stripe(data.Parameter?.Value;, { apiVersion: "2020-08-27", maxNetworkRetries: 3, }); return stripe; }; #JP_Stripes
Stripe CustomerͱCognito User poolͷ࿈ܞ // Authorization HeaderͳͲͰऔಘͨ͠tokenͰCognito UserΛGet const user
= await cognito.getUser({ AccessToken: req.headers.authorization || “" }).promise() // User attributes͔ΒEmailΛऔಘ const emailAttribute = user.UserAttributes.find((data) => data.Name === "email"); const email = emailAttribute?.Value || “"; // EmailΛ͔ͭͬͯStripe CustomerΛ࡞ const customer = await stripe.customers.create({ email }); #JP_Stripes
Stripe CustomerͱCognito User poolͷ࿈ܞ // ࡞ͨ͠Stripe Customer const customer =
await stripe.customers.create({ email }); // User Attributeʹอଘ͢Δ await cognito .updateUserAttributes({ AccessToken: req.headers.authorization, UserAttributes: [{ Name: "custom:stripeCustomerId", Value: customer.id, }], }).promise(); #JP_Stripes
Customer idΛηοτͯ͠checkout.sessions.create const session = await stripe.checkout.sessions.create({ customer: customerId, allow_promotion_codes:
true, line_items: [{ price: price.id, quantity: 1, }], mode: "subscription", success_url: `${appUrl.replace(/\/$/, "")}/mypages/subscriptions`, cancel_url: `${appUrl.replace(/\/$/, "")}/mypages/plans`, payment_method_types: ["card"], }); res.status(200).json({ session_id: session.id }); #JP_Stripes
Customer PortalCustomer IDΛ͏ // Cognito͔ΒϢʔβʔΛऔಘ const user = await cognito.getUser({
AccessToken: req.headers.authorization }).promise() const attribute = user.UserAttributes.find((data) => { return data.Name === “custom:stripeCustomerId" }); // Customer Poral SessionΛ࡞ const session = await stripe.billingPortal.sessions.create({ customer: attribute?.Value, return_url: `${appUrl.replace(/\/$/, "")}/mypages/subscriptions`, }); res.status(200).json({ url: session.url }); #JP_Stripes
#JP_Stripes ໘ͳ ٻཧܥը໘͕ ͨͬͨ4ߦͰ࡞ΕΔ
APIͰϙʔλϧͷURLΛੜͯ͠ϦμΠϨΫτ const { push } = useRouter(); return (<button onClick={async
() => { const session = await Auth.currentSession(); const token = session.getAccessToken().getJwtToken(); const data = await fetch("/api/portal", { method: "POST", headers: { "Content-Type": "application/json", Authorization: token, }, }).then(data => data.json()); push(data.url); }}>Button</button>) #JP_Stripes
࣮࣌ͷϙΠϯτ 1. StripeͷCustomer IDΛϢʔβʔใͱඥ͚ͮΔඞཁ͋Γ • Customer Portal Linkͷੜαʔόʔଆॲཧ 2. Customer
Portalʹग़͢ίϯςϯπͷ੍ޚݪଇDashboard • API͔ΒͳΒઃఆෳ࡞ΕΔ༷ʢະݕূʣ 3. Stripe Secret APIΩʔͷѻ͍͕ෆ҆ͳΒ੍ݶ͖ΩʔΛ͓͏ #JP_Stripes
Agenda • ࠷খݶͷ։ൃͰ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮͢Δ
• ઃܭɾ։ൃ࣌ͷҙ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
ར༻نϖʔδͱ ϓϥΠόγʔϙϦγʔϖʔδ ొඞਢ #JP_Stripes
#JP_Stripes AWS Amplify Next.jsΛLambda@edge Ͱ࣮ߦ͢Δ
#JP_Stripes ͍͍ͩͨ ͜Εͩͱࢥͬͯ ѻ͓͏
ΞϓϦ֎ͰStripeͷσʔλ͕มΘΔ͜ͱʹҙ • ϓϥϯมߋɾղɾϢʔβʔใͷมߋͳͲͷૢ࡞ • Customer PortalͰى͖ͨมߋΛγεςϜʹөͤ͞Δඞཁ͕͋Δ • Stripe WebhookͰΠϕϯτΛड͚ͯσʔλΛมߋ͠Α͏ •
Customer PortalʹʮCustomerআʯ͕ݱঢ়ͳ͍ 1. Subscriptions.delete WebhookͰσʔλΛফ͢ 2. CognitoͳͲͷϢʔβʔআ࣌ʹফ͢Α͏ʹγεςϜΛߏங #JP_Stripes
ඞཁͳAPIΛݺͼग़ͯ͠ ػೳΛ։ൃ͢Δ ↓ ඞཁͳWebhookΠϕϯτΛ Subscribeͯ͠։ൃ͢Δ
Agenda • ࠷খݶͷ։ൃͰ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮͢Δ
• ઃܭɾ։ൃ࣌ͷҙ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
ઃఆ߲ʹʹ૿Ճ͍ͯ͠Δ
Customer Portalͱ ಉͷػೳΛ ࣗલͰ։ൃɾఏڙͰ͖Δ͔ʁ
ίΞϏδωεྖҬ֎ͷػೳΛ୭͕࡞Δ͔ʁ A. ࣗྗ։ൃ͢Δ͜ͱͰɺσβΠϯ༷ͷࣗ༝Λ֬อͰ͖Δ • ػೳ͕૿͑Δͱอकɾӡ༻ͷൣғ૿͑Δ • ͦͷࣗ༝Λ׆༻Ͱ͖Δ͚ͩͷ։ൃϦιʔε͕͋Δ͔൱͔ B. SaaS /
Low Codeʹҕৡͯ͠ɺॏཁͳػೳʹूத͢Δ • ϕϯμʔ͕࠷దͱ͢ΔUIػೳΛৗʹड͚औΕΔ • υϝΠϯσβΠϯɾػೳͷ੍Λڐ༰Ͱ͖Δ͔൱͔ #JP_Stripes
ΠϕϯτۦಈͳγεςϜ͔ͩΒͰ͖Δ͜ͱ #JP_Stripes • Checkout / Customer PortalWebhookͰγεςϜͱ࿈ܞ͢ΔΈ • ϓϥϯมߋͳͲͷΠϕϯτΛड͚ͯಈ࡞͢ΔγεςϜʹͳΔ •
ʮಉ͡ΠϕϯτΛൃՐͰ͖Εʯ͍ͭͰஔ͖͑Ͱ͖Δ • ্ཱͪ͛࣌྆ػೳΛͬͯίΞ։ൃʹϦιʔεΛूத͢Δ • Ҡߦ͢Δ࣌ɺΠϕϯτ୯ҐͰஈ֊తʹΓସ͍͑ͯ͘ • ʮΠϕϯτۦಈΞʔΩςΫνϟʯͷୈҰาʹ
More info
ϝʔϧͰߋ৽ใΛ ͬ͟ͱݟͰ͖Δ Developer Digest #JP_Stripes https://stripe.dev/
https://www.youtube.com/stripedevelopers
Thanks! • ࠷খݶͷ։ൃͰ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮͢Δ
• ઃܭɾ։ൃ࣌ͷҙ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes