fix: enforce WeChat Pay JSAPI field limits
This commit is contained in:
@@ -927,10 +927,47 @@ pub fn build_runtime_profile_recharge_order_id(
|
||||
created_at_micros: i64,
|
||||
product_id: &str,
|
||||
) -> String {
|
||||
format!(
|
||||
"recharge:{}",
|
||||
build_runtime_profile_recharge_wallet_ledger_id(user_id, created_at_micros, product_id)
|
||||
)
|
||||
// 微信支付 v3 的 out_trade_no 只接受较短的字母、数字和部分符号。
|
||||
// 订单号同时作为本地 profile_recharge_order 主键,因此统一使用可支付渠道兼容的紧凑格式。
|
||||
let timestamp = encode_runtime_profile_recharge_order_base36(created_at_micros.unsigned_abs());
|
||||
let hash = hash_runtime_profile_recharge_order_key(user_id, product_id, created_at_micros);
|
||||
format!("rcg{timestamp}{:010x}", hash & 0x0000_0003_ffff_ffff)
|
||||
}
|
||||
|
||||
fn encode_runtime_profile_recharge_order_base36(mut value: u64) -> String {
|
||||
const DIGITS: &[u8; 36] = b"0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
if value == 0 {
|
||||
return "0".to_string();
|
||||
}
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
while value > 0 {
|
||||
buffer.push(DIGITS[(value % 36) as usize] as char);
|
||||
value /= 36;
|
||||
}
|
||||
buffer.iter().rev().collect()
|
||||
}
|
||||
|
||||
fn hash_runtime_profile_recharge_order_key(
|
||||
user_id: &str,
|
||||
product_id: &str,
|
||||
created_at_micros: i64,
|
||||
) -> u64 {
|
||||
let mut hash = 14_695_981_039_346_656_037u64;
|
||||
for byte in user_id
|
||||
.trim()
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.copied()
|
||||
.chain([b':'])
|
||||
.chain(product_id.trim().as_bytes().iter().copied())
|
||||
.chain([b':'])
|
||||
.chain(created_at_micros.to_le_bytes())
|
||||
{
|
||||
hash ^= u64::from(byte);
|
||||
hash = hash.wrapping_mul(1_099_511_628_211);
|
||||
}
|
||||
hash
|
||||
}
|
||||
|
||||
pub fn resolve_runtime_profile_points_recharge_delta(
|
||||
|
||||
@@ -683,9 +683,13 @@ mod tests {
|
||||
build_runtime_profile_recharge_wallet_ledger_id("user-1", 200, "points_60"),
|
||||
"user-1:200:points_60"
|
||||
);
|
||||
assert_eq!(
|
||||
build_runtime_profile_recharge_order_id("user-1", 200, "points_60"),
|
||||
"recharge:user-1:200:points_60"
|
||||
let order_id = build_runtime_profile_recharge_order_id("user-1", 200, "points_60");
|
||||
assert!(order_id.starts_with("rcg"));
|
||||
assert!(order_id.len() <= 32);
|
||||
assert!(
|
||||
order_id
|
||||
.chars()
|
||||
.all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit())
|
||||
);
|
||||
assert_eq!(
|
||||
build_runtime_profile_redeem_code_usage_id("GIFT", "user-1", 300, 2),
|
||||
|
||||
Reference in New Issue
Block a user