mirror of
https://github.com/GMWalletApp/epusdt.git
synced 2026-07-07 18:26:16 +00:00
feat: integrate okpay switch-network flow and notify handling
This commit is contained in:
@@ -12,6 +12,19 @@ const (
|
||||
PaymentTypeEpay = "Epay"
|
||||
)
|
||||
|
||||
const (
|
||||
// PaymentProviderOnChain means this concrete order record is settled by
|
||||
// sending funds to a directly assigned wallet address on a supported chain.
|
||||
PaymentProviderOnChain = "on_chain"
|
||||
// PaymentProviderOkPay means this concrete order record is settled through
|
||||
// the third-party OkayPay/OkPay hosted checkout flow.
|
||||
//
|
||||
// In the current design this is typically used by a switch-network-created
|
||||
// child order, while the parent order keeps its original merchant-facing
|
||||
// semantics and callback behavior.
|
||||
PaymentProviderOkPay = "okpay"
|
||||
)
|
||||
|
||||
type Orders struct {
|
||||
TradeId string `gorm:"column:trade_id;uniqueIndex:orders_trade_id_uindex" json:"trade_id" example:"T2026041612345678"`
|
||||
OrderId string `gorm:"column:order_id;uniqueIndex:orders_order_id_uindex" json:"order_id" example:"ORD20260416001"`
|
||||
@@ -33,7 +46,17 @@ type Orders struct {
|
||||
CallBackConfirm int `gorm:"column:callback_confirm;default:2" json:"callback_confirm" enums:"1,2" example:"2"`
|
||||
IsSelected bool `gorm:"column:is_selected;default:false" json:"is_selected" example:"false"`
|
||||
PaymentType string `gorm:"column:payment_type" json:"payment_type" example:"Epay"`
|
||||
ApiKeyID uint64 `gorm:"column:api_key_id;default:0;index:orders_api_key_id_index" json:"api_key_id" example:"1"`
|
||||
// PayProvider identifies how this specific order row is collected.
|
||||
//
|
||||
// Semantics:
|
||||
// - parent orders and regular chain child orders use on_chain
|
||||
// - third-party hosted checkout child orders use their provider name
|
||||
// (for example okpay)
|
||||
//
|
||||
// Existing rows default to on_chain for backward compatibility so upgrades
|
||||
// can rely on AutoMigrate without rewriting old orders.
|
||||
PayProvider string `gorm:"column:pay_provider;size:32;default:on_chain;index:orders_pay_provider_index" json:"pay_provider" example:"on_chain"`
|
||||
ApiKeyID uint64 `gorm:"column:api_key_id;default:0;index:orders_api_key_id_index" json:"api_key_id" example:"1"`
|
||||
// PayBySubId holds the primary-key ID of the sub-order that settled this parent order.
|
||||
// Zero when the parent order was paid directly (no sub-order involved).
|
||||
PayBySubId uint64 `gorm:"column:pay_by_sub_id;default:0" json:"pay_by_sub_id" example:"0"`
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package mdb
|
||||
|
||||
const (
|
||||
ProviderOrderStatusCreating = "creating"
|
||||
ProviderOrderStatusPending = "pending"
|
||||
ProviderOrderStatusPaid = "paid"
|
||||
ProviderOrderStatusFailed = "failed"
|
||||
ProviderOrderStatusExpired = "expired"
|
||||
)
|
||||
|
||||
// ProviderOrder stores provider-specific checkout data for one internal order
|
||||
// row. For OkPay this is expected to bind to the concrete child order created
|
||||
// by switch-network, not to the parent merchant order.
|
||||
//
|
||||
// Binding rules:
|
||||
// - trade_id always points to orders.trade_id
|
||||
// - the bound orders row should use the same pay_provider value
|
||||
// - provider identifies which downstream checkout created the provider row
|
||||
// - provider_order_id is the provider's own order number (for OkPay this is
|
||||
// the returned order_id from /payLink)
|
||||
// - pay_url is the hosted payment URL returned by the provider
|
||||
//
|
||||
// The main orders table remains the source of truth for merchant-facing state,
|
||||
// while this table keeps provider-specific identifiers and callback payloads.
|
||||
type ProviderOrder struct {
|
||||
TradeId string `gorm:"column:trade_id;size:32;not null;uniqueIndex:provider_orders_trade_id_provider_uindex,priority:1;index:provider_orders_trade_id_index" json:"trade_id" example:"T2026041612345678"`
|
||||
// Provider values should match the bound Orders.PayProvider value.
|
||||
Provider string `gorm:"column:provider;size:32;not null;uniqueIndex:provider_orders_trade_id_provider_uindex,priority:2;index:provider_orders_provider_status_index,priority:1" json:"provider" example:"okpay"`
|
||||
// ProviderOrderID is the downstream provider's own order identifier for the
|
||||
// bound concrete order row.
|
||||
ProviderOrderID string `gorm:"column:provider_order_id;size:128;not null;default:'';index:provider_orders_provider_order_id_index" json:"provider_order_id" example:"ac7b86615fdb137576ae35879f7ed844"`
|
||||
// PayURL is the hosted checkout URL returned by the downstream provider for
|
||||
// the bound concrete order row.
|
||||
PayURL string `gorm:"column:pay_url;size:512;not null;default:''" json:"pay_url" example:"https://pay.example.com/checkout/abc123"`
|
||||
// Amount/Coin mirror the exact payload submitted to the provider, which may
|
||||
// be useful when validating callbacks and troubleshooting mismatches.
|
||||
Amount float64 `gorm:"column:amount" json:"amount" example:"14.2857"`
|
||||
Coin string `gorm:"column:coin;size:16;not null;default:''" json:"coin" example:"USDT"`
|
||||
Status string `gorm:"column:status;size:32;not null;default:pending;index:provider_orders_provider_status_index,priority:2" json:"status" example:"pending"`
|
||||
// NotifyRaw stores the original provider callback payload for auditing and
|
||||
// replay/debug use. It is provider-specific and intentionally opaque here.
|
||||
NotifyRaw string `gorm:"column:notify_raw;type:text" json:"notify_raw"`
|
||||
BaseModel
|
||||
}
|
||||
|
||||
func (p *ProviderOrder) TableName() string {
|
||||
return "provider_orders"
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package mdb
|
||||
|
||||
// Setting stores non-credential runtime configuration as key/value pairs.
|
||||
// Groups: brand, rate, system, epay. Merchant credentials (pid + secret_key)
|
||||
// live in the api_keys table; notification configs live in NotificationChannel.
|
||||
// Default rows for the epay group are seeded on first startup (see
|
||||
// Groups: brand, rate, system, epay, okpay. Merchant credentials (pid +
|
||||
// secret_key) live in the api_keys table; notification configs live in
|
||||
// NotificationChannel.
|
||||
// Default rows for the epay/okpay groups are seeded on first startup (see
|
||||
// model/dao/mdb_table_init.go seedDefaultSettings). All other groups start
|
||||
// empty and fall back to hardcoded defaults until an admin sets them.
|
||||
// Only exception: system.jwt_secret is auto-generated on first startup.
|
||||
@@ -12,6 +13,7 @@ const (
|
||||
SettingGroupRate = "rate"
|
||||
SettingGroupSystem = "system"
|
||||
SettingGroupEpay = "epay"
|
||||
SettingGroupOkPay = "okpay"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -42,10 +44,20 @@ const (
|
||||
SettingKeyEpayDefaultToken = "epay.default_token"
|
||||
SettingKeyEpayDefaultCurrency = "epay.default_currency"
|
||||
SettingKeyEpayDefaultNetwork = "epay.default_network"
|
||||
|
||||
// OkPay hosted-checkout settings.
|
||||
SettingKeyOkPayEnabled = "okpay.enabled"
|
||||
SettingKeyOkPayShopID = "okpay.shop_id"
|
||||
SettingKeyOkPayShopToken = "okpay.shop_token"
|
||||
SettingKeyOkPayAPIURL = "okpay.api_url"
|
||||
SettingKeyOkPayCallbackURL = "okpay.callback_url"
|
||||
SettingKeyOkPayReturnURL = "okpay.return_url"
|
||||
SettingKeyOkPayTimeoutSeconds = "okpay.timeout_seconds"
|
||||
SettingKeyOkPayAllowTokens = "okpay.allow_tokens"
|
||||
)
|
||||
|
||||
type Setting struct {
|
||||
Group string `gorm:"column:group;size:32;index:settings_group_index" json:"group" enums:"brand,rate,system" example:"rate"`
|
||||
Group string `gorm:"column:group;size:32;index:settings_group_index" json:"group" enums:"brand,rate,system,epay,okpay" example:"rate"`
|
||||
Key string `gorm:"column:key;uniqueIndex:settings_key_uindex;size:128" json:"key" example:"rate.forced_usdt_rate"`
|
||||
Value string `gorm:"column:value;type:text" json:"value" example:"7.2"`
|
||||
Type string `gorm:"column:type;size:16;default:string" json:"type" enums:"string,int,bool,json" example:"string"`
|
||||
|
||||
Reference in New Issue
Block a user