Slide 1

Slide 1 text

4USJQFͰ੥ٻॻ෷͍ۜߦৼࠐΈ +1@4USJQF0OMJOF7PM 1MBZ5FDIOPMPHJFT *OD )JSPLJ,PNVSBTBLJ!QFUJUWJPMFU

Slide 2

Slide 2 text

ࣗݾ঺հ w খࢵ߂و )JSPLJ,PNVSBTBLJ w !QFUJUWJPMFU w 1MBZ5FDIOPMPHJFTͰΤϯδχΞΛ΍͍ͬͯ·͢ w IUUQTQMBZUFDIKQ w ʰϙνίʱΛఏڙ͍ͯ͠·͢

Slide 3

Slide 3 text

ࠓ೔࿩͢͜ͱ w 4USJQFͰ࣮૷͢Δ੥ٻॻ෷͍ ۜߦৼࠐ w ʰཌ݄຤కΊ੾Γʱͷ࣮૷ w ະ෷͍ϢʔβΛࣗಈͰղ໿ͤ͞Δ w కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ

Slide 4

Slide 4 text

ϙνίʁ -*/&༧໿αʔϏε ˇ ݄ͳαϒεΫϦϓγϣϯܕϏδωε

Slide 5

Slide 5 text

ϙνίͱ4USJQF w ༗ྉϢʔβʔͷ؅ཧ w 'JSFCBTF"VUIFOUJDBUJPO w αϒεΫϦϓγϣϯͷ؅ཧ w ແྉτϥΠΞϧ w ੥ٻ w Χʔυ෷͍ w ੥ٻॻ෷͍ ΧʔυPSۜߦৼࠐ ˡ/&8ʂ

Slide 6

Slide 6 text

4USJQFͰ࣮૷͢Δ੥ٻॻ෷͍ ۜߦৼࠐ

Slide 7

Slide 7 text

ϙνίͷར༻ྉࢧ෷͍ํ๏ w Χʔυ෷͍͍ͨ͠Ϣʔβʔ w ՝ۚ։࢝࣌ʹΧʔυ৘ใΛೖྗˠ4USJQFͰ؅ཧ w ੥ٻॻ෷͍͍ͨ͠Ϣʔβʔ w ౰ॳ͸αϙʔτ͍ͯ͠ͳ͔͕ͬͨɺཁ๬ͷଟ͞ʹ·͚ͯ ӡ༻ͰΧόʔ͠͸͡Ίͨ w (PPHMF'PSNͰͦͷࢫΛૹ৴ͯ͠΋ΒͬͯɺεϓϨου γʔτͰ੥ٻॻ෷͍ͷϢʔβʔΛ؅ཧ w .˓OFZ'PSXBSEͰ੥ٻॻൃߦɾૹ෇ w ౰વɺ৭ʑͱਏ͍ w ೋॏ؅ཧɺ%#ͱͷঢ়ଶ੔߹ੑɺకΊ࡞ۀɺFUD

Slide 8

Slide 8 text

͕࣌ܦͪ Χʔυ෷͍ɾۜߦৼࠐͷͲͪΒʹ΋ରԠͨ͠੥ٻॻ ෷͍͕4USJQFͰՄೳʹͳͬͨʂ ੥ٻॻͷϢʔβʔΛ εϓϨουγʔτ.˓OFZ'PSXBSE ˣ

Slide 9

Slide 9 text

4USJQF΁ͷҠߦεςοϓ 4USJQFͷ$VTUPNFSΛ࡞੒ 4USJQFͷ4VCTDSJQUJPOΛ࡞੒ w DPMMFDUJPO@NFUIPEʹzTFOE@JOWPJDFzΛ༩͑Δ

Slide 10

Slide 10 text

4USJQF΁ͷҠߦεςοϓ 4USJQFͷ$VTUPNFSΛ࡞੒ 4USJQFͷ4VCTDSJQUJPOΛ࡞੒ w DPMMFDUJPO@NFUIPEʹzTFOE@JOWPJDFzΛ༩͑Δ

Slide 11

Slide 11 text

4USJQFͷ$VTUPNFSΛ࡞੒ ୯ʹ$VTUPNFSΛ࡞੒͢Δ͚ͩ ಛච͢΂͖͜ͱ͸ͳ͍ stripe.customers.create({ email, name, description, metadata: { paymentType: 'invoice', // metadataに請求書払いユーザであることをマークしている }, });

Slide 12

Slide 12 text

4USJQF΁ͷҠߦεςοϓ 4USJQFͷ$VTUPNFSΛ࡞੒ 4USJQFͷ4VCTDSJQUJPOΛ࡞੒ w DPMMFDUJPO@NFUIPEʹzTFOE@JOWPJDFzΛ༩͑Δ

Slide 13

Slide 13 text

4USJQFͷ4VCTDSJQUJPOΛ࡞੒ 4VCTDSJQUJPOΛ࡞੒͢Δ͚ͩ stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, backdate_start_date: today.startOf('M').unix(), // 今月頭 billing_cycle_anchor: today.startOf('M').add(1, 'M').unix(), // 月初請求 days_until_due: 60, // 雑な"翌月末" trial_end: 'now', }); IUUQTTUSJQFDPNEPDTBQJTVCTDSJQUJPOTDSFBUF

Slide 14

Slide 14 text

4USJQFͷ4VCTDSJQUJPOΛ࡞੒ 4VCTDSJQUJPOΛ࡞੒͢Δ͚ͩ stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, backdate_start_date: today.startOf('M').unix(), // 今月頭 billing_cycle_anchor: today.startOf('M').add(1, 'M').unix(), // 月初請求 days_until_due: 60, // 雑な"翌月末" trial_end: 'now', }); ੥ٻॻૹ෇ɾΧʔυPSۜߦৼࠐͰͷࢧ෷͍Մ IUUQTTUSJQFDPNEPDTBQJTVCTDSJQUJPOTDSFBUF

Slide 15

Slide 15 text

4USJQFͷ4VCTDSJQUJPOΛ࡞੒ 4VCTDSJQUJPOΛ࡞੒͢Δ͚ͩ stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, backdate_start_date: today.startOf('M').unix(), // 今月頭 billing_cycle_anchor: today.startOf('M').add(1, 'M').unix(), // 月初請求 days_until_due: 60, // 雑な"翌月末" trial_end: 'now', }); ੥ٻλΠϛϯάͷઃఆ IUUQTTUSJQFDPNEPDTBQJTVCTDSJQUJPOTDSFBUF

Slide 16

Slide 16 text

4USJQFͷ4VCTDSJQUJPOΛ࡞੒ ແྉτϥΠΞϧظؒ ΞΧ΢ϯτొ࿥ޙϲ݄ ʹ੥ٻॻ෷͍Ͱొ࿥͢Δͱ return stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, // 無料トライアル終了後の翌月頭 billing_cycle_anchor: account.createdAt.add(1, 'M').startOf('M').add(1, ‘M').unix(), // アカウント作成後1ヶ月は無料トライアル trial_end: account.createdAt.add(1, 'M').startOf('d').subtract(1, ’s').unix(), // 支払いは翌月末 days_until_due: today.add(1, 'M').endOf('M').diff(today, 'd'), });

Slide 17

Slide 17 text

return stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, // 無料トライアル終了後の翌月頭 billing_cycle_anchor: account.createdAt.add(1, 'M').startOf('M').add(1, ‘M').unix(), // アカウント作成後1ヶ月は無料トライアル trial_end: account.createdAt.add(1, 'M').startOf('d').subtract(1, ’s').unix(), // 支払いは翌月末 days_until_due: today.add(1, 'M').endOf('M').diff(today, 'd'), }); 4USJQFͷ4VCTDSJQUJPOΛ࡞੒ ແྉτϥΠΞϧظؒ ΞΧ΢ϯτొ࿥ޙϲ݄ ʹ੥ٻॻ෷͍Ͱొ࿥͢Δͱ ੥ٻλΠϛϯάͷઃఆ͕ෳࡶԽ

Slide 18

Slide 18 text

4USJQFͷ4VCTDSJQUJPOΛ࡞੒ ແྉτϥΠΞϧظؒ ΞΧ΢ϯτొ࿥ޙϲ݄ ʹ੥ٻॻ෷͍Ͱొ࿥͢Δͱ ͜ͷ··ʹ͓ͯ͘͠ͱɺ࣍ͷ੥ٻॻͷࢧ෷ظݶ͕ཌ݄຤Ͱͳ͘ͳͬͯ͠·͏ return stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, // 無料トライアル終了後の翌月頭 billing_cycle_anchor: account.createdAt.add(1, 'M').startOf('M').add(1, ‘M').unix(), // アカウント作成後1ヶ月は無料トライアル trial_end: account.createdAt.add(1, 'M').startOf('d').subtract(1, ’s').unix(), // 支払いは翌月末 days_until_due: today.add(1, 'M').endOf('M').diff(today, 'd'), }); ੥ٻॻൃߦ͸ແྉτϥΠΞϧऴྃ࣌ ࢧ෷ظݶ͸ͦͷཌ݄຤

Slide 19

Slide 19 text

ʰཌ݄຤కΊ੾Γʱͷ࣮૷

Slide 20

Slide 20 text

4VCTDSJQUJPOͷEBZT@VOUJM@EVF return stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, // 無料トライアル終了後の翌月頭 billing_cycle_anchor: account.createdAt.add(1, 'M').startOf('M').add(1, ‘M').unix(), // アカウント作成後1ヶ月は無料トライアル trial_end: account.createdAt.add(1, 'M').startOf('d').subtract(1, ’s').unix(), // 支払いは翌月末 days_until_due: today.add(1, 'M').endOf('M').diff(today, 'd'), }); ແྉτϥΠΞϧதͷ4VCTDSJQUJPO࡞੒ stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], collection_method: 'send_invoice', default_tax_rates: defaultTaxRates, payment_settings: { payment_method_types: ['card', 'customer_balance'] }, backdate_start_date: today.startOf('M').unix(), // 今月頭 billing_cycle_anchor: today.startOf('M').add(1, 'M').unix(), // 月初請求 days_until_due: 60, // 雑な"翌月末" trial_end: 'now', }); ௨ৗ࣌ͷ4VCTDSJQUJPO࡞੒

Slide 21

Slide 21 text

4VCTDSJQUJPOͷEBZT@VOUJM@EVF return stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], default_tax_rates: defaultTaxRates, collection_method: 'send_invoice', payment_settings: { payment_method_types: ['card', 'customer_balance'] }, // 無料トライアル終了後の翌月頭 billing_cycle_anchor: account.createdAt.add(1, 'M').startOf('M').add(1, ‘M').unix(), // アカウント作成後1ヶ月は無料トライアル trial_end: account.createdAt.add(1, 'M').startOf('d').subtract(1, ’s').unix(), // 支払いは翌月末 days_until_due: today.add(1, 'M').endOf('M').diff(today, 'd'), }); ແྉτϥΠΞϧதͷ4VCTDSJQUJPO࡞੒ stripe.subscriptions.create({ customer: customerId, items: [{ price: priceId }], collection_method: 'send_invoice', default_tax_rates: defaultTaxRates, payment_settings: { payment_method_types: ['card', 'customer_balance'] }, backdate_start_date: today.startOf('M').unix(), // 今月頭 billing_cycle_anchor: today.startOf('M').add(1, 'M').unix(), // 月初請求 days_until_due: 60, // 雑な"翌月末" trial_end: 'now', }); ௨ৗ࣌ͷ4VCTDSJQUJPO࡞੒ ੥ٻॻͷࢧ෷ظݶΛଗ͍͑ͨ

Slide 22

Slide 22 text

8FCIPPLΛ࢖͏ 4USJQF͸Πϕϯτ͝ͱʹ8FCIPPLΛඈ͹ͯ͘͠ΕΔ IUUQTTUSJQFDPNEPDTXFCIPPLT

Slide 23

Slide 23 text

8FCIPPLΛ࢖͏ 4USJQF͸Πϕϯτ͝ͱʹ8FCIPPLΛඈ͹ͯ͘͠ΕΔ ࠓճ࢖ͬͨͷ͸zDVTUPNFSTVCTDSJQUJPOVQEBUFEz ແྉτϥΠΞϧऴྃ࣌ʹൃՐ͢Δ IUUQTTUSJQFDPNEPDTBQJFWFOUTUZQFTFWFOU@UZQFTDVTUPNFSTVCTDSJQUJPOVQEBUFE

Slide 24

Slide 24 text

8FCIPPLΛ࢖͏ 8FCIPPLͷઃఆͰDVTUPNFSTVCTDSJQUJPOVQEBUFEΛ ड͚औΔΑ͏ʹ໌͓ࣔͯ͘͜͠ͱ

Slide 25

Slide 25 text

8FCIPPLΛ࢖͏ lDVTUPNFSTVCTDSJQUJPOVQEBUFEzΛड͚औͬͯ TVCTDSJQUJPOEBZT@VOUJM@EVFΛઃఆ͠௚͢ if (event.type === 'customer.subscription.updated') { const previousAttributes = event.data.previous_attributes; const trialEnded = 'status' in previousAttributes && previousAttributes.status === 'trialing'; if (trialEnded) { // 請求書払いなsubscriptionのtrialが終わったら、 // daysUntilDueを更新して請求書を月末発行・翌月末期限に調整する await updateSubscription(event.data.object.id, { days_until_due: 60, }); } }

Slide 26

Slide 26 text

ະ෷͍ϢʔβΛࣗಈͰղ໿ͤ͞Δ

Slide 27

Slide 27 text

ࢧ෷Θͳ͍Ϣʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞ ੥ٻॻ෷͍ ۜߦৼࠐ ͩͱࢧ෷͍͕஗Ε͕ͪ ˣ ஗ΕͨϢʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞ Ͱ΋ଈղ໿͸ݫ͗͢͠ΔͷͰ༛༧Λ͍࣋ͨͤͨ

Slide 28

Slide 28 text

ࢧ෷Θͳ͍Ϣʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞ ੥ٻॻ෷͍ ۜߦৼࠐ ͩͱࢧ෷͍͕஗Ε͕ͪ ˣ ஗ΕͨϢʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞ Ͱ΋ଈղ໿͸ݫ͗͢͠ΔͷͰ༛༧Λ͍࣋ͨͤͨ 4USJQFͳΒ؆୯ʹग़དྷΔΑʂ

Slide 29

Slide 29 text

ࢧ෷Θͳ͍Ϣʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞

Slide 30

Slide 30 text

ࢧ෷Θͳ͍Ϣʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞

Slide 31

Slide 31 text

ࢧ෷Θͳ͍Ϣʔβʔ͸ࣗಈͰղ໿͍ͤͨ͞ ཌ݄຤͕ࢧ෷ظݶ ཌʑ݄຤ʹࣗಈղ໿

Slide 32

Slide 32 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ

Slide 33

Slide 33 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ కΊ੾ΓˠਅͷకΊ੾Γ ࣗಈղ໿ ·Ͱ༛༧͕͋Δ ͜ͷؒʹࢧ෷͍͕͋Δͱফࠐ͞Εͣʹʰ࢒ߴʱʹ ೖͬͯ͠·͏

Slide 34

Slide 34 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ ݱۚ࢒ߴ͕͋Δͷʹ੥ٻॻ͕ະ෷͍Ͱͦͷ··ղ໿ ͞Εͯ͠·͏ͱ͍͏࠷ѱͷ݁Ռʹ ͦͯۜ͠ߦৼࠐ͸4USJQFʹ൓ө͞ΕΔ·Ͱϥά͕͋Δʜ

Slide 35

Slide 35 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ खಈͰফࠐ͢Δ࣮૷͕ඞཁ IUUQTTUSJQFDPNEPDTQBZNFOUTDVTUPNFSCBMBODFSFDPODJMJBUJPODBTINBOVBMSFDPODJMJBUJPO await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'manual', }, }, }); await stripe.paymentIntents.applyCustomerBalance( invoice.payment_intent as string ); await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'automatic', }, }, });

Slide 36

Slide 36 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ खಈͰফࠐ͢Δ࣮૷͕ඞཁ IUUQTTUSJQFDPNEPDTQBZNFOUTDVTUPNFSCBMBODFSFDPODJMJBUJPODBTINBOVBMSFDPODJMJBUJPO await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'manual', }, }, }); await stripe.paymentIntents.applyCustomerBalance( invoice.payment_intent as string ); await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'automatic', }, }, }); ফࠐϞʔυΛखಈʹมߋ

Slide 37

Slide 37 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ खಈͰফࠐ͢Δ࣮૷͕ඞཁ IUUQTTUSJQFDPNEPDTQBZNFOUTDVTUPNFSCBMBODFSFDPODJMJBUJPODBTINBOVBMSFDPODJMJBUJPO await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'manual', }, }, }); await stripe.paymentIntents.applyCustomerBalance( invoice.payment_intent as string ); await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'automatic', }, }, }); ফࠐ͢Δ

Slide 38

Slide 38 text

కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ खಈͰফࠐ͢Δ࣮૷͕ඞཁ IUUQTTUSJQFDPNEPDTQBZNFOUTDVTUPNFSCBMBODFSFDPODJMJBUJPODBTINBOVBMSFDPODJMJBUJPO await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'manual', }, }, }); await stripe.paymentIntents.applyCustomerBalance( invoice.payment_intent as string ); await stripe.customers.update(customer.id, { cash_balance: { settings: { reconciliation_mode: 'automatic', }, }, }); ফࠐϞʔυΛࣗಈʹ໭͢

Slide 39

Slide 39 text

ࠓ೔࿩ͨ͜͠ͱ w 4USJQFͰ࣮૷͢Δ੥ٻॻ෷͍ ۜߦৼࠐ w ʰཌ݄຤కΊ੾Γʱͷ࣮૷ w ະ෷͍ϢʔβΛࣗಈͰղ໿ͤ͞Δ w కΊ੾ΓΛ͗ͨ͢ࢧ෷͍ͷফࠐ ڵຯ͕͋Ε͹IUUQTQPDIJDPBQQ࢖ͬͯΈͯͶʂ