Files
Chengdong Zhang a7cd392bd4 feat(payments): configurable checkout payments — wallet + Stripe crypto, original-method refunds (add-configurable-payments)
- payment domain: payments/memberships/attempts/receipts/refunds/commands/events, legacy-demo provenance (0024), checkout header-hash idempotency (0025)
- wallet collection all-or-none across shop orders; group-wide cancellation; checkout cutover, status-only payOrder removed
- Stripe crypto-only Checkout adapter, raw-body HMAC webhooks, durable command worker with leases
- original-method refunds with receipt/allocation budgets; refund_pending/refund_failed aftersale states
- admin channel CRUD/revisions/audit/verify + operations list/detail/reconcile; secret-ref allowlist (VMALL_PAYMENT_*), env-fixed demo/sandbox/live
- mall/mobile checkout pay surfaces, admin console pages; shared contract updated
- pre-launch leftovers recorded in docs/TBD-payments.md

cargo test -p vmall-api green twice; four frontend builds green; browser smoke: mall wallet checkout paid, admin channels/operations verified
2026-10-15 16:14:28 +08:00

29 lines
1.1 KiB
TypeScript

/**
* Renders one audit change entry for display.
*
* The API redacts secret material server-side and only ever exposes
* allowlisted secret *references*. This helper keeps values out of the UI even
* if a sensitive field slips through: reference fields (…_ref) stay visible so
* rotations remain traceable, raw credential keys and credential-shaped values
* render as redacted.
*/
export function useRedactedAudit() {
const { t } = useI18n();
function renderValue(value: unknown): string {
if (value === null || value === undefined || value === "") return "—";
if (typeof value === "string") {
return /^(sk|whsec|rk)_[A-Za-z0-9]/.test(value) ? t("admin.payChannelRedacted") : value;
}
return JSON.stringify(value);
}
function changeText(key: string, change: { from: unknown; to: unknown }): string {
const sensitiveKey = /secret|key|token|authorization|webhook/i.test(key) && !key.endsWith("_ref");
if (sensitiveKey) return t("admin.payChannelRedacted");
return `${renderValue(change.from)} → ${renderValue(change.to)}`;
}
return { changeText };
}