docs(归档): 归档退款方式与原路退款变更并同步主规格

- 将 add-refund-methods-and-original-route-refunds 归档为
  2026-09-14-add-refund-methods-and-original-route-refunds。
- 合并两份 delta 到主规格:
  * order-refund-exchange:改写「订单、退款与换货状态门禁」,新增「退款实收金额与方式矩阵」
    「企业微信唯一终审与审批尝试重提」「原路退款渠道能力与执行」「退款权益与订单状态时点」
    「退款终态事实与失败分类」五项行为要求。
  * merchant-payment-routing:改写「商户与微信授权配置管理」与「新支付商户快照与历史兼容」
    (删除「不得新增渠道退款能力」与「不新增富友退款」,改由退款能力按商户凭证执行;
    微信 v2 客户端证书改为可选凭证键)。
- 同步上下文健康检查证据链与入口矩阵:为新要求登记证据行,并把退款创建、重提、
  企微审批回调、退款详情与 refund:channel:recovery 任务与对应要求双向关联。
This commit is contained in:
2026-09-14 12:00:35 +08:00
parent ba0855d9eb
commit 09abee9778
10 changed files with 377 additions and 14 deletions

View File

@@ -1095,7 +1095,8 @@
"requirements": [
"identity-access::数据范围拒绝",
"order-refund-exchange::订单、退款与换货状态门禁",
"order-refund-exchange::代理退款查询按所属店铺隔离"
"order-refund-exchange::代理退款查询按所属店铺隔离",
"order-refund-exchange::退款终态事实与失败分类"
],
"classification": "behavior"
},
@@ -1106,7 +1107,8 @@
"requirements": [
"identity-access::数据范围拒绝",
"order-refund-exchange::订单、退款与换货状态门禁",
"order-refund-exchange::代理退款查询按所属店铺隔离"
"order-refund-exchange::代理退款查询按所属店铺隔离",
"order-refund-exchange::退款终态事实与失败分类"
],
"classification": "behavior"
},
@@ -2322,7 +2324,8 @@
"capability": "order-refund-exchange",
"requirements": [
"identity-access::数据范围拒绝",
"order-refund-exchange::订单、退款与换货状态门禁"
"order-refund-exchange::订单、退款与换货状态门禁",
"order-refund-exchange::退款实收金额与方式矩阵"
],
"classification": "behavior"
},
@@ -2355,7 +2358,8 @@
"capability": "order-refund-exchange",
"requirements": [
"identity-access::数据范围拒绝",
"order-refund-exchange::订单、退款与换货状态门禁"
"order-refund-exchange::订单、退款与换货状态门禁",
"order-refund-exchange::企业微信唯一终审与审批尝试重提"
],
"classification": "behavior"
},
@@ -2795,7 +2799,9 @@
"capability": "external-integration",
"requirements": [
"external-integration::企微回调与补偿",
"employee-collection-bill::核销申请审批、重提与幂等"
"employee-collection-bill::核销申请审批、重提与幂等",
"order-refund-exchange::企业微信唯一终审与审批尝试重提",
"order-refund-exchange::退款权益与订单状态时点"
],
"classification": "behavior"
},
@@ -3931,7 +3937,9 @@
"capability": "order-refund-exchange",
"requirements": [
"order-refund-exchange::订单、退款与换货状态门禁",
"order-refund-exchange::代理退款查询按所属店铺隔离"
"order-refund-exchange::代理退款查询按所属店铺隔离",
"order-refund-exchange::原路退款渠道能力与执行",
"order-refund-exchange::退款终态事实与失败分类"
],
"classification": "route_index_or_infrastructure"
},

View File

@@ -3163,5 +3163,169 @@
],
"exit_status": 0
}
},
{
"capability": "order-refund-exchange",
"requirement": "退款实收金额与方式矩阵",
"spec": "openspec/specs/order-refund-exchange/spec.md",
"entries": [
"/api/admin/refunds"
],
"handler_consumer_job": [
"internal/routes/refund.go",
"internal/handler/admin/refund.go"
],
"application_service_query": [
"internal/service/refund/method.go"
],
"domain_state_amount": [
"internal/model/refund.go",
"internal/model/payment.go",
"pkg/constants/refund.go"
],
"store_migration_config": [
"migrations/000218_add_refund_attempt_and_channel_refund.up.sql"
],
"verification": {
"command": "grep -n 'func (s \\*Service) decideRefundMethods' internal/service/refund/method.go",
"literal_output": [
"internal/service/refund/method.go:40:func (s *Service) decideRefundMethods(ctx context.Context, order *model.Order) (*refundMethodDecision, error) {"
],
"exit_status": 0
}
},
{
"capability": "order-refund-exchange",
"requirement": "企业微信唯一终审与审批尝试重提",
"spec": "openspec/specs/order-refund-exchange/spec.md",
"entries": [
"/api/admin/refunds/{id}/resubmit",
"/api/callback/wecom/approval/{application_id}"
],
"handler_consumer_job": [
"internal/routes/refund.go",
"internal/handler/admin/refund.go",
"internal/application/refundapproval/creation.go",
"cmd/worker/main.go"
],
"application_service_query": [
"internal/application/refundapproval/resolve.go",
"internal/service/refund/service.go"
],
"domain_state_amount": [
"pkg/constants/approval.go",
"internal/model/refund.go"
],
"store_migration_config": [
"migrations/000218_add_refund_attempt_and_channel_refund.up.sql"
],
"verification": {
"command": "grep -n 'BusinessID: attempt.ID' internal/application/refundapproval/creation.go",
"literal_output": [
"internal/application/refundapproval/creation.go:141:BusinessID: attempt.ID, SubmitterAccountID: current.Creator,",
"internal/application/refundapproval/creation.go:358:BusinessID: attempt.ID, SubmitterAccountID: current.Creator,"
],
"exit_status": 0
}
},
{
"capability": "order-refund-exchange",
"requirement": "原路退款渠道能力与执行",
"spec": "openspec/specs/order-refund-exchange/spec.md",
"entries": [
"constants.TaskTypeRefundChannelRecovery"
],
"handler_consumer_job": [
"internal/infrastructure/payment/refund_channel_recovery_task.go",
"internal/infrastructure/payment/refund_adapter.go",
"internal/application/refundchannel/event.go",
"cmd/worker/main.go"
],
"application_service_query": [
"internal/application/refundchannel/service.go",
"internal/service/refund/payment_merchant.go"
],
"domain_state_amount": [
"pkg/constants/refund.go",
"pkg/wechat/payment_v2_refund.go",
"pkg/fuiou/refund.go",
"pkg/alipay/refund.go"
],
"store_migration_config": [
"migrations/000218_add_refund_attempt_and_channel_refund.up.sql",
"migrations/000219_add_wechat_v2_client_cert_credentials.up.sql"
],
"verification": {
"command": "grep -n 'func RefundCredentialIssue' internal/application/refundchannel/service.go",
"literal_output": [
"internal/application/refundchannel/service.go:452:func RefundCredentialIssue(providerType string, config *model.WechatConfig) string {"
],
"exit_status": 0
}
},
{
"capability": "order-refund-exchange",
"requirement": "退款权益与订单状态时点",
"spec": "openspec/specs/order-refund-exchange/spec.md",
"entries": [
"/api/callback/wecom/approval/{application_id}",
"/api/admin/refunds/{id}/approve"
],
"handler_consumer_job": [
"internal/service/refund/approval_decision.go",
"internal/application/refundchannel/service.go",
"cmd/worker/main.go"
],
"application_service_query": [
"internal/service/refund/service.go",
"internal/service/package/activation_service.go"
],
"domain_state_amount": [
"internal/model/order.go",
"internal/model/refund.go"
],
"store_migration_config": [
"migrations/000218_add_refund_attempt_and_channel_refund.up.sql"
],
"verification": {
"command": "grep -n 'originalRoute := refund.Method' internal/service/refund/approval_decision.go",
"literal_output": [
"internal/service/refund/approval_decision.go:120:originalRoute := refund.Method == constants.RefundMethodOriginalRoute"
],
"exit_status": 0
}
},
{
"capability": "order-refund-exchange",
"requirement": "退款终态事实与失败分类",
"spec": "openspec/specs/order-refund-exchange/spec.md",
"entries": [
"/api/admin/refunds/{id}",
"constants.TaskTypeRefundChannelRecovery"
],
"handler_consumer_job": [
"internal/routes/refund.go",
"internal/handler/admin/refund.go",
"internal/infrastructure/audit/refund_channel.go"
],
"application_service_query": [
"internal/service/refund/attempt_query.go",
"internal/exporter/refund_scene.go"
],
"domain_state_amount": [
"pkg/constants/refund.go",
"internal/model/refund.go",
"internal/infrastructure/commissiondelivery/event.go"
],
"store_migration_config": [
"migrations/000218_add_refund_attempt_and_channel_refund.up.sql"
],
"verification": {
"command": "grep -n 'func RefundFailureReasonIsDefinitive' pkg/constants/refund.go",
"literal_output": [
"pkg/constants/refund.go:99:func RefundFailureReasonIsDefinitive(reason string) bool {"
],
"exit_status": 0
}
}
]