支持官方直连支付、退款配置与套餐联动

This commit is contained in:
zhiqicloud
2026-05-20 00:21:56 +08:00
parent f5deed8709
commit 3a318a86b2
40 changed files with 4674 additions and 365 deletions
@@ -7,15 +7,39 @@ use super::super::shared::{
};
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
use crate::handlers::admin::shared::attach_admin_audit_response;
use crate::handlers::shared::{
payment_gateway_provider_for_payment_method, payment_gateway_refund_enabled,
};
use crate::GatewayError;
use axum::{
body::Body,
response::{IntoResponse, Response},
Json,
};
use serde_json::json;
use serde_json::{json, Value};
use tracing::warn;
fn merge_gateway_refund_proof(
proof: Option<Value>,
gateway_refund: Option<&crate::handlers::shared::DirectGatewayRefundResult>,
) -> Option<Value> {
let Some(gateway_refund) = gateway_refund else {
return proof;
};
let mut object = proof
.and_then(|value| value.as_object().cloned())
.unwrap_or_default();
object.insert(
"gateway_refund".to_string(),
json!({
"id": gateway_refund.gateway_refund_id,
"status": gateway_refund.status,
"payload": gateway_refund.payload,
}),
);
Some(Value::Object(object))
}
pub(in super::super) async fn build_admin_wallet_complete_refund_response(
state: &AdminAppState<'_>,
request_context: &AdminRequestContext<'_>,
@@ -76,13 +100,73 @@ pub(in super::super) async fn build_admin_wallet_complete_refund_response(
}
let owner = resolve_admin_wallet_owner_summary(state, &wallet).await?;
let Some(refund_before_complete) = state
.app()
.find_wallet_refund(&wallet_id, &refund_id)
.await?
else {
return Ok(build_admin_wallet_refund_not_found_response());
};
let mut gateway_refund_id = gateway_refund_id;
let mut payout_proof = payload.payout_proof;
if payload.gateway_refund {
let Some(payment_order_id) = refund_before_complete.payment_order_id.as_deref() else {
return Ok(build_admin_wallets_bad_request_response(
"网关原路退款需要退款申请关联支付订单",
));
};
let order = match state.read_admin_payment_order(payment_order_id).await? {
crate::AdminWalletMutationOutcome::Applied(order) => order,
crate::AdminWalletMutationOutcome::NotFound => {
return Ok(build_admin_wallets_bad_request_response("支付订单不存在"))
}
crate::AdminWalletMutationOutcome::Invalid(detail) => {
return Ok(build_admin_wallets_bad_request_response(detail))
}
crate::AdminWalletMutationOutcome::Unavailable => {
return Ok(build_admin_wallets_data_unavailable_response())
}
};
if let Some(provider) = payment_gateway_provider_for_payment_method(&order.payment_method) {
let refund_enabled = state
.app()
.find_payment_gateway_config(provider)
.await?
.is_some_and(|record| payment_gateway_refund_enabled(&record.channels_json));
if !refund_enabled {
return Ok(build_admin_wallets_bad_request_response(
"该支付方式未启用退款",
));
}
}
match crate::handlers::shared::refund_direct_gateway_order(
state.app(),
&order,
&refund_before_complete.refund_no,
refund_before_complete.amount_usd,
refund_before_complete.reason.as_deref(),
)
.await
{
Ok(Some(result)) => {
gateway_refund_id = Some(result.gateway_refund_id.clone());
payout_proof = merge_gateway_refund_proof(payout_proof, Some(&result));
}
Ok(None) => {
return Ok(build_admin_wallets_bad_request_response(
"该支付方式不支持官方直连退款,请使用线下完成",
))
}
Err(detail) => return Ok(build_admin_wallets_bad_request_response(detail)),
}
}
match state
.admin_complete_wallet_refund(
&wallet_id,
&refund_id,
gateway_refund_id.as_deref(),
payout_reference.as_deref(),
payload.payout_proof,
payout_proof,
)
.await?
{