サイトアイコンmaita tomoya dev io

ECサイトを作る場合: 決済・在庫管理・検索・SEOの技術選定

case-studies

ECサイトを作る場合: 決済・在庫管理・検索・SEOの技術選定

はじめに

ECサイト(Electronic Commerce)の構築は、決済処理、在庫管理、商品検索、SEO対策など、多くの技術的課題を同時に解決する必要があります。本記事では「Shopifyを使うか、自作するか」という根本的な判断から、自作する場合の具体的な技術構成まで解説します。

身近な例えで理解するECサイトの技術課題

ECサイトは「デパート」の運営に似ています。

  • 決済システム = レジ。お金を正確に、安全に処理する(最も重要で失敗が許されない)
  • 在庫管理 = 倉庫管理。「残り1個」を2人が同時に買おうとしたらどうする?
  • 商品検索 = フロアガイド。お客様が欲しい商品を素早く見つけられるように
  • SEO = 広告とのれん。Google検索で見つけてもらえるように
  • カート = ショッピングカート。途中で離脱しても中身を覚えておく

Shopify vs 自作: 判断フロー

[ECサイト構築の判断]
    |
    v
[独自の業務ロジックが必要?]
    |
    +-- いいえ --> [月商1,000万円以上になる見込み?]
    |                |
    |                +-- いいえ --> Shopify(最も手軽)
    |                |
    |                +-- はい --> Shopify Plus or 自作
    |
    +-- はい
         |
         v
    [どの程度のカスタマイズが必要?]
         |
         +-- デザインのみ --> Shopify + テーマカスタマイズ
         |
         +-- 機能追加が必要 --> Shopify + アプリ/Hydrogen
         |
         +-- 完全なカスタム --> 自作
              (独自の決済フロー、複雑な在庫管理、
               既存システムとの深い統合が必要な場合)

Shopify vs 自作の比較

項目Shopify自作(Next.js + Stripe)
初期構築期間数日〜数週間3〜6ヶ月
初期費用$0〜数百万円〜
月額費用$39〜$399 + 手数料サーバー費 + 保守費
決済手数料3.4%〜Stripe: 3.6%
カスタマイズ性中(テーマ + アプリ)最高
SEO良好自由自在
スケーラビリティShopifyが管理自分で管理
保守運用Shopifyが管理自分で管理
PCI DSS準拠Shopifyが対応Stripe利用で大幅に軽減

自作する場合の全体アーキテクチャ

推奨構成: Next.js + Stripe + PostgreSQL

                    +-------------------+
                    |   CloudFront      |
                    |   (CDN + WAF)     |
                    +--------+----------+
                             |
                    +--------v----------+
                    |   Next.js         |
                    |   (SSR/SSG)       |
                    |   on Vercel       |
                    +--------+----------+
                             |
                    +--------v----------+
                    |   ALB             |
                    +--------+----------+
                             |
              +--------------+--------------+
              |              |              |
      +-------v------+ +----v-------+ +----v--------+
      |API Server    | |Payment     | |Search       |
      |NestJS        | |Service     | |Service      |
      |(商品/注文/   | |(Stripe     | |(OpenSearch) |
      | ユーザー)    | | Webhook)   | |             |
      +-------+------+ +----+-------+ +----+--------+
              |              |              |
       +------v------+  +---v---+    +-----v-----+
       |PostgreSQL   |  |Stripe |    |OpenSearch  |
       |(Aurora)     |  |API    |    |Cluster     |
       +------+------+  +-------+    +-----------+
              |
       +------v------+
       |Redis         |
       |(ElastiCache) |
       |セッション/   |
       |カート/在庫   |
       +-------------+

       +-------------------------------------------+
       |  バックグラウンド処理                      |
       |  - SQS: 注文処理キュー                    |
       |  - Lambda: メール送信、画像処理            |
       |  - EventBridge: 在庫アラート               |
       |  - S3: 商品画像保存                        |
       +-------------------------------------------+

技術選定の詳細

フロントエンド: Next.js

要件Next.jsでの対応方法
SEOSSR/SSGで事前レンダリング。構造化データ(JSON-LD)対応
商品ページISR(増分静的再生成)で高速表示 + 最新データ
カートClient-sideのState管理(Zustand等)
決済ページStripe Elementsの埋め込み
レスポンシブTailwind CSSでモバイル対応

バックエンド: NestJS (Node.js)

NestJSを選ぶ理由:

  • TypeScriptネイティブ
  • モジュール構造でドメイン分離が容易
  • デコレーターベースのAPI定義
  • Swagger自動生成
  • テストが書きやすい

決済: Stripe

決済サービス手数料特徴
Stripe3.6%開発者体験最高、API充実
PayPay1.98%〜日本のモバイル決済
GMO PaymentGateway3.2%〜日本の主要決済代行
Square3.25%対面/オンライン両対応

Stripeを選ぶ理由:

  • APIファーストの設計で開発が容易
  • Webhookで決済イベントを確実に受信
  • Stripe Checkoutで安全な決済フォームを簡単に実装
  • サブスクリプション、分割払い、クーポンなど豊富な機能
  • PCI DSS準拠の負担を大幅に軽減

データベース: PostgreSQL (Aurora)

[テーブル設計の概要]

users           -- ユーザー情報
products        -- 商品マスタ
product_variants -- 商品バリエーション(サイズ、色等)
inventory       -- 在庫管理
orders          -- 注文ヘッダー
order_items     -- 注文明細
payments        -- 決済情報
addresses       -- 配送先
categories      -- カテゴリ
reviews         -- レビュー

在庫管理の設計

在庫管理で最も重要な課題: 在庫の競合

2人のユーザーが同時に「残り1個」の商品を購入しようとした場合の対処。

方式の比較

方式仕組みメリットデメリット
悲観的ロックDB行ロック(SELECT FOR UPDATE)確実パフォーマンス低下
楽観的ロックバージョン番号チェック高パフォーマンスリトライが必要
Redis在庫カウンターRedisでアトミックにデクリメント超高速Redis障害時の整合性

推奨: Redis在庫カウンター + DBの楽観的ロック

[在庫確保の流れ]

1. カートに追加時
   Redis: DECR inventory:product_123
   → 0以上なら「仮確保」成功
   → 0未満なら「在庫切れ」、INCR で戻す

2. 決済完了時
   DB: UPDATE inventory SET quantity = quantity - 1
       WHERE product_id = 123 AND quantity > 0
   → 成功: 注文確定
   → 失敗: Redisの在庫を戻す

3. カート放棄時(30分後)
   Redis: INCR inventory:product_123
   → 仮確保を解放

検索機能

検索要件

要件説明
キーワード検索商品名、説明文からの全文検索
ファセット検索カテゴリ、価格帯、ブランド等でのフィルタリング
サジェスト入力途中での候補表示
類似検索「赤いTシャツ」→「レッドのTシャツ」もヒット
ソート価格順、新着順、人気順

OpenSearchの構成

[商品データ(PostgreSQL)]
    |
    v
[DMS / Lambda(同期ジョブ)]
    |
    v
[OpenSearch Index]
    |-- 商品名(日本語形態素解析: kuromoji)
    |-- 説明文
    |-- カテゴリ(ファセット用)
    |-- 価格(範囲検索用)
    |-- タグ
    |
    v
[検索API] --> [フロントエンドの検索結果]

SEO対策

ECサイトのSEO要件

対策実装方法
構造化データJSON-LD(Product、BreadcrumbList、Review等)
メタタグ商品ごとにtitle、description、OGP画像を動的生成
サイトマップNext.jsのnext-sitemapで自動生成
パンくずリストカテゴリ階層を反映
ページ速度ISR + 画像最適化 + CDN
モバイル対応レスポンシブデザイン
canonical URL重複コンテンツの防止
robots.txtクロール制御

ISR(増分静的再生成)の活用

[商品ページの配信戦略]

1. 初回アクセス
   → SSGでビルド済みのHTMLを返す(高速)

2. revalidate期間経過後
   → バックグラウンドで再生成
   → 次のアクセスから新しいHTMLを返す

3. 新商品追加
   → On-demand ISRで即座に生成
   → APIからrevalidateをトリガー

チーム規模と開発スケジュール

MVP(3ヶ月)

役割人数担当範囲
フロントエンド2人商品一覧/詳細、カート、決済ページ
バックエンド2人API、決済連携、在庫管理
インフラ1人AWS構築、CI/CD
デザイン1人UI/UXデザイン
PM1人進捗管理、要件定義
合計7人3ヶ月

MVPの機能:

  • 商品一覧/詳細/検索
  • カート
  • 会員登録/ログイン
  • Stripe決済
  • 注文履歴
  • 管理画面(商品/注文管理)

本格展開(6ヶ月追加)

追加機能必要人数期間
レコメンデーション1人2ヶ月
レビュー/評価システム1人1ヶ月
ポイント/クーポン1人2ヶ月
メール配信(カート放棄等)1人1ヶ月
分析ダッシュボード1人2ヶ月

コスト見積り

MVPフェーズ(〜月商100万円)

サービス構成月額
VercelProプラン$20
ECS/Fargate2タスク$40
Aurora PostgreSQLdb.t3.medium$130
ElastiCache Rediscache.t3.micro$25
S3 + CloudFront50GB + 50GB転送$10
OpenSearcht3.small.search$35
Stripe手数料月商100万円の3.6%$260 (36,000円)
合計(Stripe手数料除く)約$260/月

成長フェーズ(〜月商1,000万円)

サービス構成月額
VercelTeamプラン$100
ECS/Fargate4タスク x 1vCPU$200
Aurora PostgreSQLdb.r6g.large + Replica$600
ElastiCache Rediscache.r6g.large$200
S3 + CloudFront500GB + 500GB転送$80
OpenSearch3ノード$200
SESメール送信$10
Stripe手数料月商1,000万円の3.6%$2,600 (360,000円)
合計(Stripe手数料除く)約$1,390/月

Shopifyを選ぶ場合のアーキテクチャ

Shopify + カスタムフロントエンド(Hydrogen/Next.js)

[ユーザー]
    |
    v
[Next.js (カスタムフロント)]
    |
    v
[Shopify Storefront API (GraphQL)]
    |
    +-- 商品データ取得
    +-- カート管理
    +-- 決済(Shopify Checkout)
    +-- 注文管理
    |
[Shopify Admin API]
    |
    +-- 在庫管理
    +-- 注文処理
    +-- 顧客管理

Shopify + ヘッドレスのメリット:

  • バックエンド(決済、在庫、注文)はShopifyが管理
  • フロントエンドは完全にカスタマイズ可能
  • SEOも自由にコントロール

デメリット:

  • Shopifyの月額費用 + 決済手数料が発生
  • Shopify APIの制約を受ける
  • 複雑な在庫ロジックは実装しにくい

決済のセキュリティ

PCI DSS準拠

クレジットカード情報を扱うシステムは、PCI DSS(Payment Card Industry Data Security Standard)に準拠する必要がある。

方式PCI DSS負担説明
Stripe Elements最小(SAQ A)カード情報はStripeのiframeで処理。自社サーバーにカード情報が一切流れない
Stripe Checkout最小(SAQ A)Stripeの決済ページにリダイレクト
自社で直接処理最大(SAQ D)カード情報を自社サーバーで処理。年間数千万円のコスト

推奨: Stripe Elementsを使い、自社サーバーにクレジットカード情報を一切保存しない設計にする。


まとめ

判断の要約

状況推奨
小規模EC、早く始めたいShopify
デザインを自由にしたいShopify + ヘッドレス(Next.js)
複雑な業務ロジックがある自作(Next.js + NestJS + Stripe)
超大規模、完全な制御自作(フルカスタム)

推奨技術スタック(自作の場合)

レイヤー技術理由
フロントエンドNext.jsSSR/ISR、SEO最適化
バックエンドNestJSTypeScript、モジュール構造
データベースPostgreSQL (Aurora)信頼性、トランザクション
キャッシュRedisセッション、在庫カウンター
決済Stripe開発者体験、PCI DSS軽減
検索OpenSearch全文検索、ファセット
画像S3 + CloudFrontスケーラブル、CDN配信

ECサイトは「お金を扱う」という特性上、セキュリティと信頼性が最も重要。Stripeのような信頼できる決済プロバイダーを活用し、自社はビジネスロジックに集中するのが最善の戦略である。


参考リンク