You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PHP GET传递JavaScript变量至Millikart支付网关

实现在线支付表单的完整方案

我来帮你搞定这个在线支付表单的实现,咱们从你最关心的金额转换开始,一步步拆解所有环节:

1. 处理交易金额转换(JS计算后的变量转整数格式)

你提到交易金额是JS计算得到的变量,需要转换成整数格式(比如$50.25转成5025),这里要注意浮点数精度问题——直接乘以100可能会出现类似0.1+0.2=0.30000000000000004的误差,所以推荐用Math.round来确保准确性:

// 假设这是你JS计算得到的金额(比如从购物车总价、输入框获取等)
const calculatedAmount = 50.25; 

// 转换为整数格式:乘以100后取整
const amount = Math.round(calculatedAmount * 100); 
// 结果:5025

如果你的金额是字符串格式(比如用户输入的"50.25"),先转成数字再处理:

const amountStr = "50.25";
const amount = Math.round(parseFloat(amountStr) * 100);

2. 收集所有必填参数

按支付网关要求整理参数:

  • mid:你的商户ID(固定值,比如"Test")
  • amount:上面转换后的整数金额
  • currency:ISO 4217货币代码(比如阿塞拜疆马纳特是944)
  • description:交易描述(比如"test1000",可根据业务动态生成)
  • reference:唯一交易参考号(建议用时间戳+随机字符串生成,确保不重复)
  • language:可选语言(az/en/ru,比如选"az")
  • key:商户密钥(重要提醒:绝对不能把密钥写在前端代码里!建议后端生成签名,避免密钥泄露)

3. 生成Signature签名

根据你提供的PHP逻辑,转换成JS版本的签名生成函数。注意参数顺序必须严格和示例一致,否则签名会验证失败:

function generateSignature(mid, amount, currency, description, reference, language, key) {
    // 处理description为空的情况,用"0"代替
    const descPart = description ? `${description.length}${description}` : "0";
    
    // 按顺序拼接所有参数的长度+值,最后加密钥
    const signatureStr = 
        `${mid.length}${mid}` +
        `${amount.toString().length}${amount}` +
        `${currency.length}${currency}` +
        descPart +
        `${reference.length}${reference}` +
        `${language.length}${language}` +
        key;
    
    // 生成MD5哈希并转大写
    // 注意:JS本身没有内置MD5函数,你可以用第三方库(如crypto-js)或者后端生成
    // 以下是用crypto-js的示例(需要先引入库)
    const md5Hash = CryptoJS.MD5(signatureStr).toString();
    return md5Hash.toUpperCase();
}

关于签名的安全提醒

如果把密钥放在前端,任何人都能通过查看源码获取,会导致交易被篡改的风险。更安全的做法是:前端把计算好的金额、描述、参考号等参数传给后端接口,后端用密钥生成签名,再返回完整的支付跳转URL给前端。

4. 拼接支付跳转URL

把所有参数拼接成符合要求的URL,注意对参数值进行URL编码:

// 假设已经获取到所有参数和生成的signature
const mid = "Test";
const currency = "944";
const description = "test1000";
// 生成唯一参考号示例:时间戳+随机字符串
const reference = `T${Date.now()}${Math.random().toString(16).slice(2, 10)}`;
const language = "az";
const signature = generateSignature(mid, amount, currency, description, reference, language, YOUR_KEY); // 注意YOUR_KEY如果是前端用的话要替换,但不建议

// 拼接URL参数
const params = new URLSearchParams({
    mid,
    amount,
    currency,
    description,
    reference,
    language,
    signature
});

// 完整支付URL
const paymentUrl = `https://test.millikart.az:7444/gateway/payment/register?${params.toString()}`;

5. 触发支付跳转

给你的支付按钮添加点击事件,执行上述逻辑后跳转:

<button id="payBtn">发起支付</button>

<script>
document.getElementById("payBtn").addEventListener("click", async () => {
    // 1. 计算并转换金额
    const calculatedAmount = 50.25; // 替换成你的实际计算逻辑
    const amount = Math.round(calculatedAmount * 100);
    
    // 2. 如果是后端生成签名,这里调用接口获取支付URL
    // const response = await fetch('/api/generate-payment-url', {
    //     method: 'POST',
    //     headers: { 'Content-Type': 'application/json' },
    //     body: JSON.stringify({ amount, description: "test1000", language: "az" })
    // });
    // const { paymentUrl } = await response.json();
    
    // 3. 跳转到支付页面
    window.location.href = paymentUrl;
});
</script>

关键注意事项

  • 参数顺序:生成签名时的参数顺序必须严格按照mid → amount → currency → description → reference → language → key的顺序,不能打乱。
  • 金额精度:一定要用Math.round处理浮点数,避免转换后出现错误的整数(比如50.259转成5026而不是5025)。
  • 签名安全:密钥绝对不能暴露在前端,后端生成签名是最优方案。

内容的提问来源于stack exchange,提问作者Nahid Mirzayev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:37:19