package app 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/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" ) func (h *ClientWalletHandler) appendRechargePaymentCreatedAudit(ctx context.Context, tx *gorm.DB, payment *model.Payment, recharge *model.RechargeOrder) error { if h.auditWriter == nil { return errors.New(errors.CodeInvalidStatus, "充值支付统一审计接缝未配置") } rechargeID := strconv.FormatUint(uint64(recharge.ID), 10) resources := []audit.ResourceInput{ audit.PaymentResource(payment, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePaymentTarget, nil, map[string]any{"status": payment.Status}), { Type: constants.AuditResourceRechargeOrder, ID: &rechargeID, Key: recharge.RechargeOrderNo, DisplayName: recharge.RechargeOrderNo, Relation: constants.AuditResourceRelationReference, Role: constants.AuditResourceRolePaymentBusinessOrder, IdentitySnapshot: map[string]any{ "id": recharge.ID, "recharge_order_no": recharge.RechargeOrderNo, "user_id": recharge.UserID, "asset_wallet_id": recharge.AssetWalletID, "resource_type": recharge.ResourceType, "resource_id": recharge.ResourceID, "amount": recharge.Amount, "status": recharge.Status, }, SubjectVisibility: constants.AuditSubjectResult, SubjectSummary: "资产充值支付已创建", }, } references, err := audit.AssetRechargeReferences(ctx, tx, recharge) if err != nil { return err } resources = append(resources, references...) return h.auditWriter.Append(ctx, tx, audit.AppendInput{ ActionCode: constants.AuditActionPaymentCreated, Summary: "创建资产充值支付记录", ScopeType: constants.AuditScopePlatform, Result: constants.AuditResultSuccess, CorrelationID: payment.PaymentNo, Resources: resources, }) } func (h *ClientWalletHandler) startRechargePaymentAttempt(ctx context.Context, config *model.WechatConfig, paymentNo, rechargeNo string, amount int64) (*model.IntegrationLog, time.Time, error) { if h.paymentIntegration == nil { return nil, time.Time{}, errors.New(errors.CodeInvalidStatus, "充值支付 Integration Log 接缝未配置") } provider := constants.IntegrationProviderWechatPay if config.ProviderType == model.ProviderTypeFuiou { provider = constants.IntegrationProviderFuiou } series := "payment:" + paymentNo + ":" + constants.IntegrationOperationPaymentPreCreate log, err := h.paymentIntegration.Start(ctx, integrationlog.Attempt{ Provider: provider, Direction: constants.IntegrationDirectionOutbound, Operation: constants.IntegrationOperationPaymentPreCreate, ResourceType: constants.IntegrationResourceTypePayment, ResourceKey: &paymentNo, ExternalID: &paymentNo, TriggerSeries: &series, CorrelationID: &rechargeNo, RequestSummary: map[string]any{"payment_config_id": config.ID, "amount": amount}, }) return log, time.Now(), err } func (h *ClientWalletHandler) completeRechargePaymentAttempt(ctx context.Context, log *model.IntegrationLog, startedAt time.Time, result, providerCode, safeMessage string) error { 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 := h.paymentIntegration.Complete(ctx, log.IntegrationID, completion) return err } func (h *ClientWalletHandler) markRechargePaymentFailed(ctx context.Context, payment *model.Payment) error { return h.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { result := tx.Model(&model.Payment{}).Where("id = ? AND status = ?", payment.ID, model.PaymentRecordStatusPending). Update("status", model.PaymentRecordStatusFailed) if result.Error != nil { return errors.Wrap(errors.CodeDatabaseError, result.Error, "关闭失败支付记录失败") } if result.RowsAffected == 0 { return nil } after := *payment after.Status = model.PaymentRecordStatusFailed return h.auditWriter.Append(ctx, tx, audit.AppendInput{ ActionCode: constants.AuditActionPaymentFailed, Summary: "支付宝支付链接生成失败,关闭支付记录", ScopeType: constants.AuditScopePlatform, Result: constants.AuditResultSuccess, CorrelationID: payment.PaymentNo, Resources: []audit.ResourceInput{audit.PaymentResource(&after, constants.AuditResourceRelationPrimary, constants.AuditResourceRolePaymentTarget, map[string]any{"status": payment.Status}, map[string]any{"status": after.Status})}, }) }) }