补齐微信虚拟支付查单与补偿

接入微信官方虚拟支付查单并缓存稳定接口令牌
让用户确认与订单过期补偿统一核对支付类型、状态、金额和单号
增加单笔历史订单的 dry-run 与确认指纹补单工具
隔离运行时身份与敏感 openid 文件并补充配置契约和回归测试
This commit is contained in:
2026-07-13 13:12:44 +08:00
parent 06aa99e3eb
commit 2f69f2fda2
16 changed files with 1343 additions and 33 deletions
+18
View File
@@ -145,6 +145,7 @@ pub struct AppConfig {
pub wechat_mini_program_virtual_payment_offer_id: Option<String>,
pub wechat_mini_program_virtual_payment_app_key: Option<String>,
pub wechat_mini_program_virtual_payment_sandbox_app_key: Option<String>,
pub wechat_mini_program_virtual_payment_query_order_endpoint: String,
pub wechat_mini_program_message_token: Option<String>,
pub wechat_mini_program_message_encoding_aes_key: Option<String>,
pub wechat_mini_program_subscribe_message_enabled: bool,
@@ -400,6 +401,8 @@ impl Default for AppConfig {
wechat_mini_program_virtual_payment_offer_id: None,
wechat_mini_program_virtual_payment_app_key: None,
wechat_mini_program_virtual_payment_sandbox_app_key: None,
wechat_mini_program_virtual_payment_query_order_endpoint:
"https://api.weixin.qq.com/xpay/query_order".to_string(),
wechat_mini_program_message_token: None,
wechat_mini_program_message_encoding_aes_key: None,
wechat_mini_program_subscribe_message_enabled: true,
@@ -941,6 +944,11 @@ impl AppConfig {
read_first_non_empty_env(&["WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_APP_KEY"]);
config.wechat_mini_program_virtual_payment_sandbox_app_key =
read_first_non_empty_env(&["WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_SANDBOX_APP_KEY"]);
if let Some(endpoint) =
read_first_non_empty_env(&["WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_QUERY_ORDER_ENDPOINT"])
{
config.wechat_mini_program_virtual_payment_query_order_endpoint = endpoint;
}
config.wechat_mini_program_message_token =
read_first_non_empty_env(&["WECHAT_MINIPROGRAM_MESSAGE_TOKEN"]);
config.wechat_mini_program_message_encoding_aes_key =
@@ -2083,6 +2091,7 @@ mod tests {
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_OFFER_ID");
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_APP_KEY");
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_SANDBOX_APP_KEY");
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_QUERY_ORDER_ENDPOINT");
std::env::remove_var("WECHAT_MINIPROGRAM_MESSAGE_TOKEN");
std::env::remove_var("WECHAT_MINIPROGRAM_MESSAGE_ENCODING_AES_KEY");
std::env::remove_var("WECHAT_MINIPROGRAM_SUBSCRIBE_MESSAGE_ENABLED");
@@ -2110,6 +2119,10 @@ mod tests {
"WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_SANDBOX_APP_KEY",
"sandbox-app-key-001",
);
std::env::set_var(
"WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_QUERY_ORDER_ENDPOINT",
"http://127.0.0.1:18080/xpay/query_order",
);
std::env::set_var("WECHAT_MINIPROGRAM_MESSAGE_TOKEN", "message-token-001");
std::env::set_var(
"WECHAT_MINIPROGRAM_MESSAGE_ENCODING_AES_KEY",
@@ -2181,6 +2194,10 @@ mod tests {
);
assert_eq!(config.wechat_mini_program_subscribe_message_state, "trial");
assert_eq!(config.wechat_mini_program_virtual_payment_env, 1);
assert_eq!(
config.wechat_mini_program_virtual_payment_query_order_endpoint,
"http://127.0.0.1:18080/xpay/query_order"
);
unsafe {
std::env::remove_var("WECHAT_PAY_ENABLED");
@@ -2195,6 +2212,7 @@ mod tests {
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_OFFER_ID");
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_APP_KEY");
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_SANDBOX_APP_KEY");
std::env::remove_var("WECHAT_MINI_PROGRAM_VIRTUAL_PAYMENT_QUERY_ORDER_ENDPOINT");
std::env::remove_var("WECHAT_MINIPROGRAM_MESSAGE_TOKEN");
std::env::remove_var("WECHAT_MINIPROGRAM_MESSAGE_ENCODING_AES_KEY");
std::env::remove_var("WECHAT_MINIPROGRAM_SUBSCRIBE_MESSAGE_ENABLED");