feat: integrate okpay switch-network flow and notify handling

This commit is contained in:
mcmc
2026-05-09 18:06:27 +08:00
parent a4022df7b4
commit 377176a0f2
209 changed files with 1842 additions and 304 deletions
+12
View File
@@ -202,6 +202,18 @@ func MarkOrderSelected(tradeId string) error {
Update("is_selected", true).Error
}
// ExpireOrderByTradeID marks a waiting order as expired. Used to retire failed
// child-order attempts that should not remain selectable/reusable.
func ExpireOrderByTradeID(tradeId string) error {
return dao.Mdb.Model(&mdb.Orders{}).
Where("trade_id = ?", tradeId).
Where("status = ?", mdb.StatusWaitPay).
Updates(map[string]interface{}{
"status": mdb.StatusExpired,
"is_selected": false,
}).Error
}
// RefreshOrderExpiration resets created_at to now so the expiration timer restarts.
// Called on the parent order when a sub-order is created or returned.
func RefreshOrderExpiration(tradeId string) error {
+76
View File
@@ -0,0 +1,76 @@
package data
import (
"github.com/GMWalletApp/epusdt/model/dao"
"github.com/GMWalletApp/epusdt/model/mdb"
"gorm.io/gorm"
)
func GetProviderOrderByTradeIDAndProvider(tradeID string, provider string) (*mdb.ProviderOrder, error) {
row := new(mdb.ProviderOrder)
err := dao.Mdb.Model(row).
Where("trade_id = ?", tradeID).
Where("provider = ?", provider).
Limit(1).
Find(row).Error
return row, err
}
func CreateProviderOrderWithTransaction(tx *gorm.DB, row *mdb.ProviderOrder) error {
return tx.Model(row).Create(row).Error
}
func UpdateProviderOrderCreated(tradeID string, provider string, providerOrderID string, payURL string) error {
return dao.Mdb.Model(&mdb.ProviderOrder{}).
Where("trade_id = ?", tradeID).
Where("provider = ?", provider).
Updates(map[string]interface{}{
"provider_order_id": providerOrderID,
"pay_url": payURL,
"status": mdb.ProviderOrderStatusPending,
}).Error
}
func MarkProviderOrderFailed(tradeID string, provider string) error {
return dao.Mdb.Model(&mdb.ProviderOrder{}).
Where("trade_id = ?", tradeID).
Where("provider = ?", provider).
Update("status", mdb.ProviderOrderStatusFailed).Error
}
func SaveProviderOrderNotify(tradeID string, provider string, notifyRaw string) error {
return dao.Mdb.Model(&mdb.ProviderOrder{}).
Where("trade_id = ?", tradeID).
Where("provider = ?", provider).
Update("notify_raw", notifyRaw).Error
}
func MarkProviderOrderPaid(tradeID string, provider string, notifyRaw string) error {
return dao.Mdb.Model(&mdb.ProviderOrder{}).
Where("trade_id = ?", tradeID).
Where("provider = ?", provider).
Updates(map[string]interface{}{
"status": mdb.ProviderOrderStatusPaid,
"notify_raw": notifyRaw,
}).Error
}
func MarkProviderOrderExpired(tradeID string, provider string) error {
return dao.Mdb.Model(&mdb.ProviderOrder{}).
Where("trade_id = ?", tradeID).
Where("provider = ?", provider).
Where("status IN ?", []string{mdb.ProviderOrderStatusCreating, mdb.ProviderOrderStatusPending}).
Update("status", mdb.ProviderOrderStatusExpired).Error
}
func GetSubOrderByTokenPayProvider(parentTradeID string, token string, payProvider string) (*mdb.Orders, error) {
order := new(mdb.Orders)
err := dao.Mdb.Model(order).
Where("parent_trade_id = ?", parentTradeID).
Where("token = ?", token).
Where("pay_provider = ?", payProvider).
Where("status = ?", mdb.StatusWaitPay).
Limit(1).
Find(order).Error
return order, err
}
+58
View File
@@ -5,6 +5,7 @@ import (
"strings"
"sync"
"github.com/GMWalletApp/epusdt/config"
"github.com/GMWalletApp/epusdt/model/dao"
"github.com/GMWalletApp/epusdt/model/mdb"
"gorm.io/gorm/clause"
@@ -157,6 +158,63 @@ var sensitiveSettingKeys = []string{
mdb.SettingKeyInitAdminPasswordChanged,
}
// OkPay settings helpers keep the provider-specific defaults in one place so
// business logic does not need to repeat raw settings keys.
func GetOkPayEnabled() bool {
return GetSettingBool(mdb.SettingKeyOkPayEnabled, false)
}
func GetOkPayShopID() string {
return strings.TrimSpace(GetSettingString(mdb.SettingKeyOkPayShopID, ""))
}
func GetOkPayShopToken() string {
return strings.TrimSpace(GetSettingString(mdb.SettingKeyOkPayShopToken, ""))
}
func GetOkPayAPIURL() string {
return strings.TrimSpace(GetSettingString(mdb.SettingKeyOkPayAPIURL, "https://api.okaypay.me/shop/"))
}
func GetOkPayCallbackURL() string {
if configured := strings.TrimSpace(GetSettingString(mdb.SettingKeyOkPayCallbackURL, "")); configured != "" {
return configured
}
appURI := strings.TrimSpace(config.GetAppUri())
if appURI == "" {
return ""
}
return strings.TrimRight(appURI, "/") + "/payments/okpay/v1/notify"
}
func GetOkPayReturnURL() string {
return strings.TrimSpace(GetSettingString(mdb.SettingKeyOkPayReturnURL, ""))
}
func GetOkPayTimeoutSeconds() int {
return GetSettingInt(mdb.SettingKeyOkPayTimeoutSeconds, 10)
}
func GetOkPayAllowTokens() []string {
raw := GetSettingString(mdb.SettingKeyOkPayAllowTokens, "USDT,TRX")
if strings.TrimSpace(raw) == "" {
return []string{"USDT", "TRX"}
}
parts := strings.Split(raw, ",")
out := make([]string, 0, len(parts))
for _, part := range parts {
token := strings.ToUpper(strings.TrimSpace(part))
if token == "" {
continue
}
out = append(out, token)
}
if len(out) == 0 {
return []string{"USDT", "TRX"}
}
return out
}
// ListSettingsByGroup returns all rows for a given group (empty group = all),
// excluding any keys in sensitiveSettingKeys.
func ListSettingsByGroup(group string) ([]mdb.Setting, error) {