TEXTBOOK SECTION / AI LEARNING

Square Orders APIと連携する

Square API × Next.js 実践EC開発|自社ECを低コストで作る、決済・在庫・注文管理の設計と実装の「カート・注文・在庫を本格化する」より、Square Orders APIと連携するを解説。生成AI、AI活用、DX、業務改善を実践しながら学べるオンライン教材です。

3カート・注文・在庫を本格化するEC

OVERVIEW

この節で学べること

概要を表示する
項目内容
教材名Square API × Next.js 実践EC開発|自社ECを低コストで作る、決済・在庫・注文管理の設計と実装
カート・注文・在庫を本格化する
Square Orders APIと連携する
カテゴリEC
学習内容生成AI、AI活用、DX、業務改善を実践しながら理解するための教材です。

TABLE OF CONTENTS

目次

CONTENT

ここから

この章でわかること

この章では、Square Orders APIと自前DBの注文データを連携する考え方を整理します。

第9章では、自前DBに保存する注文データを設計しました。

orders
↓
注文全体の情報

order_items
↓
注文された商品の明細

次に必要なのは、この自前DBの注文と、Square側の注文をつなげることです。

SquareにはOrders APIがあります。

Orders APIを使うと、Square側に注文情報を作成できます。

Square公式ドキュメントでは、Orders APIのCreateOrderエンドポイントを使ってOrderオブジェクトを作成でき、Orderにはline items、fulfillments、taxes、discountsなどを含められると説明されています。 (Square)

攻略本でいうと、この章は「自社の注文書をSquareの世界にも登録するステージ」です。


10.1 Orders APIの役割

Orders APIは、Square側で注文情報を扱うためのAPIです。

ECにおける注文は、単に金額だけではありません。

次のような情報を含みます。

何を買ったか
いくつ買ったか
単価はいくらか
小計はいくらか
送料はいくらか
税金はいくらか
割引はあるか
合計金額はいくらか
どの店舗・Locationの注文か

Square Orders APIは、こうした注文情報をSquare側に作るために使います。

SquareのAPIリファレンスでは、Orders APIは販売データ、支払いの商品明細、過去の売上や返品の明細データなどを扱うAPIとして説明されています。 (Square)

なぜOrders APIを使うのか

第7章では、quick_payを使って、1商品をすぐに決済ページへつなげる方法を扱いました。

これは最小構成としては便利です。

しかし、カート機能が入ると、注文の中に複数の商品が入ります。

商品A × 2
商品B × 1
商品C × 3

このような注文を扱う場合は、Square側にも明細付きのOrderを作るほうが管理しやすくなります。

自前DB
↓
orders / order_items

Square
↓
Order / line_items

Orders APIの役割

Orders APIの役割は、次の通りです。

Square側に注文を作る
商品明細を持たせる
税・割引・送料を含める
Squareの決済と注文を紐づける
Square Dashboard上で確認しやすくする

攻略ポイント

Orders APIは、決済そのものではありません。

注文情報をSquare側に作るための道具です。

Orders API
↓
何を買うのかを記録する

Checkout API / Payments API
↓
どう支払うのかを処理する

この違いを押さえておくと、Square連携が理解しやすくなります。


10.2 自前注文とSquare Orderの対応関係

本書では、自前DBの注文とSquare Orderを対応づける設計にします。

つまり、注文情報を2つの場所で扱います。

自前DB
↓
EC運用のための注文データ

Square
↓
決済・Square連携のための注文データ

どちらか一方だけに寄せるのではなく、役割を分けます。

自前DBの注文

自前DBでは、EC運用に必要な情報を管理します。

自社注文ID
注文番号
注文ステータス
決済ステータス
購入者情報
配送先情報
発送ステータス
管理メモ
メール送信履歴
Webhook処理状況

Square Order

Square Orderでは、Square側で扱う注文情報を管理します。

Square Order ID
Location ID
line_items
taxes
discounts
service_charges
fulfillments

対応づけに必要なカラム

自前DBのordersテーブルには、Square側のIDを保存するカラムを持たせます。

alter table orders
add column square_order_id text,
add column square_payment_link_id text,
add column square_payment_id text;

役割は次の通りです。

カラム役割
square_order_idSquare側のOrder ID
square_payment_link_idSquare側のPayment Link ID
square_payment_id実際の支払いID
order_number自社EC側の注文番号

対応関係のイメージ

orders.id
↓
自前DBの内部ID

orders.order_number
↓
お客様に見せる注文番号

orders.square_order_id
↓
Square側の注文ID

orders.square_payment_id
↓
Square側の支払いID

攻略ポイント

自前注文とSquare Orderをつなぐ鍵は、IDです。

自前DBの注文ID
↓
自社運用で使う

Square Order ID
↓
Square側の確認で使う

問い合わせやトラブル時に、両方をたどれる状態にしておきます。


10.3 line_itemsの作り方

line_itemsは、Square Orderの中に入る商品明細です。

自前DBのorder_itemsに近いものです。

order_items
↓
自前DBの注文明細

line_items
↓
Square Order側の商品明細

SquareのCreateOrderでは、Orderオブジェクトの中にline items、fulfillments、taxes、discountsなどを含められます。 (Square)

line_itemsに入れる基本情報

line itemでは、最低限次のような情報を扱います。

商品名
数量
単価
通貨

Square APIへ送るイメージは次のようになります。

{
  "name": "クラシックだし",
  "quantity": "2",
  "base_price_money": {
    "amount": 1200,
    "currency": "JPY"
  }
}

注意点として、SquareのOrderLineItemのquantityは文字列として扱われます。

そのため、TypeScript側で数値として持っている数量を、Squareへ送るときに文字列へ変換します。

quantity: String(item.quantity)

自前DBのorder_itemsから変換する

自前DBのorder_itemsが次の形だとします。

type OrderItem = {
  productId: string;
  productName: string;
  quantity: number;
  unitPriceAmount: number;
  currency: 'JPY';
};

Squareのline_itemsへ変換します。

type SquareLineItem = {
  name: string;
  quantity: string;
  base_price_money: {
    amount: number;
    currency: 'JPY';
  };
};

/**
 * 役割: 自前DBの注文明細をSquare Orderのline_items形式へ変換する
 * 入力: 注文明細配列
 * 出力: Square APIへ送信できるline_items配列
 */
export function toSquareLineItems(orderItems: OrderItem[]): SquareLineItem[] {
  return orderItems.map((item) => ({
    name: item.productName,
    quantity: String(item.quantity),
    base_price_money: {
      amount: item.unitPriceAmount,
      currency: item.currency,
    },
  }));
}

攻略ポイント

order_itemsline_itemsは似ていますが、同じものではありません。

order_items
↓
自前DBに保存する注文時点の商品明細

line_items
↓
Squareへ送るための商品明細

自前DB用の型とSquare API送信用の型は分けると安全です。


10.4 税・送料・割引の扱い

ECでは、商品代金だけでなく、税、送料、割引も考える必要があります。

商品小計
税
送料
割引
合計金額

Square Orders APIでは、注文にtaxes、discounts、service chargesなどを含められます。Square公式ドキュメントでは、Orders APIでtaxes、discounts、service chargesを注文価格計算に適用する方法が案内されています。 (Square)

税の扱い

日本国内のECでは、税込価格で表示することが一般的です。

本書では、最初は税込価格として商品価格を扱う設計にします。

商品価格
↓
税込価格として扱う

この場合、Square Order側では、まずは商品価格そのものを税込金額として送る形にします。

税額を細かく分けて管理する必要がある場合は、後からtaxesの設計を追加します。

送料の扱い

送料は、Square Order上ではservice chargeとして扱う設計が考えられます。

Square公式ドキュメントでは、Order Service Chargesが注文に追加料金を適用する仕組みとして説明されています。Service chargeには計算フェーズなどの考え方があります。 (Square)

最小構成では、送料を次のように扱います。

商品小計
↓
5,000円以上なら送料無料
↓
それ以外は送料700円

Squareへ送るときは、送料をservice chargeとして追加する設計にします。

{
  "name": "送料",
  "amount_money": {
    "amount": 700,
    "currency": "JPY"
  },
  "calculation_phase": "TOTAL_PHASE"
}

割引の扱い

割引には、いくつかの種類があります。

定額割引
割合割引
クーポン割引
送料無料
初回購入割引

Square Orders APIでは、discountsを使って割引を扱えます。OrderLineItemの説明では、ORDERスコープのdiscountは全line itemに自動適用され、LINE_ITEMスコープのdiscountはline item側に適用指定が必要だと説明されています。 (Square)

最初は、割引なしで進めても構いません。

割引は、運用ルールが増えるため、後から追加するのが安全です。

攻略ポイント

税・送料・割引は、最初から複雑にしすぎないことです。

初期構成
↓
税込価格
一律送料
割引なし

拡張構成
↓
税分離
地域別送料
クーポン割引

最初の目的は、注文を正しく作り、決済へ進めることです。


10.5 Square側の注文IDを保存する

Square Orderを作成すると、Square側のOrder IDが返ってきます。

このIDを自前DBのorders.square_order_idに保存します。

SquareのCreateOrder APIでは、Orderを作成するためにPOST /v2/ordersを使い、作成されたOrder情報が返ります。CreateOrderのリクエストでは、Orderオブジェクトとidempotency_keyを指定できます。 (Square)

保存する流れ

1. 自前DBに仮注文を作る
2. order_itemsを保存する
3. Square CreateOrderを呼ぶ
4. Square Order IDを受け取る
5. orders.square_order_idに保存する
6. Checkout APIで決済リンクを作る

なぜ保存するのか

Square Order IDを保存しておくと、後からSquare側の注文を確認できます。

Webhookが届いた
↓
Square Order IDを確認

問い合わせが来た
↓
自前DBの注文番号からSquare Order IDを見る

Square Dashboardで確認したい
↓
Square Order IDを使う

TypeScriptの例

type CreateSquareOrderResult = {
  squareOrderId: string;
};

/**
 * 役割: Square APIのレスポンスからSquare Order IDを取り出す
 * 入力: Square CreateOrderのレスポンス
 * 出力: Square Order ID
 */
function extractSquareOrderId(value: unknown): CreateSquareOrderResult | null {
  if (typeof value !== 'object' || value === null) {
    return null;
  }

  const order = (value as { order?: unknown }).order;

  if (typeof order !== 'object' || order === null) {
    return null;
  }

  const id = (order as { id?: unknown }).id;

  if (typeof id !== 'string') {
    return null;
  }

  return {
    squareOrderId: id,
  };
}

攻略ポイント

Square Order IDは、Square世界の注文番号です。

自前DBに必ず保存します。

自社注文番号
↓
お客様・管理画面用

Square Order ID
↓
Square連携用

両方を持っておくと、運用が安定します。


10.6 注文作成に失敗した場合の処理

Square Orderの作成に失敗することがあります。

たとえば、次のようなケースです。

Access Tokenが間違っている
Location IDが間違っている
line_itemsの形式が不正
Square APIが一時的に失敗している
通信が切れた
環境がSandboxとProductionで混ざっている

このとき、何も考えずに処理を進めると、注文データが中途半端な状態になります。

起きやすい中途半端な状態

自前DBには注文がある
↓
Square Orderは作れていない

Square Orderは作れた
↓
自前DBへの保存に失敗した

Square Orderが作れたか不明
↓
通信エラーでレスポンスが返らない

このような状態を想定して設計します。

自前DB側のステータスを用意する

注文作成中や失敗を表すステータスを持つと安全です。

export type OrderStatus =
  | 'draft'
  | 'pending_payment'
  | 'paid'
  | 'square_order_failed'
  | 'canceled';

流れは次のようにします。

自前DBにdraft注文を作る
↓
Square Order作成を試す
↓
成功したらpending_paymentへ進む
↓
失敗したらsquare_order_failedにする

ユーザー向け表示

Square Order作成に失敗した場合、ユーザーには内部情報を出しません。

表示してよい
↓
購入手続きを開始できませんでした。
時間をおいて再度お試しください。

表示してはいけない
↓
Square Access Tokenが無効です。
CreateOrderのline_itemsが不正です。

攻略ポイント

外部API連携では、失敗する前提で設計します。

成功したら進む
失敗したら止める
不明なら二重作成を避けて確認する

「たぶん成功したはず」で進めないことが大切です。


10.7 冪等性キーの考え方

冪等性キーは、同じ処理が重複して実行されるのを防ぐためのキーです。

Square公式ドキュメントでは、SquareはAPI操作にidempotency keyを提供できるようにすることで、事故的な重複呼び出しから保護すると説明されています。 (Square)

CreateOrder APIでも、idempotency_keyを指定します。

SquareのCreateOrder APIリファレンスでは、idempotency_keyは作成するOrderを一意に識別する値で、Orderが作成されたか不明な場合に同じキーで再試行しても重複作成を心配しなくてよいと説明されています。 (Square)

なぜ必要なのか

ECでは、同じ処理が複数回走ることがあります。

ユーザーがボタンを連打する
通信が遅くて再送される
サーバーがタイムアウトする
ブラウザが再読み込みされる
Webhookが複数回届く

もし毎回新しい注文を作ってしまうと、二重注文になります。

冪等性キーを使うと、同じ処理を同じキーで再試行できます。

1回目
↓
idempotency_key = abc123

通信エラーで不明
↓
もう一度同じキーで送る

Square
↓
同じ注文として扱う

自前DBの注文IDを使う

おすすめは、自前DBの注文IDや注文番号をもとに冪等性キーを作ることです。

/**
 * 役割: 自前DBの注文IDからSquare Order作成用の冪等性キーを作る
 * 入力: 自前DBの注文ID
 * 出力: Square APIへ送る冪等性キー
 */
export function createSquareOrderIdempotencyKey(orderId: string): string {
  return `create-square-order-${orderId}`;
}

こうすると、同じ注文に対して同じ冪等性キーを使えます。

攻略ポイント

冪等性キーは、二重作成を防ぐお守りです。

同じ注文
↓
同じ冪等性キー

別の注文
↓
別の冪等性キー

crypto.randomUUID()を毎回作るだけでは、再試行時に別処理として扱われる可能性があります。

「同じ処理には同じキー」を意識します。


10.8 同じ注文が二重作成されない設計

同じ注文が二重作成されると、ECでは大きなトラブルになります。

同じ商品が2回注文される
同じ金額が2回請求される
在庫が2回減る
メールが2通届く
発送作業が重複する

これを防ぐために、画面側、サーバー側、Square API側の3段階で対策します。

画面側の対策

購入ボタンを押したら、処理中にします。

購入ボタンを押す
↓
ボタンを無効化
↓
二度押しを防ぐ

これはユーザー体験としても重要です。

サーバー側の対策

サーバー側では、同じカート・同じ注文に対して、すでに処理中の注文がないか確認します。

同じ注文が作成済みか確認
↓
作成済みなら再利用
↓
未作成なら新規作成

DBにも一意制約を付けます。

create unique index orders_order_number_unique
on orders(order_number);

Square Order IDも、重複しないようにします。

create unique index orders_square_order_id_unique
on orders(square_order_id)
where square_order_id is not null;

Square API側の対策

CreateOrderでは、冪等性キーを使います。

{
  "idempotency_key": "create-square-order-自前注文ID",
  "order": {
    "location_id": "LOCATION_ID",
    "line_items": []
  }
}

Squareの共通APIパターンのドキュメントでも、多くの作成・更新・削除系APIでは、重複呼び出しによる悪影響を防ぐために冪等性キーが使われると説明されています。 (Square)

攻略ポイント

二重注文対策は、1箇所だけでは不十分です。

画面側
↓
二度押し防止

サーバー側
↓
既存注文チェック

DB側
↓
一意制約

Square側
↓
冪等性キー

何重にも守ることで、事故を減らします。


10.9 テスト注文を作成する

最後に、Square Sandboxでテスト注文を作成します。

Square Sandboxは、本物のお金を動かさずにSquare APIや決済を試せるテスト環境です。

Square公式ドキュメントでは、Sandboxは決済や注文などをシミュレーションできる環境として案内されています。 (Square)

テストの流れ

1. カートに商品を入れる
2. 自前DBにdraft注文を作る
3. Square CreateOrderを呼ぶ
4. Square Order IDを保存する
5. Checkout APIでPayment Linkを作る
6. Square Sandbox決済ページへ移動する
7. テストカードで支払う
8. 自前DBの注文を確認する

CreateOrderの最小リクエスト例

type SquareCreateOrderRequest = {
  idempotency_key: string;
  order: {
    location_id: string;
    line_items: Array<{
      name: string;
      quantity: string;
      base_price_money: {
        amount: number;
        currency: 'JPY';
      };
    }>;
  };
};

/**
 * 役割: Square CreateOrder APIへ送るリクエストボディを作る
 * 入力: Location ID、冪等性キー、line_items
 * 出力: Square CreateOrder API用のリクエストボディ
 */
export function buildCreateSquareOrderRequest(
  locationId: string,
  idempotencyKey: string,
  lineItems: SquareCreateOrderRequest['order']['line_items'],
): SquareCreateOrderRequest {
  return {
    idempotency_key: idempotencyKey,
    order: {
      location_id: locationId,
      line_items: lineItems,
    },
  };
}

CreateOrderを呼び出す例

type CreateSquareOrderResponse = {
  squareOrderId: string;
};

/**
 * 役割: Square Orders APIを呼び出してSquare側に注文を作成する
 * 入力: Square APIの接続情報とCreateOrderリクエスト
 * 出力: 作成されたSquare Order ID
 */
export async function createSquareOrder(
  accessToken: string,
  squareBaseUrl: string,
  requestBody: SquareCreateOrderRequest,
): Promise<CreateSquareOrderResponse> {
  const response = await fetch(`${squareBaseUrl}/v2/orders`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      'Square-Version': '2026-05-20',
    },
    body: JSON.stringify(requestBody),
  });

  const responseData: unknown = await response.json();

  if (!response.ok) {
    throw new Error('Square Orderの作成に失敗しました。');
  }

  const result = extractSquareOrderId(responseData);

  if (!result) {
    throw new Error('Square Order IDを取得できませんでした。');
  }

  return result;
}

テストで確認すること

Square Order IDが返る
自前DBにsquare_order_idが保存される
line_itemsの数量が正しい
単価が正しい
送料が意図通りに入る
同じ冪等性キーで再試行しても二重作成されない
失敗時に注文ステータスが壊れない

攻略ポイント

Sandboxテストでは、成功パターンだけを見て終わらないことです。

成功する注文
失敗する注文
二重送信
売り切れ商品
不正な数量
Square APIエラー

失敗時の動きを確認しておくと、本番公開後の事故を減らせます。


実装全体の流れ

この章の内容を実装フローとしてまとめると、次のようになります。

カートを確認
↓
サーバー側で商品価格を再計算
↓
自前DBにdraft注文を作成
↓
order_itemsを保存
↓
Square CreateOrderを呼び出す
↓
square_order_idを自前DBに保存
↓
Checkout APIでPayment Linkを作成
↓
ユーザーをSquare決済ページへ移動

この流れを作ることで、自前DBとSquareの注文情報をつなげられます。


この章のまとめ

この章では、Square Orders APIと自前DBの注文データを連携する考え方を整理しました。

Orders APIは、Square側に注文情報を作成するためのAPIです。

CreateOrderでは、Orderオブジェクトを作成でき、line items、fulfillments、taxes、discountsなどを含められます。 (Square)

この章で扱った内容は、次の通りです。

Orders APIの役割
自前注文とSquare Orderの対応関係
line_itemsの作り方
税・送料・割引の扱い
Square側の注文IDを保存する
注文作成に失敗した場合の処理
冪等性キーの考え方
同じ注文が二重作成されない設計
テスト注文の作成

特に重要なのは、次の3つです。

1. 自前DBの注文IDとSquare Order IDを対応づける
2. line_itemsはサーバー側で正しい商品情報から作る
3. 冪等性キーで二重作成を防ぐ

Square Orderは、Square側の注文情報です。

自前DBの注文は、自社EC運用の注文情報です。

Square Order
↓
Square連携・決済側の注文

自前DB orders
↓
管理画面・配送・メール・社内運用の注文

この2つを正しくつなぐことで、Webhook、在庫管理、メール通知、管理画面へ進みやすくなります。


次の章でやること

次の章では、在庫管理を実装します。

注文を作れるようになると、次に問題になるのが在庫です。

商品が購入されたら、いつ在庫を減らすのか。

決済前に減らすのか、決済後に減らすのか。

Square Inventory APIを使うのか、自前DBで管理するのか。

次章では、在庫管理の難しさを整理しながら、最初に作るべき現実的な在庫設計を攻略していきます。

FAQ

よくある質問

Square Orders APIと連携するは医療関係者向けだけの内容ですか。
医療分野の例が含まれる場合もありますが、医療関係者だけに限定した内容ではありません。生成AI、AI活用、DX、業務改善、プロトタイプ開発など、一般的なAI学習の事例として読める内容です。
AI初心者でも読めますか。
はい。AIをこれから学ぶ方、数学が苦手な方、仕事でAIを使いたい方にも読み進めやすいように、教材の章と節の流れに沿って整理しています。
サムネイル画像は必ず表示されますか。
はい。教材にcoverUrlが設定されている場合はその画像を表示し、未設定の場合は代替サムネイル画像を表示します。
Square API × Next.js 実践EC開発|自社ECを低コストで作る、決済・在庫・注文管理の設計と実装のほかの章も読めますか。
はい。教材トップから章立てを確認でき、前後の節へもページ下部のナビゲーションから移動できます。