feat: switch mini program recharge to virtual payment

This commit is contained in:
kdletters
2026-05-26 22:32:16 +08:00
parent b388b124da
commit f36b90ebdb
22 changed files with 959 additions and 137 deletions

View File

@@ -245,6 +245,22 @@ pub struct WechatMiniProgramPayParamsResponse {
pub pay_sign: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct WechatMiniProgramVirtualPayParamsResponse {
pub mode: String,
pub sign_data: String,
pub pay_sig: String,
pub signature: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum WechatMiniProgramPaymentParamsResponse {
Ordinary(WechatMiniProgramPayParamsResponse),
Virtual(WechatMiniProgramVirtualPayParamsResponse),
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct WechatH5PaymentResponse {
@@ -283,7 +299,7 @@ pub struct CreateProfileRechargeOrderResponse {
pub order: ProfileRechargeOrderResponse,
pub center: ProfileRechargeCenterResponse,
#[serde(default)]
pub wechat_mini_program_pay_params: Option<WechatMiniProgramPayParamsResponse>,
pub wechat_mini_program_pay_params: Option<WechatMiniProgramPaymentParamsResponse>,
#[serde(default)]
pub wechat_h5_payment: Option<WechatH5PaymentResponse>,
#[serde(default)]
@@ -1451,6 +1467,67 @@ mod tests {
);
}
#[test]
fn create_profile_recharge_order_response_serializes_virtual_wechat_payloads() {
let order = ProfileRechargeOrderResponse {
order_id: "rcgtest002".to_string(),
product_id: "member_month".to_string(),
product_title: "月卡".to_string(),
kind: "membership".to_string(),
amount_cents: 2800,
status: "pending".to_string(),
payment_channel: "wechat_mp_virtual".to_string(),
paid_at: None,
provider_transaction_id: None,
created_at: "2026-05-15T10:00:00Z".to_string(),
points_delta: 0,
membership_expires_at: Some("2026-06-15T10:00:00Z".to_string()),
};
let center = ProfileRechargeCenterResponse {
wallet_balance: 0,
membership: ProfileMembershipResponse {
status: "normal".to_string(),
tier: "normal".to_string(),
started_at: None,
expires_at: None,
updated_at: None,
},
point_products: vec![],
membership_products: vec![],
benefits: vec![],
latest_order: None,
has_points_recharged: false,
};
let payload = serde_json::to_value(CreateProfileRechargeOrderResponse {
order,
center,
wechat_mini_program_pay_params: Some(WechatMiniProgramPaymentParamsResponse::Virtual(
WechatMiniProgramVirtualPayParamsResponse {
mode: "short_series_goods".to_string(),
sign_data:
"{\"offerId\":\"offer-1\",\"productId\":\"member_month\",\"goodsPrice\":2800}"
.to_string(),
pay_sig: "pay-sig".to_string(),
signature: "user-sig".to_string(),
},
)),
wechat_h5_payment: None,
wechat_native_payment: None,
})
.expect("payload should serialize");
assert_eq!(
payload["wechatMiniProgramPayParams"]["mode"],
json!("short_series_goods")
);
assert_eq!(
payload["wechatMiniProgramPayParams"]["signData"],
json!("{\"offerId\":\"offer-1\",\"productId\":\"member_month\",\"goodsPrice\":2800}")
);
assert_eq!(payload["wechatMiniProgramPayParams"]["paySig"], json!("pay-sig"));
assert_eq!(payload["wechatMiniProgramPayParams"]["signature"], json!("user-sig"));
}
#[test]
fn profile_feedback_response_uses_camel_case_fields() {
let payload = serde_json::to_value(SubmitProfileFeedbackResponse {