feat: add payment gateway and billing plans

This commit is contained in:
Entropy.Xu
2026-05-13 01:18:38 +08:00
parent 0fa97595bf
commit 10285c5eb9
97 changed files with 14797 additions and 404 deletions
@@ -1,6 +1,6 @@
use super::super::shared::{
admin_wallet_id_from_detail_path, build_admin_wallet_not_found_response,
build_admin_wallet_summary_payload, build_admin_wallets_bad_request_response,
build_admin_wallet_summary_payload_with_package, build_admin_wallets_bad_request_response,
resolve_admin_wallet_owner_summary,
};
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
@@ -29,7 +29,8 @@ pub(in super::super) async fn build_admin_wallet_detail_response(
};
let owner = resolve_admin_wallet_owner_summary(state, &wallet).await?;
let mut payload = build_admin_wallet_summary_payload(&wallet, &owner);
let mut payload =
build_admin_wallet_summary_payload_with_package(state, &wallet, &owner).await?;
if let Some(object) = payload.as_object_mut() {
object.insert("pending_refund_count".to_string(), serde_json::Value::Null);
}
@@ -1,6 +1,6 @@
use super::super::shared::{
build_admin_wallets_bad_request_response, parse_admin_wallets_limit,
parse_admin_wallets_offset, parse_admin_wallets_owner_type_filter,
build_admin_wallets_bad_request_response, enrich_admin_wallet_package_summary,
parse_admin_wallets_limit, parse_admin_wallets_offset, parse_admin_wallets_owner_type_filter,
wallet_owner_summary_from_fields,
};
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
@@ -32,38 +32,48 @@ pub(in super::super) async fn build_admin_wallet_list_response(
let (wallets, total) = state
.list_admin_wallets(status.as_deref(), owner_type.as_deref(), limit, offset)
.await?;
let items = wallets
.into_iter()
.map(|wallet| {
let owner = wallet_owner_summary_from_fields(
wallet.user_id.as_deref(),
wallet.user_name.clone(),
wallet.api_key_id.as_deref(),
wallet.api_key_name.clone(),
);
json!({
"id": wallet.id,
"user_id": wallet.user_id,
"api_key_id": wallet.api_key_id,
"owner_type": owner.owner_type,
"owner_name": owner.owner_name,
"balance": wallet.balance + wallet.gift_balance,
"recharge_balance": wallet.balance,
"gift_balance": wallet.gift_balance,
"refundable_balance": wallet.balance,
"currency": wallet.currency,
"status": wallet.status,
"limit_mode": wallet.limit_mode.clone(),
"unlimited": wallet.limit_mode.eq_ignore_ascii_case("unlimited"),
"total_recharged": wallet.total_recharged,
"total_consumed": wallet.total_consumed,
"total_refunded": wallet.total_refunded,
"total_adjusted": wallet.total_adjusted,
"created_at": wallet.created_at_unix_ms.and_then(unix_secs_to_rfc3339),
"updated_at": wallet.updated_at_unix_secs.and_then(unix_secs_to_rfc3339),
})
})
.collect::<Vec<_>>();
let mut items = Vec::with_capacity(wallets.len());
for wallet in wallets {
let owner = wallet_owner_summary_from_fields(
wallet.user_id.as_deref(),
wallet.user_name.clone(),
wallet.api_key_id.as_deref(),
wallet.api_key_name.clone(),
);
let user_id = wallet.user_id.clone();
let wallet_balance = wallet.balance + wallet.gift_balance;
let unlimited = wallet.limit_mode.eq_ignore_ascii_case("unlimited");
let mut payload = json!({
"id": wallet.id,
"user_id": wallet.user_id,
"api_key_id": wallet.api_key_id,
"owner_type": owner.owner_type,
"owner_name": owner.owner_name,
"balance": wallet_balance,
"recharge_balance": wallet.balance,
"gift_balance": wallet.gift_balance,
"refundable_balance": wallet.balance,
"currency": wallet.currency,
"status": wallet.status,
"limit_mode": wallet.limit_mode.clone(),
"unlimited": unlimited,
"total_recharged": wallet.total_recharged,
"total_consumed": wallet.total_consumed,
"total_refunded": wallet.total_refunded,
"total_adjusted": wallet.total_adjusted,
"created_at": wallet.created_at_unix_ms.and_then(unix_secs_to_rfc3339),
"updated_at": wallet.updated_at_unix_secs.and_then(unix_secs_to_rfc3339),
});
enrich_admin_wallet_package_summary(
state,
&mut payload,
user_id.as_deref(),
wallet_balance,
unlimited,
)
.await?;
items.push(payload);
}
Ok(Json(json!({
"items": items,
@@ -1,6 +1,6 @@
use super::super::shared::{
admin_wallet_id_from_suffix_path, build_admin_wallet_not_found_response,
build_admin_wallet_refund_payload, build_admin_wallet_summary_payload,
build_admin_wallet_refund_payload, build_admin_wallet_summary_payload_with_package,
build_admin_wallets_bad_request_response, parse_admin_wallets_limit,
parse_admin_wallets_offset, resolve_admin_wallet_owner_summary,
ADMIN_WALLETS_API_KEY_REFUND_DETAIL,
@@ -46,7 +46,8 @@ pub(in super::super) async fn build_admin_wallet_refunds_response(
}
let owner = resolve_admin_wallet_owner_summary(state, &wallet).await?;
let wallet_payload = build_admin_wallet_summary_payload(&wallet, &owner);
let wallet_payload =
build_admin_wallet_summary_payload_with_package(state, &wallet, &owner).await?;
let (refunds, total) = state
.list_admin_wallet_refunds(&wallet.id, limit, offset)
.await?;
@@ -1,6 +1,6 @@
use super::super::shared::{
admin_wallet_id_from_suffix_path, build_admin_wallet_not_found_response,
build_admin_wallet_summary_payload, build_admin_wallets_bad_request_response,
build_admin_wallet_summary_payload_with_package, build_admin_wallets_bad_request_response,
parse_admin_wallets_limit, parse_admin_wallets_offset, resolve_admin_wallet_owner_summary,
};
use crate::handlers::admin::request::{AdminAppState, AdminRequestContext};
@@ -39,7 +39,8 @@ pub(in super::super) async fn build_admin_wallet_transactions_response(
return Ok(build_admin_wallet_not_found_response());
};
let owner = resolve_admin_wallet_owner_summary(state, &wallet).await?;
let wallet_payload = build_admin_wallet_summary_payload(&wallet, &owner);
let wallet_payload =
build_admin_wallet_summary_payload_with_package(state, &wallet, &owner).await?;
let (transactions, total) = state
.list_admin_wallet_transactions(&wallet.id, limit, offset)