- 24 Apr, 2026 1 commit
-
-
VpSanta33 authored
-
- 23 Apr, 2026 1 commit
-
-
erio authored
Introduce a sentinel ErrOrderNotFound in the payment service layer so the webhook handler can distinguish "the out_trade_no does not exist in our DB" from other fulfillment failures, and downgrade the former to a WARN log + success response. Background - Providers (Stripe, Alipay, Wxpay, EasyPay, ...) retry webhooks whenever we answer non-2xx. When a webhook endpoint is misconfigured (e.g. a foreign environment points at us) or our orders table has been wiped, we return 500 forever and the provider retries for days, spamming logs. - The old code also collapsed "order not found" and "DB query failed" into the same branch — a DB blip would be reported as "order not found" and swallowed. Service layer (payment_fulfillment.go) - Add `var ErrOrderNotFound = errors.New("payment order not found")`. - In HandlePaymentNotification, distinguish the two error paths: * dbent.IsNotFound(err) → wrap with ErrOrderNotFound so callers can errors.Is(...) it. * anything else → wrap the original err with %w so it still bubbles up as 500 and the provider retries (DB hiccup should be retried). Handler layer (payment_webhook_handler.go) - Before returning 500, check errors.Is(err, service.ErrOrderNotFound): emit a WARN (with provider / outTradeNo / tradeNo for discoverability), then call writeSuccessResponse so the provider sees its expected 2xx body (Stripe empty body / Wxpay JSON / others "success"). - Other errors retain the existing 500 behavior. Monitoring note: because this path now swallows unknown-order webhooks silently from the provider's perspective, the WARN log line is the only signal. Alert on "unknown order, acking to stop retries" if you want visibility into misrouted webhooks or accidental data loss.
-
- 22 Apr, 2026 1 commit
-
-
IanShaw027 authored
-
- 21 Apr, 2026 4 commits
-
-
IanShaw027 authored
-
IanShaw027 authored
-
IanShaw027 authored
-
IanShaw027 authored
-
- 20 Apr, 2026 2 commits
-
-
IanShaw027 authored
-
IanShaw027 authored
-
- 14 Apr, 2026 6 commits
-
-
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
-
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
-
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
-
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
-
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
-
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
-
- 11 Apr, 2026 1 commit
-
-
erio authored
Add a full payment and subscription system supporting EasyPay (Alipay/WeChat), Stripe, and direct Alipay/WeChat Pay providers with multi-instance load balancing.
-