Files
junhong_cmp_fiber/internal/service/order/payment_audit.go
break 5e552d99bc 收口审计治理与套餐任务进展
Constraint: 在线热修前必须保存当前迭代分支全部有效代码进展
Confidence: medium
Scope-risk: broad
Directive: 后续修改需保持审计事件与业务事务边界一致
Tested: git diff --cached --check
Not-tested: 未运行全量测试,提交用于切换分支前保存既有工作
2026-08-05 14:30:54 +08:00

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,
}
}