Backend:
- Define OrderTypeBalance/Subscription, EntityStatusActive, DeductionType*,
NotificationStatus* constants in payment/types.go
- Replace all magic strings in payment_order, payment_fulfillment, payment_refund
- Add local constants in easypay.go (tradeStatusSuccess, signTypeMD5)
- Add 27 unit tests for load balancer (filterByLimits, pickLeastAmount,
getInstanceChannelLimits, startOfDay)
Frontend:
- Remove all `any` types in SettingsView.vue (18 catch blocks + 1 payload)
- Fix bare catch blocks in PaymentResultView, PaymentView
- Add `unknown` type annotation to all catch blocks
chore: bump version to 0.1.108.140
Backend:
- Extract YuanToFen/FenToYuan to payment/amount.go using shopspring/decimal
- Require alipay publicKey in config validation
- Fix wxpay webhook response to return JSON per V3 spec
- Remove wxpay certSerial fallback to publicKeyId
- Define magic strings as named constants in wxpay/alipay providers
- Add slog warning for wxpay H5→Native payment downgrade
- Make EncryptionKey validation return error on invalid (non-empty) key
- Make decryptConfig propagate errors instead of returning nil
- Add idempotency check in doBalance to prevent stuck FAILED retries
Frontend:
- Fix dashboard currency symbol from $ to ¥
- Fix AdminPaymentPlansView any type to proper SubscriptionPlan type
- Make quick amount buttons follow selected payment method limits
- Center help image with larger height and text below
Upstream removed sora feature (090_drop_sora.sql) but left i18n keys
and wire.go references. Clean up:
- Remove entire sora i18n block from en.ts and zh.ts (~190 lines)
- Remove sora nav key and unused 'data' settings tab key
- Remove sora_client_enabled from settings (fork-specific)
- Remove SoraMediaCleanupService from wire.go
The API client's error interceptor was dropping the reason and metadata
fields from backend error responses. This caused PaymentView to miss
specific error codes (TOO_MANY_PENDING, CANCEL_RATE_LIMITED) and fall
back to generic error messages.
Stripe payment path was setting expiresAt to empty string, causing
PaymentStatusPanel to fall back to hardcoded 30-minute default when
the popup redirect switches to the waiting view.
The built-in payment system replaces the old external purchase subscription
iframe approach. Remove purchase_subscription_enabled/url from admin settings
interface and form defaults, as the Payment tab now handles this functionality.
Kept in stores/app.ts fallback to match backend DTO response structure.
Add a full payment and subscription system supporting EasyPay (Alipay/WeChat),
Stripe, and direct Alipay/WeChat Pay providers with multi-instance load balancing.
- Sync cc_version in x-anthropic-billing-header with the fingerprint
User-Agent version, preserving the message-derived suffix
- Implement xxHash64-based CCH signing to replace the cch=00000
placeholder with a computed hash
- Add admin toggle (enable_cch_signing) under gateway forwarding settings,
disabled by default
The previous Sora removal missed several frontend references, causing
TypeScript build errors for sora_client_enabled and a missing SoraView.vue
import. Clean up all remaining Sora code from types, router, sidebar,
settings, store, and accounts API.
This component is used by SettingsView.vue for backup/data management.
It was mistakenly deleted as "Sora storage management" but contains
non-Sora backup functionality from upstream.