-
Notifications
You must be signed in to change notification settings - Fork 101
Open
Description
refs EC-CUBE/ec-cube#6574
概要(Overview)
Google Merchant の ユニバーサル コマース プロトコル(UCP) を使用した購入完了機能の実装
https://developers.google.com/merchant/ucp/guides/checkout/native?hl=ja
2系に元々ある API 機能の実装は古すぎるので無視してよいと思います
期待する内容(Expect) or 要望(Requirement)
ユニバーサル コマース プロトコル(UCP)を使用して購入完了できる
実装必須の3つのエンドポイント
1. 購入手続きセッション作成エンドポイント
- エンドポイント:
POST /checkout-sessions - 役割: ユーザーが商品購入を決定した際に、購入検討中の商品を含むセッションを作成
- リクエスト: 商品情報(ID、タイトル)、数量、通貨
- レスポンス: セッションID、合計額、税金(推定)、決済ハンドラー情報、利用規約・プライバシーポリシーへのリンク
2. セッション更新エンドポイント
- エンドポイント:
PUT /checkout-sessions/{id} - 役割: 配送先住所更新時の税金・配送オプション再計算など、セッション情報の変更対応
- リクエスト: 更新された配送先、決済情報を含む完全なチェックアウトオブジェクト
- レスポンス: 再計算された税金、送料、合計額、配送方法オプション
3. セッション完了エンドポイント
- エンドポイント:
POST /checkout-sessions/{id}/complete - 役割: ユーザーが「注文する」をクリックした際のセッション完了と注文確定
- リクエスト: 決済情報とリスクシグナル
- レスポンス: 注文IDと注文へのパーマリンクURL
追加が必要なデータフィールド
1. 新規テーブル: dtb_checkout_session(必須)
UCPのセッション管理用に新規テーブルが必要
| カラム名 | 型 | Default | Nullable | Comment |
|---|---|---|---|---|
checkout_session_id |
integer | (auto) | false | チェックアウトセッションID (PRIMARY KEY) |
session_id |
text | false | UCPセッションID(UUID形式、UNIQUE) | |
status |
smallint | 1 | false | セッション状態: 1=incomplete / 2=completed |
currency |
text | 'JPY' | false | 通貨コード |
expires_at |
timestamp | true | セッション有効期限 | |
order_id |
integer | true | 関連受注ID(完了後に設定) | |
order_temp_id |
text | true | 関連受注一時ID | |
buyer_data |
text | true | 購入者情報(JSON: first_name, last_name, email) | |
fulfillment_data |
text | true | 配送先・配送方法選択情報(JSON) | |
payment_data |
text | true | 決済情報(JSON) | |
selected_shipping_option |
text | true | 選択された配送オプションID | |
create_date |
timestamp | CURRENT_TIMESTAMP | false | 作成日時 |
update_date |
timestamp | false | 更新日時 | |
del_flg |
smallint | 0 | false | 削除フラグ |
インデックス:
dtb_checkout_session_session_id_keyON (session_id) - UNIQUEdtb_checkout_session_order_id_keyON (order_id)
2. 店舗設定への追加フィールド(dtb_baseinfo)
| カラム名 | 型 | Default | Nullable | Comment |
|---|---|---|---|---|
privacy_policy_url |
text | true | プライバシーポリシーURL | |
terms_of_service_url |
text | true | 利用規約URL | |
ucp_enabled |
smallint | 0 | false | UCP機能有効フラグ (0=無効, 1=有効) |
google_pay_merchant_id |
text | true | Google Pay マーチャントID | |
google_pay_merchant_name |
text | true | Google Pay マーチャント名 |
3. 配送業者への追加フィールド(dtb_deliv)(任意)
| カラム名 | 型 | Default | Nullable | Comment |
|---|---|---|---|---|
estimated_delivery_days_min |
integer | true | 最短お届け日数 | |
estimated_delivery_days_max |
integer | true | 最長お届け日数 | |
carrier_code |
text | true | 配送業者コード |
データ形式のマッピング対応
住所フォーマット変換(EC-CUBE 2系 → UCP)
EC-CUBE 2系は電話番号・郵便番号が分割されているため、結合処理が必要
| EC-CUBE 2 | UCP | 変換処理 |
|---|---|---|
order_name01 + order_name02 |
recipient_name |
姓名結合 |
order_zip01 + order_zip02 または order_zipcode |
postal_code |
結合または海外対応フィールド使用 |
mtb_pref.name (via order_pref) |
region |
都道府県名取得 |
order_addr01 |
locality |
市区町村 |
order_addr02 |
address1, address2 |
番地・建物名 |
mtb_country.iso_code (via order_country_id) |
country |
ISO 3166-1 alpha-2 |
order_tel01 + order_tel02 + order_tel03 |
phone |
電話番号結合 |
購入者情報マッピング
| EC-CUBE 2 | UCP | 備考 |
|---|---|---|
order_name01 |
last_name |
姓 |
order_name02 |
first_name |
名 |
order_email |
email |
メールアドレス |
order_tel01-order_tel03 |
phone |
電話番号(結合) |
金額単位変換(センス/マイナー単位)
UCPでは金額をマイナー単位(整数)で表現する。
| 通貨 | 補助単位 | 変換例 |
|---|---|---|
| USD(米ドル) | セント | $10.50 → 1050 |
| EUR(ユーロ) | セント | €10.50 → 1050 |
| JPY(日本円) | なし | ¥1000 → 1000(変換不要) |
日本円は「ゼロデシマル通貨」のため、基本的に変換不要(numeric → int のキャストのみ)
// JPY専用のシンプルな実装
$ucpAmount = (int) round($order['total']);
// 多通貨対応の場合
function toMinorUnits($amount, $currency = 'JPY') {
$decimals = array(
'JPY' => 0, 'KRW' => 0, 'TWD' => 0, // ゼロデシマル通貨
);
$dec = isset($decimals[$currency]) ? $decimals[$currency] : 2;
if ($dec === 0) {
return (int) round($amount);
}
return (int) round($amount * pow(10, $dec));
}実装タスク
Phase 1: 基盤構築
-
dtb_checkout_sessionテーブル作成(マイグレーションSQL) -
dtb_baseinfoへのUCP関連カラム追加 -
SC_Helper_CheckoutSessionヘルパークラス作成
Phase 2: API実装
-
LC_Page_Api_CheckoutSessionクラス作成 -
POST /checkout-sessionsエンドポイント実装 -
PUT /checkout-sessions/{id}エンドポイント実装 -
POST /checkout-sessions/{id}/completeエンドポイント実装 - 既存
SC_Helper_Purchaseとの連携
Phase 3: 変換・サービス層
- 住所フォーマット変換関数実装(電話番号・郵便番号結合)
- 金額単位変換関数実装
- 税金・送料再計算ロジック実装
Phase 4: 品質・セキュリティ
- リクエストバリデーション実装(
SC_CheckError活用) - エラーハンドリング(UCPプロトコル準拠のJSON形式)
- API認証・セキュリティ対策
- CSRF対策
Phase 5: テスト・運用
- PHPUnit テスト作成
- API仕様書作成
- Google Merchant設定手順ドキュメント
EC-CUBE 4系との実装差異
| 項目 | EC-CUBE 2系 | EC-CUBE 4系 |
|---|---|---|
| アーキテクチャ | 手続き型・LC_Page ベース | Symfony Controller ベース |
| ORM | SC_Query(生SQL) | Doctrine ORM |
| 購入処理 | SC_Helper_Purchase | PurchaseFlow(プロセッサパターン) |
| バリデーション | SC_CheckError | Symfony Validator |
| セッション管理 | $_SESSION 直接操作 | Symfony Session |
| JSONレスポンス | 手動echo | JsonResponse |
| 電話番号 | 3分割(tel01, tel02, tel03) | 1フィールド(phone_number) |
| 郵便番号 | 2分割 or 海外対応1フィールド | 1フィールド(postal_code) |
| 受注一時情報 | dtb_order_temp テーブル | pre_order_id による管理 |
既存クラスの活用
| 既存クラス | 用途 |
|---|---|
SC_Helper_Purchase |
受注処理(registerOrderComplete, registerOrder等) |
SC_Helper_Delivery |
配送業者・送料取得 |
SC_Helper_TaxRule |
税率計算 |
SC_CartSession |
カート操作 |
SC_CheckError |
バリデーション |
SC_Response |
レスポンス出力 |
技術的考慮事項
- 既存購入フローとの共存: 既存の
LC_Page_Shopping_*による購入フローとUCP経由の購入フローの統合 - 受注一時テーブル活用:
dtb_order_tempを活用したセッション管理の検討 - トランザクション管理: 受注完了時の複合トランザクション(dtb_order, dtb_order_detail, dtb_shipping, dtb_shipment_item)
- 在庫管理:
SC_Helper_Purchase::registerOrderComplete()内の在庫減少処理との連携 - ポイント管理:
add_point,use_pointとの整合性 - セッション有効期限:
dtb_checkout_session.expires_atによる期限切れ処理 - クリーンアップ: 期限切れセッションの定期削除(cron)
参考リソース
- Google UCP ドキュメント
- EC-CUBE 4系 UCP Issue
- 既存実装参考:
data/class/helper/SC_Helper_Purchase.phpdata/class/pages/shopping/LC_Page_Shopping_Complete.phpdata/class/SC_CartSession.php
- テーブル定義:
docs/database-schema/public.dtb_order.mddocs/database-schema/public.dtb_shipping.mddocs/database-schema/public.dtb_baseinfo.md
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels