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

決済システム超初心者が Stripe に入門している話

Avatar for SAW SAW
March 29, 2026

決済システム超初心者が Stripe に入門している話

個人開発の学び共有勉強会 in 大阪 の発表資料です。

Avatar for SAW

SAW

March 29, 2026
Tweet

More Decks by SAW

Other Decks in Programming

Transcript

  1. $(whoami) w ࢯ໊Ճ౻फҰ࿠ ࡀ  w ϋϯυϧωʔϜ4"8 w 9 چ5XJUUFS

    !B[VLJ@FBUFS w ؔ੢ͷ*5ΤϯδχΞίϛϡχςΟͷ೐΍͔͠ ࣗশ  w େࡕࡏॅɾѪ஌ग़਎ w ಘҙ෼໺8FCΞϓϦέʔγϣϯ։ൃ w -BSBWFM 7VF w ॴଐ༗ݶձࣾΞϦ΢ʔϓ  ʮ։͚ɺΰϚʯʹରͯ͠ ʮด͡Ζʯ͸ԿͩΖ͏ ຊ೔ͷ໎ݴ
  2. 1SPEVDUT w ঎඼Λ4USJQFͰදݱ͢ΔΦϒδΣΫτ w &$αΠτͳͲͷ঎඼΍4BB4ͷαʔϏεͳͲ w ঎඼໊͚ͩͰͳ͘঎඼ͷઆ໌΍ը૾ͳͲ΋ઃఆՄೳ w 1SPEVDUTͷ৽ن࡞੒࣌ʹ*%ΛಠࣗͰࢦఆՄೳ w

    طଘͷγεςϜͰ؅ཧ͍ͯ͠Δ੡඼ͷ*%ͱϚοϐϯά w *%Λࢦఆ͢Δ৔߹΋Ұҙʹͳ͍ͬͯΔඞཁ͕͋Δ w 4USJQFͷμογϡϘʔυ͔Β΋ૢ࡞Մೳ  // 商品の一覧取得 $products = $stripe->products->all(); // 商品の新規作成 $product = $stripe->products ->create([ 'name' => 'スタンダードプラン', ]); // 商品の削除 $stripe->products->delete($productId); 1SPEVDUTͷ"1*ͷ࢖༻ྫ
  3. 1SJDFT w ྉۚΛ4USJQFͰදݱ͢ΔΦϒδΣΫτ w 1SPEVDUTʹରͯ͠ෳ਺ͷ1SJDFT͕ઃఆՄೳ w ྫ4BB4ͷϓϥϯͷֹ݄༻ͷֹۚͱ೥ֹ༻ͷֹۚ w ࢧ෷͍ํ๏Λઃఆ w

    0OFUJNFճݶΓͷܾࡁ w ྫ&$αΠτͷ঎඼ߪೖ w 3FDVSSJOHఆظతʹൃੜ͢Δܾࡁ w ྫֹ݄ͷԻָ഑৴αʔϏεͷܖ໿ w 4USJQFͷμογϡϘʔυ͔Β΋ૢ࡞Մೳ  // 特定の products の料金一覧の取得 $prices = $stripe->prices ->all(['products' => 'prod_xxxx']); // products に料金を追加 $price = $stripe->prices ->create([ // 紐付ける products の ID 'product' => 'prod_xxxx', 'currency' => 'jpy', // 金額の通貨 'unit_amount' => 1500, // 単価 ]); 1SJDFTͷ"1*ͷ࢖༻ྫ
  4. αϒεΫϦϓγϣϯͰͷ1SPEVDUTͱ1SJDFTͷ࢖͍෼͚ w ϓϥϯͷ಺༰͕ҟͳΔ৔߹͸1SPEVDUTΛར༻ w ྫແྉϓϥϯͱελϯμʔυϓϥϯΛͦΕͧΕ࡞੒ w ಉ͡ϓϥϯ಺Ͱෳ਺ͷֹۚઃఆΛ͍ͨ͠৔߹͸1SJDFTΛར༻ w ελϯμʔυϓϥϯͷ೥෷͍ͱ݄෷͍ͷֹۚΛͦΕͧΕઃఆ w

    ϓϥϯͷ಺༰Λ1SPEVDUTʹઃఆ͢Δཧ༝ w ϓϥϯ͝ͱʹҟͳΔػೳΛઃఆ͢Δ৔߹ʹ࢖͍উख͕ྑ͍ w 1SJDFTͩͱಉ͡ϓϥϯͰෳ਺ֹۚ͋Δ৔߹ʹରԠ͕൥ࡶ w 4USJQFͷ&OUJUMFNFOUTΛར༻͢Δ৔߹͸ඥ෇͚ઌ͸1SPEVDUT 
  5. $VTUPNFST w ܾࡁ͢Δސ٬Λ4USJQFͰදݱ͢ΔΦϒδΣΫτ w ࿈བྷઌ΍ܾࡁํ๏ͳͲͷ৘ใΛอ࣋ w 4USJQFͷμογϡϘʔυ͔Β΋ૢ࡞Մೳ  // 顧客の一覧取得

    $customers = $stripe->customers->all(); // 顧客の登録 $customer = $stripe->customers ->create([ 'name' => 'サンプル 太郎', 'email' => '[email protected]', ]); // 顧客の削除 $stripe->customers->delete('cus_xxxx'); $VTUPNFSTͷ"1*ͷ࢖༻ྫ
  6. 4VCTDSJQUJPOT w αϒεΫϦϓγϣϯΛ4USJQFͰදݱ͢ΔΦϒδΣΫτ w $VTUPNFS͕ొ࿥ͨ͠αϒεΫϦϓγϣϯΛ؅ཧ w ඥͮ͘QSJDFTͷֹۚͱܾࡁִؒ SFDVSSJOH Λ൓ө w

    ແྉͷ͓ࢼ͠ظؒΛઃఆ͢Δ͜ͱ΋Մೳ  // サブスクリプションの新規作成 $subscription = $stripe ->subscriptions->create([ 'customer' => 'cus_xxxx', 'items' => [['price' => 'price_xxxx']], ]); // サブスクリプションのキャンセル $stripe->subscriptions->cancel('sub_xxxx'); 4VCTDSJQUJPOͷ"1*ͷ࢖༻ྫ
  7. 1BZNFOU.FUIPET w ܾࡁํ๏Λ4USJQFͰදݱ͢ΔΦϒδΣΫτ w ܾࡁ৘ใͷೖྗͰ$VTUPNFSTͱඥ෇͚ w ੈքதͷ༷ʑͳܾࡁํ๏ʹରԠ w ରԠ͍ͯ͠Δܾࡁํ๏ͷҰྫ w

    ΫϨδοτΧʔυ w ۜߦৼࠐ w "QQMF1BZ w (PPHMF1BZ w 1BZ1BM  // 顧客の決済方法の取得 $paymentMethods = $stripe->customers ->allPaymentMethods('cus_xxx'); // 決済方法の新規作成 $paymentMethod = $stripe->paymentMethods ->create([ 'type' => 'card', 'card' => [ 'exp_month' => 12, 'exp_year' => 2030, // テスト用のカード番号 'number' => '4242424242424242', ], ]); // 決済方法を customer に紐付け $stripe->paymentMethods->attach( 'pm_xxxx', ['customer' => 'cus_xxxx'], ); 1BZNFOU.FIUPETͷ"1*ͷ࢖༻ྫ
  8. -BSBWFM$BTIJFSʹ௅ઓ w 4USJQFͷಈ͖ΛͳΜͱͳ͘ཧղͨ͠ͷͰ-BSBWFM$BTIJFSʹ௅ઓ w -BSBWFM$BTIJFS͕ੜ੒͢Δςʔϒϧͷ಺༰΋೺Ѳ  #Laravel Cashier をインストール composer

    require laravel/cashier # Laravel Cashier で利用するテーブルを追加 php artisan vendor:publish --tag="cashier-migrations" php artisan migrate -BSBWFM$BTIJFSͷΠϯετʔϧͱηοτΞοϓ
  9. -BSBWFM$BTIJFSͷNJHSBUJPO fi MFTͷ಺༰ w subscriptionsςʔϒϧͷ௥Ճ w 4USJQFͷ4VCTDSJQUJPOͷ৘ใΛอଘ͢ΔͨΊͷςʔϒϧ w usersΛ֎෦Ωʔͱͯ͠อ࣋ͯ͠TVCTDSJQUJPOTΛϢʔβʔͱؔ࿈෇͚ w

    subscription_itemsςʔϒϧͷ௥Ճ w 4USJQFͷ4VCTDSUJPO*UFNTͷ৘ใΛอଘ͢ΔͨΊͷςʔϒϧ w usersςʔϒϧʹΧϥϜΛ௥Ճ w stripe_id4USJQFͷDVTUPNFSTͷ*% w pm_typeܾࡁํ๏ͷछผ w pm_last_fourΫϨδοτΧʔυͷԼܻ w trial_ends_atαϒεΫϦϓγϣϯͷτϥΠΞϧͷऴྃ೔ 
  10. -BSBWFM$BTIJFSΛར༻ͨ͠αϒεΫϦϓγϣϯͷొ࿥  UserͰBilliableUSBJUΛར༻  User::newSubscription()->create()ͰαϒεΫϦϓγϣϯΛొ࿥ w newSubscription()αϒεΫϦϓγϣϯΛొ࿥͢ΔͨΊͷલ४උ w ୈҾ਺ΞϓϦέʔγϣϯ಺෦Ͱ࢖͏αϒεΫϦϓγϣϯͷλΠϓ w

    ୈҾ਺ద༻͢Δ4USJQFͷQSJDFTͷ*% w create()αϒεΫϦϓγϣϯΛొ࿥ w ୈҾ਺ద༻͢Δ4USJQFͷQBZNFOUNFUIPETͷ*%  class User { use Billiable; // 以下省略 } $subscription = $user->newSubscription('default', $priceId) ->create($paymentMethodId);
  11. 4USJQF&MFNFOUTΛར༻ܾͨ͠ࡁϑΥʔϜͷ࡞੒  // Laravel Cashier の createSetupIntent() で SetupIntent からシークレットを作成

    $setupIntent = $user->createSetupIntent(['payment_method_types'] => ['card']); $clientSecret = $setupIntent->client_secret; ϑϩϯτΤϯυ༻ͷ4USJQFͷγʔΫϨοτΛੜ੒ <div id="payment-element"></div> ܾࡁϑΥʔϜΛϚ΢ϯτ͢ΔͨΊͷ%0.ཁૉΛ࡞੒ const stripe = Stripe('pk_xxxx'); // 1 で生成したシークレットを取得 const { clientSecret } = await fetch('/setup'); const elements = stripe.elements({ clientSecret }); const paymentElement = elements.create('payment'); paymentElement.mount('#payment-element'); // 決済フォーム送信時の処理 await stripe.confirmPayment({ elements, confirmParams: { return_url: '/url/to/redirect' }, }); ϑϩϯτΤϯυ༻ͷ4USJQFͷγʔΫϨοτΛੜ੒
  12. ࠓޙͷ՝୊ w αϒεΫϦϓγϣϯͷొ࿥Ҏ֎ͷػೳͷ࣮૷ w ϓϥϯͷมߋ΍ղ໿ w ϓϥϯ͝ͱʹར༻Մೳͳػೳͷ੍ޚ w ఆظతͳܾࡁঢ়گͷ֬ೝʹඞཁͳॲཧͷ࣮૷ w

    ੥ٻॻͷൃߦͷ࣮૷ w ܾࡁࣦഊ࣌ͷॲཧ w ຊ൪ӡ༻·ͰͷྲྀΕͷ೺Ѳ w ৹ࠪͷྲྀΕ΍ඞཁͳରԠ w ܾࡁͷجૅͷཧղ w ܾࡁͷϑϩʔ w ΫϨδοτΧʔυͷػೳ %4ͳͲ