feat: 接入微信小程序支付

This commit is contained in:
2026-05-14 00:16:17 +08:00
parent bf4423e53b
commit ae58a443a3
42 changed files with 2265 additions and 191 deletions

View File

@@ -190,8 +190,9 @@ pub fn build_runtime_profile_recharge_order_record(
amount_cents: snapshot.amount_cents,
status: snapshot.status,
payment_channel: snapshot.payment_channel,
paid_at: format_utc_micros(snapshot.paid_at_micros),
paid_at: snapshot.paid_at_micros.map(format_utc_micros),
paid_at_micros: snapshot.paid_at_micros,
provider_transaction_id: snapshot.provider_transaction_id,
created_at: format_utc_micros(snapshot.created_at_micros),
created_at_micros: snapshot.created_at_micros,
points_delta: snapshot.points_delta,

View File

@@ -265,6 +265,20 @@ pub fn build_runtime_profile_recharge_order_create_input(
})
}
pub fn build_runtime_profile_recharge_order_paid_input(
order_id: String,
paid_at_micros: i64,
provider_transaction_id: Option<String>,
) -> Result<RuntimeProfileRechargeOrderPaidInput, RuntimeProfileFieldError> {
let order_id =
normalize_required_string(order_id).ok_or(RuntimeProfileFieldError::MissingOrderId)?;
Ok(RuntimeProfileRechargeOrderPaidInput {
order_id,
paid_at_micros,
provider_transaction_id: provider_transaction_id.and_then(normalize_required_string),
})
}
pub fn build_runtime_profile_feedback_submission_input(
user_id: String,
description: String,

View File

@@ -33,6 +33,7 @@ pub const PROFILE_TASK_DEFAULT_THRESHOLD: u32 = 1;
pub const SAVE_SNAPSHOT_VERSION: u32 = 2;
pub const DEFAULT_SAVE_ARCHIVE_SUMMARY_TEXT: &str = "继续推进上一次保存的故事。";
pub const PROFILE_RECHARGE_PAYMENT_CHANNEL_MOCK: &str = "mock";
pub const PROFILE_RECHARGE_PAYMENT_CHANNEL_WECHAT_MINI_PROGRAM: &str = "wechat_mp";
pub const PROFILE_FEEDBACK_DESCRIPTION_MIN_CHARS: usize = 10;
pub const PROFILE_FEEDBACK_DESCRIPTION_MAX_CHARS: usize = 200;
pub const PROFILE_FEEDBACK_CONTACT_PHONE_MAX_CHARS: usize = 40;
@@ -951,13 +952,21 @@ impl RuntimeProfileMembershipTier {
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum RuntimeProfileRechargeOrderStatus {
Pending,
Paid,
Failed,
Closed,
Refunded,
}
impl RuntimeProfileRechargeOrderStatus {
pub fn as_str(&self) -> &'static str {
match self {
Self::Pending => "pending",
Self::Paid => "paid",
Self::Failed => "failed",
Self::Closed => "closed",
Self::Refunded => "refunded",
}
}
}
@@ -1009,7 +1018,8 @@ pub struct RuntimeProfileRechargeOrderSnapshot {
pub amount_cents: u64,
pub status: RuntimeProfileRechargeOrderStatus,
pub payment_channel: String,
pub paid_at_micros: i64,
pub paid_at_micros: Option<i64>,
pub provider_transaction_id: Option<String>,
pub created_at_micros: i64,
pub points_delta: i64,
pub membership_expires_at_micros: Option<i64>,
@@ -1059,6 +1069,14 @@ pub struct RuntimeProfileRechargeOrderCreateInput {
pub created_at_micros: i64,
}
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct RuntimeProfileRechargeOrderPaidInput {
pub order_id: String,
pub paid_at_micros: i64,
pub provider_transaction_id: Option<String>,
}
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct RuntimeProfileWalletLedgerEntrySnapshot {
@@ -1471,8 +1489,9 @@ pub struct RuntimeProfileRechargeOrderRecord {
pub amount_cents: u64,
pub status: RuntimeProfileRechargeOrderStatus,
pub payment_channel: String,
pub paid_at: String,
pub paid_at_micros: i64,
pub paid_at: Option<String>,
pub paid_at_micros: Option<i64>,
pub provider_transaction_id: Option<String>,
pub created_at: String,
pub created_at_micros: i64,
pub points_delta: i64,

View File

@@ -72,6 +72,7 @@ pub enum RuntimeProfileFieldError {
TaskDisabled,
TaskNotClaimable,
TaskAlreadyClaimed,
MissingOrderId,
MissingProductId,
MissingWorldKey,
MissingBottomTab,
@@ -133,6 +134,7 @@ impl std::fmt::Display for RuntimeProfileFieldError {
Self::TaskDisabled => f.write_str("任务已停用"),
Self::TaskNotClaimable => f.write_str("任务尚未达成"),
Self::TaskAlreadyClaimed => f.write_str("任务奖励已领取"),
Self::MissingOrderId => f.write_str("recharge.order_id 不能为空"),
Self::MissingProductId => f.write_str("recharge.product_id 不能为空"),
Self::MissingWorldKey => f.write_str("profile.world_key 不能为空"),
Self::MissingBottomTab => f.write_str("runtime_snapshot.bottom_tab 不能为空"),