Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展 Confidence: medium Scope-risk: broad Directive: 后续修改需保持审计事件与业务事务边界一致 Tested: git diff --cached --check Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
79 lines
3.9 KiB
Go
79 lines
3.9 KiB
Go
package order
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/break/junhong_cmp_fiber/internal/infrastructure/audit"
|
|
"github.com/break/junhong_cmp_fiber/internal/infrastructure/integrationlog"
|
|
"github.com/break/junhong_cmp_fiber/internal/model"
|
|
"github.com/break/junhong_cmp_fiber/pkg/auditcontext"
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
)
|
|
|
|
// SetPaymentIntegrationLog 注入支付渠道 Integration Log。
|
|
func (s *Service) SetPaymentIntegrationLog(repository *integrationlog.Repository) {
|
|
s.paymentIntegration = repository
|
|
}
|
|
|
|
func (s *Service) startOrderPaymentAttempt(ctx context.Context, order *model.Order, provider, scene string) (*model.IntegrationLog, time.Time, error) {
|
|
if s.paymentIntegration == nil {
|
|
return nil, time.Time{}, errors.New(errors.CodeInvalidStatus, "支付 Integration Log 接缝未配置")
|
|
}
|
|
resourceID := strconv.FormatUint(uint64(order.ID), 10)
|
|
resourceKey, series, correlationID := order.OrderNo, "order-payment:"+resourceID+":"+constants.IntegrationOperationPaymentPreCreate, order.OrderNo
|
|
triggerSource, triggerScene := auditcontext.From(ctx).Source, scene
|
|
log, err := s.paymentIntegration.Start(ctx, integrationlog.Attempt{
|
|
Provider: provider, Direction: constants.IntegrationDirectionOutbound,
|
|
Operation: constants.IntegrationOperationPaymentPreCreate,
|
|
ResourceType: constants.AuditResourceOrder, ResourceID: &resourceID, ResourceKey: &resourceKey,
|
|
ExternalID: &resourceKey, TriggerSource: &triggerSource, TriggerScene: &triggerScene,
|
|
TriggerSeries: &series, CorrelationID: &correlationID,
|
|
RequestSummary: map[string]any{"payment_config_id": order.PaymentConfigID, "amount": order.TotalAmount},
|
|
})
|
|
return log, time.Now(), err
|
|
}
|
|
|
|
func (s *Service) completeOrderPaymentAttempt(ctx context.Context, log *model.IntegrationLog, startedAt time.Time, result, providerCode, safeMessage string) error {
|
|
if log == nil {
|
|
return errors.New(errors.CodeInvalidStatus, "支付 Integration Log 尝试不存在")
|
|
}
|
|
completion := integrationlog.Completion{
|
|
Result: result, ProviderCode: providerCode, SafeProviderMessage: safeMessage,
|
|
ResponseSummary: map[string]any{"success": result == constants.IntegrationResultSuccess},
|
|
DurationMS: time.Since(startedAt).Milliseconds(),
|
|
}
|
|
if result == constants.IntegrationResultUnknown {
|
|
completion.RecoveryStrategy = "使用原业务单号向支付渠道查单,确认结果后再推进本地支付状态"
|
|
}
|
|
_, err := s.paymentIntegration.Complete(ctx, log.IntegrationID, completion)
|
|
return err
|
|
}
|
|
|
|
func (s *Service) appendPaymentConfirmedAudit(ctx context.Context, tx *gorm.DB, payment *model.Payment, order *model.Order, beforePayment, afterPayment, beforeOrder, afterOrder map[string]any) error {
|
|
if s.auditWriter == nil {
|
|
return errors.New(errors.CodeInvalidStatus, "支付统一审计接缝未配置")
|
|
}
|
|
paymentResource := audit.PaymentResource(payment, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePaymentTarget, beforePayment, afterPayment)
|
|
orderResource := audit.OrderResource(order, constants.AuditResourceRelationAffected, constants.AuditResourceRolePaymentBusinessOrder)
|
|
orderResource.BeforeData, orderResource.AfterData = beforeOrder, afterOrder
|
|
orderResource.SubjectVisibility = constants.AuditSubjectResult
|
|
orderResource.SubjectSummary = "订单支付已确认"
|
|
return s.auditWriter.Append(ctx, tx, audit.AppendInput{
|
|
ActionCode: constants.AuditActionPaymentConfirmed, Summary: "第三方支付确认订单已支付",
|
|
ScopeType: constants.AuditScopePlatform, Result: constants.AuditResultSuccess,
|
|
CorrelationID: payment.PaymentNo, Resources: []audit.ResourceInput{paymentResource, orderResource},
|
|
})
|
|
}
|
|
|
|
func paymentStateData(payment *model.Payment) map[string]any {
|
|
return map[string]any{
|
|
"status": payment.Status, "third_party_trade_no": payment.ThirdPartyTradeNo,
|
|
"paid_at": payment.PaidAt,
|
|
}
|
|
}
|