Square 取引データとレシートローラー取引データのマッピング

Square POS連携 データマッピング 技術詳細 取引データ API

Square API から取得した取引データを、レシートローラーの取引データモデルにマッピングする仕組みの技術解説です。フィールド単位の対応表、ステータスコードの変換、支払い方法の正規化、明細・顧客・スタッフ情報の解決、タイムゾーンと冪等性の扱いなど、内部仕様を理解したい開発者・運用担当者向けに整理しています。

本記事はレシートローラー側の SquarePaymentMapper の挙動をまとめたものです。一般的な「Square と連携する」「同期するとどうなる」といった操作手順は Square の POS 連携設定 をご覧ください。フィールド単位の正規モデル仕様は PosTransactionDto 仕様(フィールドリファレンス) を参照してください。

基本構造

Square と レシートローラーでは、取引データの粒度に違いがあります。

  • Square 側は Payment(支払い)と Order(注文)の 2 つに分かれています。Payment が決済情報、Order が明細情報を持ちます
  • レシートローラー側は 1 つの PosTransactionDto に支払い + 明細 + 顧客 + スタッフを集約します
  • 取得時は Payment を起点に、関連する Order・TeamMember・Customer を追加で取りに行きます

主要フィールドの対応表

レシートローラー側Square 側備考
TransactionIdPayment.idSquare の支払い ID をそのまま採用。冪等な upsert のキーになります
ExternalTransactionIdPayment.id同上(外部参照用に重複保持)
TransactionDateTimePayment.created_atISO 8601 文字列 → UTC DateTime へ変換
CurrencyPayment.amount_money.currency通貨コード。既定 JPY
TotalAmountPayment.amount_money.amountJPY はそのまま、他通貨は smallest unit (cents) → 主単位に変換
TaxAmountPayment.tax_money.amount同上
SubtotalAmount計算値amount - tax
DiscountAmountPayment.discount_money.amount同上
TipAmountPayment.tip_money.amountチップ。ある場合のみ
PaymentMethodPayment.card_details の有無カードデータがあれば CreditCard、なければ Other(主たるテンダー。内訳は下記 Payments
Payments[]Payment 1 件 + card_details.cardテンダー内訳。Method / Amounttotal_money)/ Brand(card_brand)/ Last4(last_4)
StatusPayment.status下記「ステータス対応表」
ReceiptNumberPayment.receipt_numberSquare が発番
ReceiptUrlPayment.receipt_url顧客向けレシート URL。構造化フィールドに保持(以前は Notes に格納していましたが廃止)
ExternalIdsorder_id / location_id / customer_idベンダー横断 ID(ProviderOrderId / LocationId / ProviderCustomerId
StaffIdPayment.team_member_id未割当の場合は空
StaffNameTeamMember.display_name別途 TeamMembers API で解決
Source固定値 "API" または "Webhook"取得経路に応じて
RawJsonPayment + Order の生ペイロードモデル化していないフィールド(カード fingerprint 等)も復元できるよう保管。API では返しません
LineItemsOrder.line_items[]別途 Orders API で解決。下記「明細のマッピング」

ステータス対応表

Square Payment.statusレシートローラー Status意味
COMPLETEDCompleted会計完了
CANCELEDVoidedキャンセル
FAILEDVoided失敗(売上には含めません)
その他Pending処理中・未確定

金額の通貨変換

Square の Money オブジェクトは通貨ごとに最小単位の扱いが異なります。

  • JPY: 1 円が最小単位。amount をそのまま採用
  • USD・EUR など: 1 セントが最小単位。amount / 100 で主単位に変換

レシートローラー側はすべて主単位 (decimal) で保持し、通貨コードを Currency に保持します。

明細のマッピング

Square の Payment には明細情報が含まれていないため、関連する Order を別途取得して明細を展開します。Order が取得できなかった場合(権限不足・API エラー・OAuth トークン期限切れなど)は明細なしで取引が保存され、後から再同期で補完できます。

レシートローラー LineItemSquare Order.line_items[]備考
ProductNamename + variation_nameバリエーションがあれば「商品名 (バリエーション名)」形式
Quantityquantity文字列を整数にパース。失敗時は 1
UnitPricebase_price_money.amount通貨変換あり
Subtotaltotal_money.amount取得できない場合は UnitPrice × Quantity
TaxRate計算値(total_tax_money / (total_money - total_tax_money)) × 100 を小数 1 桁で四捨五入
TaxAmounttotal_tax_money.amount明細単位の税額。税率だけでなく金額も保持します
DiscountAmounttotal_discount_money.amount明細単位の割引額
CatalogObjectIdcatalog_object_idSquare カタログとの連携 ID
Modifiersmodifiers[]オプション・モディファイア(name + total_price_money
Category現状は常に空。Square Catalog API での解決は将来検討

顧客マッチキーの抽出

レシートローラーの自動配信パイプライン(CRM 連携)に渡すため、Square 側の顧客識別子を抽出します。

  • 主キー: Payment.customer_id(Square Customer Directory の顧客 ID)。取引には ExternalIds.ProviderCustomerId としても保持します
  • フォールバック: Payment.card_details.card.fingerprint(カード番号のハッシュ。PAN ではなく Square が生成した安定識別子。RawJson 内に保持し、API では返しません)

電話番号・メールは Square Payment には含まれないため、Customer Directory への追加 API 呼び出しが必要です。現状はカード fingerprint で十分マッチするケースが多いため省略しています。

OAuth トークンの自動リフレッシュ

Square OAuth アクセストークンは約 30 日で期限切れになります。Webhook 経路では、明細・スタッフ名取得の直前に terminal.AccessToken の有効期限を確認し、60 秒以内に切れる場合は RefreshToken で自動更新します(更新後は端末レコードに永続化)。これにより長期間 webhook 駆動の店舗でも明細の取りこぼしが起きません。

冪等性

同じ取引が複数回届いた場合(Square 側のリトライ・手動同期と Webhook の重複など)も、Payment.id をキーにした upsert で安全に再保存されます。レシートローラー側で重複レシートが発行されることはありません。

関連記事

公開日: 2026-05-29 更新日: 2026-06-21
関連記事