Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Stripe & Next.js + AWS Amplify で会員 + 定期課金機能 / JP_Stripes20210903

Stripe & Next.js + AWS Amplify で会員 + 定期課金機能 / JP_Stripes20210903

75486cbfd37125f121cf4a6c5614601c?s=128

Hidetaka Okamoto
PRO

September 03, 2021
Tweet

Transcript

  1. Stripe & Next.js + AWS Amplify Ͱձһ + ఆظ՝ۚػೳ JP_Stripes

    Online Hidetaka Okamoto #JP_Stripes
  2. 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
  3. 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
  4. Agenda • ࠷খݶͷ։ൃ޻਺Ͱ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮૷͢Δ

    • ઃܭɾ։ൃ࣌ͷ஫ҙ఺ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
  5. Agenda • ࠷খݶͷ։ൃ޻਺Ͱ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮૷͢Δ

    • ઃܭɾ։ൃ࣌ͷ஫ҙ఺ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
  6. ؾʹͳΔπʔϧ΍ ৽ػೳͰ༡Ϳ৔ॴ͕ཉ͍͠

  7. ݸਓαΠτʹ શ෦ϒνࠐΜͩ #JP_Stripes https://wp-kyoto.net Ͱ 9݄தެ։༧ఆ

  8. • 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 ٕज़ελοΫ
  9. ༗ྉձһαΠτ։ൃͷγϣʔτΧοτίʔε • ෳࡶͳػೳ͸͢΂ͯSaaS / Frameworkʹ೚ͤΔ • ΞϓϦ͸ʮAPIΛΑͼͩ͢ʯʮAPIͷ݁ՌΛදࣔ͢ΔʯʹಛԽ • ʮܾࡁʯͱʮೝূೝՄʯΛͲΕ͚ͩ࠷୹ڑ཭Ͱ࡞ΕΔ͔͕伴 •

    ೝূೝՄ: Auth0 / Cognito / Firebase / Superbase / etc… • ܾࡁ: Stripe / pay.jp / PayPal / Paidy / etc… #JP_Stripes
  10. Stripeͷ Low codeܥػೳΛ׆༻ #JP_Stripes

  11. #JP_Stripes SpeakerDeck

  12. SaaS APIΛ׆༻ͯ͠ɺίʔυͷྔΛ཈͑Δ • ܾࡁͱܾࡁ؅ཧ͸΄΅ඞͣඞཁʹͳΔػೳཁ݅ • StripeͰܾࡁ͢Δ৔߹ɺҎԼͷ2఺͕Low CodeԽͰ͖Δ • ஫จϑΥʔϜ(Χʔυ /

    ߪೖऀ৘ใೖྗ) -> Checkout • ఆظ՝ۚ৘ใ؅ཧ -> Customer Portal • ʮࣗ༝ͱޮ཰ʯͲͬͪΛॏࢹ͢Δ͔ͰಓΛબ΅͏ #JP_Stripes
  13. Agenda • ࠷খݶͷ։ൃ޻਺Ͱ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮૷͢Δ

    • ઃܭɾ։ൃ࣌ͷ஫ҙ఺ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
  14. Next.js & AWS AmplifyʹStripeΛ૊ΈࠐΉ • React AppଆʹStripe JS SDK •

    REST APIଆʹStripe Nodejs SDK • CheckoutͱCustomer Portal͚ͩͳΒReact SDK͸ෆཁ • React SDK͸Stripe ElementΛ࢖͏ͨΊͷSDK • APIΩʔͷऔΓѻ͍ʹ஫ҙʢޙड़ʣ #JP_Stripes
  15. 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
  16. 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
  17. 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
  18. 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
  19. Customer Portal͸Customer 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
  20. #JP_Stripes ໘౗ͳ ੥ٻ؅ཧܥը໘͕ ͨͬͨ4ߦͰ࡞ΕΔ

  21. 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
  22. ࣮૷࣌ͷϙΠϯτ 1. StripeͷCustomer IDΛϢʔβʔ৘ใͱඥ͚ͮΔඞཁ͋Γ • Customer Portal Linkͷੜ੒͸αʔόʔଆॲཧ 2. Customer

    Portalʹग़͢ίϯςϯπͷ੍ޚ͸ݪଇDashboard • API͔ΒͳΒઃఆ͸ෳ਺࡞ΕΔ໛༷ʢະݕূʣ 3. Stripe Secret APIΩʔͷѻ͍͕ෆ҆ͳΒ੍ݶ෇͖ΩʔΛ࢖͓͏ #JP_Stripes
  23. Agenda • ࠷খݶͷ։ൃ޻਺Ͱ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮૷͢Δ

    • ઃܭɾ։ൃ࣌ͷ஫ҙ఺ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
  24. ར༻ن໿ϖʔδͱ ϓϥΠόγʔϙϦγʔϖʔδ ͸ొ࿥ඞਢ #JP_Stripes

  25. #JP_Stripes AWS Amplify͸ Next.jsΛLambda@edge Ͱ࣮ߦ͢Δ

  26. #JP_Stripes ͍͍ͩͨ ͜Εͩͱࢥͬͯ ѻ͓͏

  27. ΞϓϦ֎ͰStripeͷσʔλ͕มΘΔ͜ͱʹ஫ҙ • ϓϥϯมߋɾղ໿ɾϢʔβʔ৘ใͷมߋͳͲͷૢ࡞ • Customer PortalͰى͖ͨมߋΛγεςϜʹ൓өͤ͞Δඞཁ͕͋Δ • Stripe WebhookͰΠϕϯτΛड͚ͯσʔλΛมߋ͠Α͏ •

    Customer Portalʹ͸ʮCustomer࡟আʯ͕ݱঢ়ͳ͍ 1. Subscriptions.delete WebhookͰσʔλΛফ͢ 2. CognitoͳͲͷϢʔβʔ࡟আ࣌ʹফ͢Α͏ʹγεςϜΛߏங #JP_Stripes
  28. ඞཁͳAPIΛݺͼग़ͯ͠ ػೳΛ։ൃ͢Δ ↓ ඞཁͳWebhookΠϕϯτΛ Subscribeͯ͠։ൃ͢Δ

  29. Agenda • ࠷খݶͷ։ൃ޻਺Ͱ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮૷͢Δ

    • ઃܭɾ։ൃ࣌ͷ஫ҙ఺ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes
  30. ઃఆ߲໨͸೔ʹ೔ʹ૿Ճ͍ͯ͠Δ

  31. Customer Portalͱ ಉ౳ͷػೳΛ ࣗલͰ։ൃɾఏڙͰ͖Δ͔ʁ

  32. ίΞϏδωεྖҬ֎ͷػೳΛ୭͕࡞Δ͔ʁ A. ࣗྗ։ൃ͢Δ͜ͱͰɺσβΠϯ΍࢓༷ͷࣗ༝౓Λ֬อͰ͖Δ • ػೳ͕૿͑Δͱอकɾӡ༻ͷൣғ΋૿͑Δ • ͦͷࣗ༝Λ׆༻Ͱ͖Δ͚ͩͷ։ൃϦιʔε͕͋Δ͔൱͔ B. SaaS /

    Low Codeʹҕৡͯ͠ɺॏཁͳػೳʹूத͢Δ • ϕϯμʔ͕࠷దͱ͢ΔUI΍ػೳΛৗʹड͚औΕΔ • υϝΠϯ΍σβΠϯɾػೳͷ੍໿Λڐ༰Ͱ͖Δ͔൱͔ #JP_Stripes
  33. ΠϕϯτۦಈͳγεςϜ͔ͩΒͰ͖Δ͜ͱ #JP_Stripes • Checkout / Customer Portal͸WebhookͰγεςϜͱ࿈ܞ͢Δ࢓૊Έ • ϓϥϯมߋͳͲͷΠϕϯτΛड͚ͯಈ࡞͢ΔγεςϜʹͳΔ •

    ʮಉ͡ΠϕϯτΛൃՐͰ͖Ε͹ʯ͍ͭͰ΋ஔ͖׵͑Ͱ͖Δ • ্ཱͪ͛࣌͸྆ػೳΛ࢖ͬͯίΞ։ൃʹϦιʔεΛूத͢Δ • Ҡߦ͢Δ࣌͸ɺΠϕϯτ୯ҐͰஈ֊తʹ੾Γସ͍͑ͯ͘ • ʮΠϕϯτۦಈΞʔΩςΫνϟʯ΁ͷୈҰาʹ
  34. More info

  35. ϝʔϧͰߋ৽৘ใΛ ͬ͟ͱݟͰ͖Δ Developer Digest #JP_Stripes https://stripe.dev/

  36. https://www.youtube.com/stripedevelopers

  37. Thanks! • ࠷খݶͷ։ൃ޻਺Ͱ༗ྉձһϝσΟΞΛ࡞Δ • Next.js / Stripe / AWS AmplifyͰ࣮૷͢Δ

    • ઃܭɾ։ൃ࣌ͷ஫ҙ఺ • ʮਖ਼͘͠SaaSʹґଘ͢Δʯ #JP_Stripes