This commit is contained in:
30
internal/domain/agentrecharge/online.go
Normal file
30
internal/domain/agentrecharge/online.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// Package agentrecharge 定义代理在线充值的纯业务规则。
|
||||
package agentrecharge
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
)
|
||||
|
||||
// ValidateOnlineCreation 校验代理在线充值的角色、金额和支付方式不变量。
|
||||
func ValidateOnlineCreation(userType int, amount int64, paymentMethod string) error {
|
||||
if userType != constants.UserTypeAgent {
|
||||
return errors.New(errors.CodeForbidden, "仅代理账号可以创建在线扫码充值")
|
||||
}
|
||||
if amount < constants.AgentOnlineRechargeMinAmount || amount > constants.AgentRechargeMaxAmount {
|
||||
return errors.New(errors.CodeInvalidParam, "在线充值金额必须在100元至100万元之间")
|
||||
}
|
||||
switch strings.TrimSpace(paymentMethod) {
|
||||
case constants.RechargeMethodWechat, constants.RechargeMethodAlipay:
|
||||
return nil
|
||||
default:
|
||||
return errors.New(errors.CodeInvalidParam, "在线充值支付方式无效")
|
||||
}
|
||||
}
|
||||
|
||||
// CanCloseAfterPreCreateFailure 判断预下单明确失败后能否关闭充值单。
|
||||
func CanCloseAfterPreCreateFailure(status int) bool {
|
||||
return status == constants.RechargeStatusPending
|
||||
}
|
||||
82
internal/domain/agentrecharge/payment_confirmation.go
Normal file
82
internal/domain/agentrecharge/payment_confirmation.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package agentrecharge
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
)
|
||||
|
||||
// PaymentState 是支付单在确认用例中的领域状态。
|
||||
type PaymentState int
|
||||
|
||||
const (
|
||||
// PaymentStatePending 表示支付单仍待确认。
|
||||
PaymentStatePending PaymentState = iota
|
||||
// PaymentStatePaid 表示支付单已确认收款。
|
||||
PaymentStatePaid
|
||||
// PaymentStateFailed 表示支付单曾被明确关闭。
|
||||
PaymentStateFailed
|
||||
// PaymentStateRefunded 表示支付单已经退款。
|
||||
PaymentStateRefunded
|
||||
)
|
||||
|
||||
// PaymentConfirmationFacts 是支付确认所需的渠道与本地权威事实。
|
||||
type PaymentConfirmationFacts struct {
|
||||
OrderType string
|
||||
ExpectedOrderType string
|
||||
PaymentMethod string
|
||||
RechargePaymentMethod string
|
||||
RechargePaymentChannel string
|
||||
PaymentConfigID uint
|
||||
RechargePaymentConfigID uint
|
||||
ConfirmedConfigID uint
|
||||
MerchantIdentity string
|
||||
ConfirmedMerchantIdentity string
|
||||
PaymentAmount int64
|
||||
RechargeAmount int64
|
||||
ConfirmedAmount int64
|
||||
PaymentOrderID uint
|
||||
RechargeID uint
|
||||
PaymentState PaymentState
|
||||
RechargeStatus int
|
||||
StoredTradeNo string
|
||||
ConfirmedTradeNo string
|
||||
}
|
||||
|
||||
// ValidatePaymentConfirmation 校验支付确认不变量,并返回是否属于完全一致的重复确认。
|
||||
func ValidatePaymentConfirmation(facts PaymentConfirmationFacts) (bool, error) {
|
||||
if facts.ExpectedOrderType == "" || facts.OrderType != facts.ExpectedOrderType ||
|
||||
facts.RechargeID == 0 || facts.PaymentOrderID != facts.RechargeID {
|
||||
return false, errors.New(errors.CodeConflict, "支付单与代理充值单关联不一致")
|
||||
}
|
||||
method := strings.TrimSpace(facts.PaymentMethod)
|
||||
if method == "" || method != strings.TrimSpace(facts.RechargePaymentMethod) ||
|
||||
method != strings.TrimSpace(facts.RechargePaymentChannel) {
|
||||
return false, errors.New(errors.CodeConflict, "支付渠道与代理充值单不一致")
|
||||
}
|
||||
identity := strings.TrimSpace(facts.MerchantIdentity)
|
||||
if facts.PaymentConfigID == 0 || facts.PaymentConfigID != facts.RechargePaymentConfigID ||
|
||||
facts.PaymentConfigID != facts.ConfirmedConfigID || identity == "" ||
|
||||
identity != strings.TrimSpace(facts.ConfirmedMerchantIdentity) {
|
||||
return false, errors.New(errors.CodeConflict, "支付配置身份与创建记录不一致")
|
||||
}
|
||||
tradeNo := strings.TrimSpace(facts.ConfirmedTradeNo)
|
||||
if tradeNo == "" || facts.ConfirmedAmount <= 0 || facts.PaymentAmount != facts.RechargeAmount ||
|
||||
facts.PaymentAmount != facts.ConfirmedAmount {
|
||||
return false, errors.New(errors.CodeConflict, "支付金额或第三方交易号无效")
|
||||
}
|
||||
if facts.PaymentState == PaymentStatePaid {
|
||||
if strings.TrimSpace(facts.StoredTradeNo) == tradeNo &&
|
||||
(facts.RechargeStatus == constants.RechargeStatusPaid || facts.RechargeStatus == constants.RechargeStatusCompleted) {
|
||||
return true, nil
|
||||
}
|
||||
return false, errors.New(errors.CodeConflict, "支付单已存在不一致的确认事实")
|
||||
}
|
||||
validPending := facts.PaymentState == PaymentStatePending && facts.RechargeStatus == constants.RechargeStatusPending
|
||||
validLateSuccess := facts.PaymentState == PaymentStateFailed && facts.RechargeStatus == constants.RechargeStatusClosed
|
||||
if !validPending && !validLateSuccess {
|
||||
return false, errors.New(errors.CodeInvalidStatus, "代理充值单当前状态不可确认支付")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user