123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- const dataJson = {"meta":{"success":true,"code":"0000","message":"Request Success"},"data":{"merchantNo":"AC202299319","merchantOrderNo":"DS202412311005240317","orderNo":"R08OC0241231100525384624557803","currency":"JPY","payType":"JAPAN_PAY","orderAmount":10000,"paidAmount":null,"orderFee":700,"payModel":"BankTransfer","orderStatus":"PENDING","webUrl":null,"page":null,"orderTime":1735610725000,"finishTime":0,"sign":"V0EZCULoPBG7q8CuWxSnAkTnigjPbX49IquVzqH8TZ2Kp+SYJmXAmAWPLKPWWTQdvAw99T3PrkEMmutKfCE2zEay5uKhtHU8BY4T0phLr8cU3G9MTWNjp3AJ/dtJ6nh19/L20vis5anvj0aC4ShnEcIzfVeWtWszT+meu7LC4Js52C9vmGGKtPWUUbD6zV/+3YYnNxf/BIEBLOewWIaHccne6E37wbzjbHWczAPecka/E7KOGPyG2PPa67Y5ixsGUjhSD6RHHjbXKJatD8+vTa4BpwieQ4FZTF1dF2oCWJjVOLiB4ZSwMs4vRf9bb0GhWmJuf1N45eWWJkMRJ+392A==","remark":"","errorMessage":null,"descriptor":null},"sign":"589092dbe5aca882cfcc409d1f868d0e"}
- const express = require('express');
- const bodyParser = require('body-parser');
- const fs = require('fs');
- const path = require('path');
- const { createVerify } = require('crypto');
- const logger = console;
- // 创建Express应用
- const app = express();
- app.use(bodyParser.urlencoded({ extended: true }));
- app.use(bodyParser.json());
- // 加载配置
- const configPath = path.join(__dirname, '../config.ini');
- const config = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf8') : null;
- // 模拟解析配置文件
- const PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n" + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK/q2uuuf+s4pd2gkVAyhHkpog1o4RL5+Dm2ZOe5i7O/ELKJvj/9JIrNO1abNNuG8g2nvBnOeJ5uii1q83Qy9C4aaey1UjqYd3iVupuO8Xfmr/3sHTec6R8X0HZnuQ/fsU8uREYEQFUfBFcZtiNz2TqXfjJXMXAeTpXc6CbKOLe3AgMBAAECgYAYDVvWSnsJ7apb9Ya4uNd8+3DBNZxEbHIAbgw41Jkhv9doGcYt2I4k/i+FRV5CP56buFnTC3RZcRKqaAuWURsqcnDG8ufFIhoSEiD11FcFrXanFdixfj9gijuPiTE4w9f07eDVEfdQjFMSO8tYDbsMUoaMPUTOoreqyy86uW0G0QJBAN5zaUsxjgtJhqO3OsoHXpu+67bsM2ounuoHWq7KehiVeb9ykrS6quZ1+r5+0SIMEFkKZKbpwfIG+Hi9NII85/ECQQDKctaP1WQzuLQvm97lfQEfgY/JWL9RZuWriGd7fDT7Nrl0FTK5O9q22HvJdwIQktaTOQca28KzHucIxa7ouYInAkB1KehteF5OR52ooRtPyW3lLjvMjr/Nz1xX+yOiKHcCd8g2M8xdcGwPEljM+NKB0kTSAQ1edIR4S3+XaGA9sIKhAkEAsfVaqJry9wgw0/zXZbGJsDFKvLpXiu3BjBReqszXIdDMGr+bk/qKWtpXjhQf64O4PTgPB8wQDTZn7m0fQJH5VwJBAIDnGXiaoMRammmmOl6sYwar8APUMhRkCNqxzwiEokmwRsrR0GKuKtLKpRg/jNAAQbj2ajVihhgR7F3/04kc/jE=\n" + "-----END RSA PRIVATE KEY-----\n"; // 从配置文件中获取私钥
- // 创建排序后的数据字符串
- function createSortedDataString(data) {
- const validKeys = ['merchantNo', 'merchantOrderNo', 'orderNo', 'currency', 'orderAmount',
- 'orderFee', 'payModel', 'orderStatus', 'payType'];
- const sortedData = Object.keys(data)
- .filter(key => validKeys.includes(key))
- .sort()
- .map(key => `${key}=${data[key]}`)
- .join('&');
- return sortedData;
- }
- // 验证Webhook
- function verifyWebhook(data) {
- const sign = data.sign;
- if (!sign) {
- logger.warn("No signature found in the data");
- return { isValid: false, message: "No signature found" };
- }
- delete data.sign;
- const signStr = createSortedDataString(data);
- logger.info(`String to be signed: ${signStr}`);
- // Verify the signature using RSA
- const verify = createVerify('SHA256');
- verify.update(signStr);
- verify.end();
- try {
- const isVerified = verify.verify(PRIVATE_KEY, sign, 'base64');
- if (isVerified) {
- logger.info("Verification passed");
- return { isValid: true, message: "Verification passed" };
- } else {
- logger.warn("Verification failed");
- return { isValid: false, message: "Verification failed" };
- }
- } catch (error) {
- logger.error(`Verification error: ${error.message}`);
- return { isValid: false, message: `Verification error: ${error.message}` };
- }
- }
- // 处理Webhook请求
- app.post('/webhook', (req, res) => {
- logger.info("Received a webhook POST request");
- const data = req.body.data;
- if (!data) {
- logger.error("Invalid data format received");
- return res.status(400).json({ status: "error", message: "Invalid data format" });
- }
- logger.info(`Received data: ${JSON.stringify(data, null, 2)}`);
- const { isValid, message } = verifyWebhook(data);
- if (isValid) {
- logger.info("Webhook verified successfully");
- res.status(200).json({ status: "success", message });
- } else {
- logger.warn(`Webhook verification failed: ${message}`);
- res.status(400).json({ status: "error", message });
- }
- });
- // 启动服务器
- const PORT = 5000;
- app.listen(PORT, () => {
- logger.info(`Server is running on http://127.0.0.1:${PORT}`);
- });
|