Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Stripe & Next.js + AWS Amplify で会員 + 定期課金機能 / ...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
690
コミュニティ運営から 中の人に変わって感じたこと
hideokamoto
0
140
Developerが Developer Advocateになった話 / dev-rel-meetup-tokyo-71
hideokamoto
0
380
Jamstack開発者のための App Runner入門
hideokamoto
1
540
WordPressでの webサイト制作2022 / ngk2022s
hideokamoto
0
490
JavaScript(TypeScript)で メディアサイトを インフラから構築する方法 / jsconf-jp-2021
hideokamoto
2
4.4k
AWS上でStripeを利用したアプリをより安全にデプロイする方法 /jaws-pankration-2021
hideokamoto
1
240
Shifter Headlessと Headless WordPressの紹介
hideokamoto
0
2.1k
後付けで 従量課金プランの 提供を開始した話 / 20210609-jp_stripes
hideokamoto
0
250
Other Decks in Programming
See All in Programming
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
200
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
150
Modding RubyKaigi for Myself
yui_knk
0
910
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
320
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
230
AIチームを指揮するOSS「TAKT」活用術 / How to Use “TAKT,” an OSS Tool for Orchestrating AI Teams
nrslib
6
850
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.3k
3Dシーンの圧縮
fadis
1
680
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.6k
New "Type" system on PicoRuby
pocke
1
730
CSC307 Lecture 17
javiergs
PRO
0
320
Lessons from Spec-Driven Development
simas
PRO
0
150
Featured
See All Featured
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
280
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2k
Raft: Consensus for Rubyists
vanstee
141
7.5k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.5k
Designing for humans not robots
tammielis
254
26k
Building an army of robots
kneath
306
46k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
180
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
160
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
160
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
200
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.1k
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