この記事について
「ポイントを使う」という行為を、「ポイントを消費してクーポンを発行し、そのクーポンで割引を受ける」という仕組みに置き換えました。その技術的なアーキテクチャを詳しく解説します。
変換処理の全体像
システム間の連携
入力UI、結果表示、コピー機能
処理制御、認証検証、トランザクション
Shopifyクーポン作成API、POSポイント操作API
処理ステップの詳細
顧客からの変換リクエストを受信し、認証を確認
POS APIでリアルタイムの残高を取得し、変換可能か検証
Shopify Admin APIで顧客専用のクーポンを作成
POS APIで指定ポイント分を残高から減算
発行したクーポン情報を顧客のメタフィールドに記録
クーポンコードと詳細情報をフロントエンドに返却
各ステップの詳細
ステップ1-2: リクエスト受付と残高確認
顧客ID: 12345、変換希望ポイント: 500pt、認証トークン: xxx
トークン有効性確認 → OK / 顧客ID所有権確認 → OK
API呼び出し: GET /customers/12345/points → 残高 1250pt
残高(1250) >= 希望(500) → OK / 最小変換単位: 100pt → OK / 変換上限: 10000pt/日 → OK
全てのチェックを通過
ステップ3: Shopifyクーポン生成
| 価格ルール(PriceRule)項目 | 設定値 |
|---|---|
| 割引タイプ | 固定金額 |
| 割引額 | -500円 |
| 使用回数 | 1回のみ |
| 顧客制限 | 特定顧客のみ |
| 有効期間 | 1年間 |
| 最低購入額 | なし |
Shopify Admin API呼び出し: エンドポイント priceRules + discountCodes
生成されるコード例: 70934-AB12CD-500
レスポンス: priceRuleId, discountCodeId, code
ステップ4: POSポイント減算
| 項目 | 値 |
|---|---|
| エンドポイント | POST /customers/12345/points/deduct |
| リクエスト amount | 500 |
| リクエスト reason | クーポン変換 |
| リクエスト reference | COUPON-70934-AB12CD-500 |
| レスポンス success | true |
| レスポンス previous_balance | 1250 |
| レスポンス deducted | 500 |
| レスポンス new_balance | 750 |
重要: 変換を追跡できるよう参照情報(reference)を記録
ステップ5: メタフィールド保存
保存先: 顧客のShopifyメタフィールド(名前空間: loyalty、キー: coupons)
| 保存項目 | 例 |
|---|---|
| code | 70934-AB12CD-500 |
| amount | 500 |
| points_used | 500 |
| created_at | 2024-01-15T10:30:00Z |
| expires_at | 2025-01-15T23:59:59Z |
| status | active |
| shopify_price_rule_id | 12345678 |
用途: マイページでの一覧表示、使用状況の追跡、取り消し時の参照
トランザクション設計
なぜ順序が重要か
理想の順序: 1. クーポン作成 → 2. ポイント減算 → 3. 記録保存
| 順序 | 処理 | 理由 |
|---|---|---|
| 1番目 | クーポン作成 | 取り消し可能。作成失敗ならポイントは減らさない |
| 2番目 | ポイント減算 | クーポンができてから減算。減算失敗ならクーポンを削除 |
| 3番目 | 記録保存 | 全て成功してから記録。記録失敗しても実体は完了している |
エラー時のロールバック
| エラーケース | 対応 | 結果 |
|---|---|---|
| クーポン作成失敗 | 何もしない(まだ何も変更していない) | エラーメッセージを表示 |
| ポイント減算失敗 | 作成したクーポンを削除 | エラーメッセージを表示 |
| メタフィールド保存失敗 | ログに警告記録(ロールバックしない) | 成功として扱い、管理者に通知 |
補足: メタフィールド保存は「nice to have」。実体(クーポンとポイント)が正しければ運用でカバー可能
API呼び出しの実装ポイント
リトライ戦略
| API | リトライ | 理由 |
|---|---|---|
| Shopifyクーポン作成 | 3回まで | 一時的なエラーの可能性 |
| POSポイント減算 | リトライしない | 二重減算を防ぐため |
| メタフィールド保存 | 3回まで | 失敗しても実害が少ない |
タイムアウト設定
| API | タイムアウト | 理由 |
|---|---|---|
| Shopifyクーポン作成 | 10秒 | Shopify APIは安定している |
| POSポイント減算 | 15秒 | POSによっては遅い場合がある |
| メタフィールド保存 | 5秒 | Shopify APIは安定している |
パフォーマンスの考慮
処理時間の内訳
| 処理ステップ | 所要時間 |
|---|---|
| 認証検証 | 約100ms |
| POS残高照会 | 約500ms |
| Shopifyクーポン作成 | 約800ms |
| POSポイント減算 | 約600ms |
| メタフィールド保存 | 約300ms |
| 合計 | 約2.3秒 |
UX対応: 顧客には「処理中...」を表示し、ローディングアニメーションで体感を改善
この設計がもたらす効果
信頼性
- 処理順序の最適化でエラー時の影響を最小化
- ロールバック戦略で不整合を防止
- 全ての処理をログに記録し追跡可能
保守性
- 各ステップが独立しておりテストしやすい
- エラー原因の特定が容易
- 将来の機能追加(ポイント還元率変更など)に対応しやすい