1. 23 Apr, 2026 1 commit
    • erio's avatar
      sync: bring over remaining release/custom-0.1.115 changes · 748a84d8
      erio authored
      - Extract PublicSettingsInjectionPayload named struct with drift test
      - Add channel_monitor_default_interval_seconds to SSR injection
      - Add image_output_price to SupportedModelChip
      - Simplify AppSidebar buildSelfNavItems (admins see available channels)
      - Add gateway WARN logs for 503 no-available-accounts branches
      - Wire ChannelMonitorRunner into provideCleanup for graceful shutdown
      - Add migrations 130/131 (CC template userid fix + mimicry field cleanup)
      - Clean up fork-only features (sora, claude max simulation, client affinity)
      - Remove ~320 obsolete i18n keys
      - Add codexUsage utility, WechatServiceButton, BulkEditAccountModal
      - Tidy go.sum
      748a84d8
  2. 22 Apr, 2026 1 commit
  3. 20 Apr, 2026 3 commits
    • IanShaw027's avatar
      fix payment resume result consistency · a27a7add
      IanShaw027 authored
      a27a7add
    • erio's avatar
      feat(payment): i18n payment error codes and label localization · 40d4e167
      erio authored
      Pairs with the backend structured payment errors (reason + metadata). The
      frontend now maps reason codes to localized messages with metadata as
      interpolation variables, and automatically localizes raw config-field names
      (e.g. "certSerial" → "证书序列号") using the existing UI-label i18n
      namespace.
      
      - frontend/src/utils/apiError.ts
        - extractApiErrorCode now prefers the string `reason` over the numeric HTTP
          `code`; reason is granular enough to drive i18n lookup, HTTP code is not.
        - New extractApiErrorMetadata to pull interpolation params off the error.
        - New extractI18nErrorMessage(err, t, namespace, fallback): looks up
          `<namespace>.<REASON>` in i18n and substitutes metadata. Before
          substitution, `metadata.key` and `metadata.keys` (slash-joined) are
          re-translated through `admin.settings.payment.field_<key>` so users see
          "缺少必填项:证书序列号" instead of "缺少必填项:certSerial".
      
      - frontend/src/i18n/locales/{zh,en}.ts
        - Add payment.errors entries for every structured reason code returned by
          the backend (PAYMENT_DISABLED, INVALID_AMOUNT, TOO_MANY_PENDING,
          DAILY_LIMIT_EXCEEDED, NO_AVAILABLE_INSTANCE, PAYMENT_PROVIDER_MISCONFIGURED,
          WXPAY_CONFIG_MISSING_KEY / INVALID_KEY_LENGTH / INVALID_KEY, NOT_FOUND,
          FORBIDDEN, CONFLICT, INVALID_ORDER_TYPE, INVALID_STATUS,
          BALANCE_NOT_ENOUGH, REFUND_AMOUNT_EXCEEDED, REFUND_FAILED, and more),
          with placeholders for template variables.
      
      - 13 payment-related Vue files
        - Migrate catch-block error reporting from extractApiErrorMessage to
          extractI18nErrorMessage(err, t, 'payment.errors', fallback).
        - Remove the ad-hoc paymentErrorMap computed in SettingsView.vue, which the
          new helper supersedes (it reads i18n directly via t).
      
      - frontend/src/components/payment/providerConfig.ts
        - wxpay: publicKey and publicKeyId are now required (was optional), matching
          the pubkey-only verifier direction; certSerial is already required.
      
      This PR is drop-in safe: reason-preferring extractApiErrorCode is backward
      compatible with callers that pass their own i18nMap, and error codes missing
      from i18n fall back to the existing message-based path.
      40d4e167
    • IanShaw027's avatar
      feat: rebuild auth identity foundation flow · e9de839d
      IanShaw027 authored
      e9de839d
  4. 18 Apr, 2026 1 commit
    • erio's avatar
      fix(payment): alipay redirect-only flow, H5 detection and popup sizing · c3cb0280
      erio authored
      The native Alipay provider previously tried to embed the payment page
      URL into a QR code on the client — the URL is not a scannable payload
      so the QR never worked. Merchants also hit a H5 detection mismatch
      whenever the backend UA sniffer missed iPadOS 13+ or embedded browsers,
      and the popup window was too small for Alipay's standard checkout
      layout (QR + account-login panel on the right), forcing the user to
      scroll horizontally and vertically.
      
      Changes:
      
      Backend
      - alipay.go: drop QR-on-URL path. Use redirect-only flow —
        alipay.trade.page.pay for PC (returns a gateway URL the browser
        opens in a new window) and alipay.trade.wap.pay for H5 (returns a
        URL the browser jumps to). Both flows produce pages on
        openapi.alipaydev.com / excashier.alipay.com; the client never
        renders a QR itself.
      - payment_handler.go: add optional is_mobile bool to
        CreateOrderRequest so the frontend can declare the device
        explicitly. Server still falls back to UA sniffing when absent.
      
      Frontend
      - types/payment.ts, PaymentView.vue: declare is_mobile in
        CreateOrderRequest and pass the computed isMobileDevice() value.
      - providerConfig.ts: replace the two fixed POPUP_WINDOW_FEATURES
        constants with getPaymentPopupFeatures(), which prefers 1250×900
        (Alipay's checkout footprint), clamps to window.screen.avail* and
        centers the popup so it never overflows on smaller laptops.
      - PaymentQRDialog.vue, PaymentStatusPanel.vue, StripePaymentInline.vue,
        PaymentView.vue: use the new helper at all popup call sites.
      c3cb0280
  5. 14 Apr, 2026 1 commit
    • erio's avatar
      feat(payment): balance recharge multiplier and refund amount separation · 60a4b931
      erio authored
      - Add balance_recharge_multiplier system setting (e.g. 1.2 = charge 100 get 120)
      - Separate order_amount (credited balance) from pay_amount (actual payment)
      - Refund calculates gateway amount proportionally from pay_amount
      - Frontend shows both amounts in order details, payment status, refund dialog
      - Admin settings UI for configuring recharge multiplier
      60a4b931
  6. 13 Apr, 2026 1 commit
  7. 11 Apr, 2026 1 commit