決済ページへ進んだ時点で在庫を引き当て、入金が確定してから棚の数を減らします。確定時に減らすだけでは、決済ページにいる数分のあいだに、同じ最後の1本を何人も買えてしまうためです。売り越さないことは「在庫から引当分を引いた数が注文数以上」を条件にした1文のUPDATEで担保しています。D1には対話的なトランザクションがないので、複数の明細の途中で足りなくなったら、それまでに積んだ分を戻します。放棄された決済が在庫を丸1日押さえないよう、決済の有効期限はStripeの下限の30分にしています。
04 — EC / 日本酒 / 2026
FUJISANSAKE
富士山麓の日本酒「武士道シリーズ」を販売するECサイト。個人向けの通販と、審査を通った取扱店にだけ卸価格を出す法人向けの導線を、ひとつのサイトに収めました。
2026静岡県富士市
- クライアント
- 株式会社近藤薬局
- 領域
- EC / 日本酒
- 担当
- デザイン、開発、決済・在庫、管理画面、多言語対応、SEO、運用
- 年
- 2026
01 / PROJECT
WHAT THE
PROJECT IS.
武士道シリーズは、富士山の湧水と兵庫・静岡の酒米で造る5銘柄の日本酒です。銘柄ごとの商品ページに加え、水・米・造りの読みもの、料理との合わせ方、取扱店向けの案内を日本語と英語で掲載しています。
購入の導線は2つあります。個人のお客様はカートからStripeの決済ページへ進み、法人のお客様は取扱店として登録し、審査が通ると卸価格とケース単位の価格表を見られるようになります。酒類の通信販売なので、20歳以上であることの確認、未成年飲酒防止の表示、特定商取引法にもとづく表記を備えています。
お店を回す側の画面も作りました。管理画面を開くと売上、対応が必要な注文、在庫の警告が並び、発送と返金、価格と在庫の変更、取扱店の審査、問い合わせへの対応、スタッフの招待までをブラウザで行えます。デザインと実装から、決済と在庫、管理画面、SEO、デプロイと運用まで一貫して担当しています。
02 / HOW IT WORKS
THE DECISIONS
UNDER IT.
実装から
法人としての登録は自己申告なので、登録しただけでは卸価格は見えません。表示の条件は取扱店の審査が承認済みであることで、審査の記録がないアカウントは未承認として扱います。審査状況を読めなかったときも、見せない側に倒します。一度表示した価格は取り消せないためです。酒類販売業免許の番号を必須にしているのは小売店と卸売店だけで、店内で提供する飲食店や宿泊施設には求めません。実態に合わない必須項目は正しい相手を弾き、嘘の入力を招くからです。
Stripeは同じイベントを複数回送ってくることがあります。注文は「未確定の注文だけを確定にする」条件付きのUPDATEで確定させ、実際に更新できた最初の1回だけが在庫を落とし、メールを送ります。メールが送れなくても注文は確定しているので、エラーは返さず記録だけ残します。Stripeに再送させるのは、確定そのものをデータベースに書けなかったときだけです。Stripeのダッシュボードから行った返金やチャージバックも同じ経路で受け取り、全額・一部の返金額を注文に記録します。
銘柄・容量・説明はコードに置き、価格と在庫はデータベースで上書きします。この2つは別の表です。同じ表にすると、価格だけ直したつもりで在庫0の行ができ、その場で完売になってしまいます。在庫はスタッフが棚卸しのたびに動かし、価格はオーナーしか変えられません。行がなければコードの値のまま売れ、データベースが読めないときもコードの価格で販売を続けます。決済・管理画面・卸価格表はすべてこの重ね合わせを読むので、管理画面で変えた価格が効かない経路は残りません。
20歳以上であることは、サイトに入るときと、決済の直前の2回確認します。2回目は画面のチェックボックスだけに頼らず、決済を始めるサーバー側の処理が、確認のない要求を拒否します。Server Actionは画面を通さずに直接呼べるためです。法令の表示は1つのファイルを唯一の出どころにし、まだ確定していない値はそれらしい伏せ字で埋めず、空のまま扱います。伏せ字は本物に見えたまま公開されうるからです。
03 / DELIVERED
WHAT WAS
BUILT.
- 01
5銘柄の商品ページ、水・米・造りの読みもの、料理との合わせ方、日本語・英語対応
- 02
メール認証つきの会員登録、カート、Stripe Checkoutによる決済と、Webhookでの注文確定
- 03
取扱店の登録と審査、承認後にだけ表示する卸価格とケース単位の価格表
- 04
決済中の在庫の引き当てと、しきい値をまたいだときだけ届く在庫の通知
- 05
注文の詳細、印刷して使える領収書、発送前のキャンセル依頼
- 06
管理画面:売上ダッシュボード、注文の絞り込みとCSV書き出し、納品書、全額・一部返金、価格と在庫の編集、取扱店の審査、問い合わせ、2段階の権限をもつスタッフ招待
- 07
年齢確認、未成年飲酒防止の表示、特定商取引法にもとづく表記
- 08
ログイン・登録・問い合わせのレート制限、商品の構造化データ、ページごとのメタデータとサイトマップ
04 / TECHNOLOGY
THE STACK
BEHIND IT.
- Next.js
- React
- TypeScript
- Cloudflare Workers
- D1
- Drizzle
- Better Auth
- Stripe
- Resend
- Tailwind CSS
- Jest

