1. 21 Apr, 2026 1 commit
  2. 20 Apr, 2026 2 commits
  3. 14 Apr, 2026 6 commits
    • 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
    • erio's avatar
      fix: resolve cherry-pick conflicts and restore compilation · d6965b06
      erio authored
      - Restore gateway_cache.go to upstream (no lua embeds)
      - Restore payment_order.go to upstream (use out_trade_no lookup)
      - Restore payment_fulfillment.go to upstream (same reason)
      - Add FeaturesConfig field and IsWebSearchEmulationEnabled to Channel
      - Add applyAccountStatsCost wrapper function
      - Add SettingKeyWebSearchEmulationConfig constant
      - Add WebSearchEmulationEnabled to SystemSettings
      - Add notify code rate limiting methods to EmailCache interface
      - Remove AllowUserRefund references (ent schema not present)
      - Fix duplicate import in payment_handler.go
      - Fix wire_gen.go argument mismatches
      d6965b06
    • erio's avatar
      fix(payment): critical audit fixes for security, idempotency and correctness · c738cfec
      erio authored
      Backend fixes:
      - #1: doSub subscription idempotency via audit log check
      - #2: markFailed only when status=RECHARGING (prevents overwriting COMPLETED)
      - #3: ExpireTimedOutOrders checks upstream payment before expiring
      - #4: Public verify endpoint for payment result page (no auth required)
      - #5: EasyPay QueryOrder returns amount, confirmPayment handles zero amount
      - #6: WxPay notifyUrl priority: request-first, config-fallback
      - #7: EasyPay remove double URL decode in VerifyNotification
      - #8: checkPaid/cancelUpstreamPayment use order's provider instance
      - #9: Amount NaN/Inf/negative validation in order creation and refund
      - #10: Refund amount comparison uses tolerance instead of float64 ==
      - #11: Skip balance deduction on retry when previous rollback failed
      - #12: checkPaid logs fulfillment errors instead of silently ignoring
      - #13: WxPay certSerial added to required config fields
      
      Frontend fixes:
      - Payment result page no longer requires authentication
      - Public verify API fallback for expired sessions
      c738cfec
    • erio's avatar
      fix: audit fixes - magic strings to constants, frontend any/catch, LB tests · 56e4a9a9
      erio authored
      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
      56e4a9a9
    • erio's avatar
      test(payment): add unit tests for payment audit fixes + allow empty supported_types · 3c884f8e
      erio authored
      Tests (1033 new lines, 100% coverage on modified functions):
      - amount.go: YuanToFen/FenToYuan with precision edge cases
      - wxpay: mapWxState, wxSV, formatPEM, NewWxpay validation
      - alipay: isTradeNotExist, NewAlipay validation
      - webhook: writeSuccessResponse (wxpay JSON, stripe empty, others text)
      - config: validateProviderRequest, isSensitiveConfigField, joinTypes
      - fulfillment: resolveRedeemAction idempotency logic
      
      Business logic changes:
      - Allow empty supported_types on provider instances
      - Block removing payment types when instance has pending orders
      - Extract resolveRedeemAction as testable pure function
      3c884f8e
    • erio's avatar
      fix(payment): audit fixes for alipay/wxpay/stripe payment providers · 5bae3b05
      erio authored
      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
      5bae3b05
  4. 11 Apr, 2026 1 commit