UNPKG

@liuliang520500/pdd-sdk

Version:

拼多多开放平台SDK,支持多多进宝API

150 lines (127 loc) 5.66 kB
/** * 拼多多开放平台签名验证示例 * * 使用官方文档提供的示例参数验证签名算法 * 期望的签名结果: E4DE3ED21002510DED352819E7AE6775 */ const crypto = require('crypto-js'); const nodeCrypto = require('crypto'); const fs = require('fs'); /** * 拼多多签名生成函数 * * 签名规则: * 1. 将参数按照键名升序排序 * 2. 在参数前后加上clientSecret * 3. 对整个字符串计算MD5并转为大写 * * @param {String} clientSecret 应用密钥 * @param {Object} params 请求参数 * @return {String} 签名值 */ function generateSign(clientSecret, params) { // 按键名升序排序 const keys = Object.keys(params).sort(); // 拼接参数字符串 let stringToSign = clientSecret; for (let i = 0; i < keys.length; i++) { const key = keys[i]; // 签名不包含sign字段本身 if (key !== 'sign' && params[key] !== undefined && params[key] !== null) { stringToSign += key + params[key]; } } stringToSign += clientSecret; // 记录签名过程 const output = []; output.push(`排序后的键名: ${keys.join(', ')}`); output.push(`拼接后的字符串: ${stringToSign}`); // 计算MD5并转为大写 const sign = crypto.MD5(stringToSign).toString().toUpperCase(); output.push(`计算出的签名: ${sign}`); fs.appendFileSync('signature-debug.log', output.join('\n') + '\n\n'); return sign; } // 基于官方文档的测试案例 function testOfficialExample() { console.log('======= 拼多多开放平台签名验证 ======='); // 清空日志文件 fs.writeFileSync('signature-debug.log', ''); // 基于文档截图的示例参数 const testCase1 = { clientSecret: '12345678', // 之前测试例子中的密钥 params: { 'type': 'pdd.ddk.oauth.goods.pid.generate', 'client_id': '89f9722aecac48d9a4363270cd4bd8e0', 'timestamp': '1499858290807', 'number': '1', 'p_id_name_list': '[123,456]', 'data_type': 'JSON', 'version': 'V1' } }; console.log('测试参数1:', JSON.stringify(testCase1.params, null, 2)); console.log('ClientSecret:', testCase1.clientSecret); // 计算签名 const sign1 = generateSign(testCase1.clientSecret, testCase1.params); console.log('生成的签名:', sign1); console.log('是否匹配期望的签名:', sign1 === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配'); console.log('\n======= 官方文档的测试例子 ======='); // 官方文档中提供的测试参数和签名 const testCase2 = { clientSecret: 'testSecret', // 官方文档中的密钥 params: { 'access_token': 'asd78172s8ds9a921j9qqwda12312w1w21211', 'client_id': '1', 'data_type': 'XML', 'type': 'pdd.order.number.list.get', 'timestamp': '1480411125', 'order_status': '1', 'page': '1', 'page_size': '10' } }; console.log('测试参数2:', JSON.stringify(testCase2.params, null, 2)); console.log('ClientSecret:', testCase2.clientSecret); // 计算签名 const sign2 = generateSign(testCase2.clientSecret, testCase2.params); console.log('生成的签名:', sign2); console.log('期望的签名:', 'E4DE3ED21002510DED352819E7AE6775'); console.log('签名是否匹配:', sign2 === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配'); // 如果签名不匹配,进行特定测试 if (sign2 !== 'E4DE3ED21002510DED352819E7AE6775') { console.log('\n尝试使用原生Node crypto库进行验证:'); // 使用Node.js原生crypto库测试 const stringToSign = 'testSecret' + 'access_token' + 'asd78172s8ds9a921j9qqwda12312w1w21211' + 'client_id' + '1' + 'data_type' + 'XML' + 'order_status' + '1' + 'page' + '1' + 'page_size' + '10' + 'timestamp' + '1480411125' + 'type' + 'pdd.order.number.list.get' + 'testSecret'; const nodeSign = nodeCrypto .createHash('md5') .update(stringToSign) .digest('hex') .toUpperCase(); console.log('拼接字符串:', stringToSign); console.log('Node crypto签名:', nodeSign); console.log('是否匹配:', nodeSign === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配'); // 测试官方提供的完整字符串 console.log('\n使用官方文档提供的完整拼接字符串测试:'); const officialString = 'testSecretaccess_tokenasd78172s8ds9a921j9qqwda12312w1w21211client_id1data_typeXMLorder_status1page1page_size10timestamp1480411125typepdd.order.number.list.gettestSecret'; const officialSign = nodeCrypto .createHash('md5') .update(officialString) .digest('hex') .toUpperCase(); console.log('官方拼接字符串:', officialString); console.log('使用官方字符串生成签名:', officialSign); console.log('是否匹配:', officialSign === 'E4DE3ED21002510DED352819E7AE6775' ? '✓ 匹配' : '✗ 不匹配'); } } // 执行测试 testOfficialExample();