134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
package payment
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
|
|
"gorm.io/gorm"
|
|
"hfb_sys/backend/internal/model"
|
|
"hfb_sys/backend/internal/modules/order"
|
|
"hfb_sys/backend/internal/modules/paymentconfig"
|
|
)
|
|
|
|
type Repository struct {
|
|
db *gorm.DB
|
|
configRepo *paymentconfig.Repository
|
|
orderRepo *order.Repository
|
|
}
|
|
|
|
type runtimePaymentConfig struct {
|
|
ID uint64
|
|
Provider string
|
|
MerchantID string
|
|
PayWay string
|
|
JSPayFlag string
|
|
NotifyURL string
|
|
JumpURL string
|
|
Channel channelClient
|
|
}
|
|
|
|
const (
|
|
channelSourceCreate = "create"
|
|
channelSourceQuery = "query"
|
|
channelSourceNotify = "notify"
|
|
channelSourceMock = "mock"
|
|
)
|
|
|
|
var refundBizTypes = []string{
|
|
"cancel_refund",
|
|
"admin_close_refund",
|
|
"admin_refund",
|
|
"checkout_refund",
|
|
"deposit_refund",
|
|
"rent_refund",
|
|
"arbitration_refund",
|
|
}
|
|
|
|
func RefundBizTypes() []string {
|
|
out := make([]string, len(refundBizTypes))
|
|
copy(out, refundBizTypes)
|
|
return out
|
|
}
|
|
|
|
func NewRepository(db *gorm.DB, configRepo *paymentconfig.Repository, orderRepo *order.Repository) *Repository {
|
|
return &Repository{
|
|
db: db,
|
|
configRepo: configRepo,
|
|
orderRepo: orderRepo,
|
|
}
|
|
}
|
|
func (c runtimePaymentConfig) isMockMode() bool {
|
|
return c.Provider == "mock"
|
|
}
|
|
func (r *Repository) defaultRuntimeConfig(ctx context.Context) (*runtimePaymentConfig, error) {
|
|
if r.configRepo == nil {
|
|
return nil, ErrPaymentUnavailable
|
|
}
|
|
dto, err := r.configRepo.FindDefaultAny(ctx, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return runtimeConfigFromDTO(dto), nil
|
|
}
|
|
func (r *Repository) runtimeConfigForPayment(ctx context.Context, payment *model.PaymentOrder) (*runtimePaymentConfig, error) {
|
|
provider := firstNonEmpty(payment.Provider, "mock")
|
|
merchantID := payment.MerchantID
|
|
if r.configRepo != nil && merchantID != "" {
|
|
dto, err := r.configRepo.FindByProviderMerchant(ctx, provider, merchantID, true)
|
|
if err == nil {
|
|
return runtimeConfigFromDTO(dto), nil
|
|
}
|
|
if err != paymentconfig.ErrConfigNotFound {
|
|
return nil, err
|
|
}
|
|
}
|
|
if provider != "leshua" {
|
|
if provider == "lakala" && r.configRepo != nil {
|
|
dto, err := r.configRepo.FindDefaultByProvider(ctx, provider, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return runtimeConfigFromDTO(dto), nil
|
|
}
|
|
return &runtimePaymentConfig{
|
|
Provider: provider,
|
|
MerchantID: merchantID,
|
|
}, nil
|
|
}
|
|
if r.configRepo == nil {
|
|
return nil, ErrPaymentUnavailable
|
|
}
|
|
dto, err := r.configRepo.FindDefaultByProvider(ctx, provider, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return runtimeConfigFromDTO(dto), nil
|
|
}
|
|
func runtimeConfigFromDTO(dto *paymentconfig.ConfigDTO) *runtimePaymentConfig {
|
|
provider := firstNonEmpty(dto.Provider, "mock")
|
|
payWay := firstNonEmpty(dto.PayWay, "ZFBZF")
|
|
jsPayFlag := firstNonEmpty(dto.JSPayFlag, "2")
|
|
client, err := buildChannelClient(dto)
|
|
if err != nil {
|
|
client = nil
|
|
}
|
|
return &runtimePaymentConfig{
|
|
ID: dto.ID,
|
|
Provider: provider,
|
|
MerchantID: dto.MerchantID,
|
|
PayWay: payWay,
|
|
JSPayFlag: jsPayFlag,
|
|
NotifyURL: dto.NotifyURL,
|
|
JumpURL: dto.JumpURL,
|
|
Channel: client,
|
|
}
|
|
}
|
|
func (r *Repository) recordConfigUsage(ctx context.Context, runtimeConfig *runtimePaymentConfig, payment *model.PaymentOrder) {
|
|
if r.configRepo == nil || runtimeConfig == nil || payment == nil || runtimeConfig.ID == 0 {
|
|
return
|
|
}
|
|
if err := r.configRepo.RecordUsage(ctx, runtimeConfig.ID, payment.ID, runtimeConfig.Provider, runtimeConfig.MerchantID, payment.AmountCent, payment.BizType); err != nil {
|
|
log.Printf("[payment] record config usage failed config_id=%d payment_id=%d err=%v", runtimeConfig.ID, payment.ID, err)
|
|
}
|
|
}
|