Skip to content

feat(history): Option B step 1 — separate OpenPay fee from network-fee-equivalent (v3 schema)#25

Merged
cipherwebllc merged 4 commits into
mainfrom
feat/payment-accounting-v3
May 31, 2026
Merged

feat(history): Option B step 1 — separate OpenPay fee from network-fee-equivalent (v3 schema)#25
cipherwebllc merged 4 commits into
mainfrom
feat/payment-accounting-v3

Conversation

@cipherwebllc
Copy link
Copy Markdown
Owner

freee 連携の前提となる会計データ整備 (Step 1/3)。 決済記録で OpenPay 利用手数料 (サービス料) と「ネットワーク手数料相当額」(JPYC sponsorship の gas 立替回収 / USDC paymaster 徴収) が feeAmount に混在していたのを分離し、売上総額 (gross) を新規記録する。

何が変わるか

  • History schema v3: saleAmount(gross)・networkFeeEquivalent(全 gasless 経路横断)・feeBreakdownVersion を追加。feeAmount は利用手数料 (サービス料・0) のみに純化。旧 v2 は MIGRATIONS[2] で null backfill + 内訳不明印 (drop しない)。
  • 記録経路 (useBatchPayment / usePaymentHistory / PaymentForm / CheckoutForm / TipForm): feeReceiver への on-chain transfer は feeAmount + gasReimbursement の合算で挙動不変。会計記録だけ分離。circle は circlePaymasterNetUsdc(検証付き)を使い networkFeeEquivalent=null
  • 表示/集計: HistoryRow は利用手数料 0 を非表示・「ネットワーク手数料相当額」を統一行で表示・売上総額が着金額と異なるとき明示。CSV に 3 列追加 + "raw wei"→"raw"。stats は GMV を売上総額ベースに・網手数料を別集計・内訳不明の旧 log を利用手数料 total から除外。
  • TipForm Circle 経路の取りこぼし修正: useBatchPaymentdisableCircle を追加し決済実行 client にも伝播 (PR fix(tips): force Pimlico erc20 for tips (Circle USDC tips failed at runtime) #24 は表示 hook のみ修正で実行経路は Circle に routing され得た)。

方針 (確定済)

決済手数料は alpha / 将来とも 0%(決済額非連動・収益化は周辺機能の月額/利用権で決済フロー非経由)。JPYC ガスレスの gas は顧客が JPYC で負担する立替・回収(肩代わりではない)。

検証

  • Codex 計画レビュー approve-with-changes → 解決。Codex コードレビュー 2 round → approve
  • tsc 0 · eslint 0 · full suite 2560 passed / 0 failed(新規テスト含む)。

クロスチェーン決済の履歴記録 (Step 3)・TipForm の履歴可視化 (Step 2) は後続。

🤖 Generated with Claude Code

cipherwebllc and others added 3 commits June 1, 2026 03:41
…e-equivalent (v3 schema)

freee 連携の前提となる会計データ整備。feeAmount に OpenPay 利用手数料 (サービス料) と
ネットワーク手数料相当額 (JPYC sponsorship の gas 立替回収 / USDC paymaster 徴収) が混在
していたのを分離し、売上総額 (gross) を新規記録する。

History schema v3 (lib/history.ts):
- saleAmount (gross・GMV の基礎)、networkFeeEquivalent (全 gasless 経路横断の統一項目)、
  feeBreakdownVersion を追加。feeAmount は利用手数料 (サービス料・0) のみに純化。
- MIGRATIONS[2]: 旧 v2 は null backfill + feeBreakdownVersion=0 (内訳不明)。
- networkFeeEquivalentOf() で circle (circlePaymasterNetUsdc) と coalesce、
  hasSeparatedBreakdown() で legacy を判定。

Recording (useBatchPayment / usePaymentHistory / PaymentForm / CheckoutForm):
- feeReceiver への on-chain transfer は feeAmount + gasReimbursement の合算 (挙動不変)。
  sponsorship 収支突合は gasReimbursement で行う。
- saleAmount / networkFeeEquivalent を分離して記録 (circle は networkFeeEquivalent=null)。
- paymentLog / KV route も同フィールドを記録・検証 (LOG_FEE_BREAKDOWN_VERSION)。

Display / 集計:
- HistoryRow: 利用手数料 0 は非表示、ネットワーク手数料相当額を統一行で表示 (circle 検証
  badge 併記)、売上総額が着金額と異なるとき明示。legacy heuristic は networkFeeEquivalent
  ===null に限定。
- CSV: 売上総額 / ネットワーク手数料相当額 / 内訳バージョン 列を末尾追加、"raw wei"→"raw"。
- stats: GMV を売上総額ベースに、網手数料相当額を別集計、内訳不明の旧 log を利用手数料
  total から除外 (unknownBreakdownCount で可視化)。
- fee.ts コメント訂正 (案A=立替・回収、決済手数料は将来も 0)。

Verified: tsc 0 · eslint 0 · full suite 2558 passed/0 failed (新規 7 test 含む)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…review)

Codex code-review found TipForm was not updated to the two-field contract, so
sponsored JPYC tips reconciled as 0-collected gas and the KV log conflated tip
gas into the service fee (inflating totalFeeWei / dropping networkFeeEquivalent).

- TipForm: pass feeAmount (service) + gasReimbursement + saleAmount + networkFeeEquivalent
  separately (on-chain transfer合算は useBatchPayment 側で不変)。
- useBatchPayment: abuse-guard のエラー文を新契約 (利用手数料 + gasReimbursement > 0) に更新。
- history.isValidEntry: feeBreakdownVersion を非負整数に厳格化。

Verified: tsc 0 · eslint 0 · full suite 2558 passed/0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ated logging (Codex review 2)

Codex re-review found PR #24's TipForm Circle fix was incomplete: useBatchPayment
calls its own internal useSmartAccount(deployment, enabled) for the execution client
WITHOUT disableCircle, so a Circle-eligible USDC tip still routed to Circle and threw
on the missing circlePermitAmount (the disableCircle on TipForm's display hook had no
effect on the execution path).

- useBatchPayment: add disableCircle param, pass to internal useSmartAccount.
- TipForm: useBatchPayment(deployment, true, true) so the execution client is also
  pinned to Pimlico erc20. This makes the networkFeeEquivalent = gasAmount assumption
  (always non-circle) hold end-to-end for tips.
- tests: add useBatchPayment coverage for (a) separated saleAmount/networkFeeEquivalent/
  feeBreakdownVersion logging, (b) disableCircle propagation; update the enabled-propagation
  assertion for the new 3rd arg.

Verified: tsc 0 · eslint 0 · full suite 2560 passed/0 failed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 31, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openpay Ready Ready Preview, Comment May 31, 2026 7:41pm

…recording path

Option B (v3 fee/gas separation) の決済記録経路が saleAmount / networkFeeEquivalent /
feeBreakdownVersion を扱うようになり、/pay の必須コード (appendHistory→loadHistory→
migrate/isValidEntry + buildHistoryEntry) が +1kB で 420→421kB。機能上必要なため予算を
423kB へ微増 (2kB headroom)。

⚠️ /pay は慢性的に上限張り付き。専用の slimming pass (lazy import 見直し) を別 task で
要検討 — これ以上の安易な予算引き上げはしない。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cipherwebllc cipherwebllc merged commit 47b6708 into main May 31, 2026
6 checks passed
@cipherwebllc cipherwebllc deleted the feat/payment-accounting-v3 branch May 31, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant