|
@@ -1,6 +1,16 @@
|
|
|
import { DateUtil } from '@pura/harmony-utils';
|
|
import { DateUtil } from '@pura/harmony-utils';
|
|
|
import { SignUtils } from './SignUtils';
|
|
import { SignUtils } from './SignUtils';
|
|
|
|
|
|
|
|
|
|
+interface BizContent {
|
|
|
|
|
+ timeout_express: string;
|
|
|
|
|
+ product_code: string;
|
|
|
|
|
+ total_amount: string;
|
|
|
|
|
+ subject: string;
|
|
|
|
|
+ body: string;
|
|
|
|
|
+ out_trade_no: string;
|
|
|
|
|
+ passback_params: string;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export class OrderInfoUtil {
|
|
export class OrderInfoUtil {
|
|
|
static readonly APP_ID = '2019091067184257';//七梦支付宝appid
|
|
static readonly APP_ID = '2019091067184257';//七梦支付宝appid
|
|
|
static totalAmount = 0.01;
|
|
static totalAmount = 0.01;
|
|
@@ -16,8 +26,9 @@ export class OrderInfoUtil {
|
|
|
*/
|
|
*/
|
|
|
static readonly RSA2_PRIVATE = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCE9pDxmlrXJa2KH2vv7dqGKnepLD6eF6rJxQ/SCHmXBY93pzfXmu2KSscyrCl5OPZSgmQV5KSOFyIJmJyRDZAk5wTXUno2B9/P8xo05aMpijSIdJeWjX1xgZOddiicHjr3EKKwBzDkukw1gtcnuaGy/qzMG84VYbBoj75pG0AD+a0EdkDSf9XO4wy/1pMyzFeitNhCr9vKyl/W45GQZYgJsKOjlIwmdyNLZz/vsKJJeUYqlZ6wI8bY+P3+Gq80uMZoKi5xxCW3TPj8Y7gv5Nb3uWc1LZfKr8gAIi3yvaN8Tj5zHgBTjIYc9+0RhMvof96Cu2pIpc99ERjc0bbhD57nAgMBAAECggEARt1m+O2sdriFGnWOwIyDiDhAGHEVWosAopMd0HJl44C6Kyp7T7Up3yflrPMnE42xct4925FFxtk7cePdpk2VQqXB5cT2j694sMs/b2vony4iu4twc3QrpIBMHYMpN7PA94btPmZGv9Eu5uI6K9j6/nxPumUjXC/5pnDeKgS1BKibrDqZzR7tQ6tdUZfaAGV0247xHwO9BEKMz5Xrl4CxktbfAN9vmb0z0AHhbLAGgAyDRE7imQ8PBT0NfGcu1ubpNGc37Mg+Ss78tBRUHxBcAOJgBT0w8mj3gweRJ/Xy3/rcgnQTVJXRaIjvNUxAiG5pRQH+w9NfV/JnmLjSQ4Kd+QKBgQC/U2hx1abJtVAyZfoqxItH8qH58dYzrF6oQXdmFBqqrD4MuYsNEtzyZnr2yFS/PkQLFMThMFWmGQGCByFjTazBD4+rB34ZT3igPEPlGLPDbVa+qegtO15cNoF0cykOpwI5V8Sb9y/WFPOq/OERZlhcU5RzkC/BqfrOg7PFd9NS3QKBgQCx6K4iMLX/FhZyrjI//JF7cr6sZ5Q2dzWVXsVhB3px7E3hAam+r1zobAnGbULXf/Q0SPqmJiKw7UKncBzMERp8476T5By7xRVlgLKVAoFcAIsQj+xyQEQ1CBJW+7xI3BXvPd1+iSKAY6SolZ847ImTJepgFBT2pb5SaqUuP3mSkwKBgD0PraHHAjgV+cZb7X+AwsLvmOpgWHCdbohcfHLDr88Qsaz1+n7tqj5inpPsU7/Fa4nt0vfbqTodePG6vNkojR4AjWWUOpZxWpopIbIYNCcG2kx3hXYKII9lheNYbZ4Thw4uCL2OImI8xZeopVwcQc8VjadkORmh2j3WoqU/HN6xAoGAPjujdihN8Z47WgBfaYyjI2i/FDXjXa4Tm12cc9WW2nULxRK82wwi1ta8EKI1yIZk2UlSDH64keVc9I8+M5AkEN3l03vvJSvK0UfUsFVBBPrXqoJ99nVOprJdH/pNIbuDHL4qVdIItJqmhaZZHSN4+HVB6Dv+HU1bJx9RCr1/fGsCgYEAh5l2zfXPPyQ/IkLQxJXKsZdZpuGUtea9+RGnzWuEesoYT7puEx2PAXWidHpDf2SWkMVr4oHYBi8QI2uepORBA6ZJ8I8dW3xILzqfUUISKVjczNFqG7dJPmyaYuWWEYSVkhbXl3NMcX00FdMCCK+R68I10oAGiK/sugqitJ4Uoz4=';
|
|
static readonly RSA2_PRIVATE = 'MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCE9pDxmlrXJa2KH2vv7dqGKnepLD6eF6rJxQ/SCHmXBY93pzfXmu2KSscyrCl5OPZSgmQV5KSOFyIJmJyRDZAk5wTXUno2B9/P8xo05aMpijSIdJeWjX1xgZOddiicHjr3EKKwBzDkukw1gtcnuaGy/qzMG84VYbBoj75pG0AD+a0EdkDSf9XO4wy/1pMyzFeitNhCr9vKyl/W45GQZYgJsKOjlIwmdyNLZz/vsKJJeUYqlZ6wI8bY+P3+Gq80uMZoKi5xxCW3TPj8Y7gv5Nb3uWc1LZfKr8gAIi3yvaN8Tj5zHgBTjIYc9+0RhMvof96Cu2pIpc99ERjc0bbhD57nAgMBAAECggEARt1m+O2sdriFGnWOwIyDiDhAGHEVWosAopMd0HJl44C6Kyp7T7Up3yflrPMnE42xct4925FFxtk7cePdpk2VQqXB5cT2j694sMs/b2vony4iu4twc3QrpIBMHYMpN7PA94btPmZGv9Eu5uI6K9j6/nxPumUjXC/5pnDeKgS1BKibrDqZzR7tQ6tdUZfaAGV0247xHwO9BEKMz5Xrl4CxktbfAN9vmb0z0AHhbLAGgAyDRE7imQ8PBT0NfGcu1ubpNGc37Mg+Ss78tBRUHxBcAOJgBT0w8mj3gweRJ/Xy3/rcgnQTVJXRaIjvNUxAiG5pRQH+w9NfV/JnmLjSQ4Kd+QKBgQC/U2hx1abJtVAyZfoqxItH8qH58dYzrF6oQXdmFBqqrD4MuYsNEtzyZnr2yFS/PkQLFMThMFWmGQGCByFjTazBD4+rB34ZT3igPEPlGLPDbVa+qegtO15cNoF0cykOpwI5V8Sb9y/WFPOq/OERZlhcU5RzkC/BqfrOg7PFd9NS3QKBgQCx6K4iMLX/FhZyrjI//JF7cr6sZ5Q2dzWVXsVhB3px7E3hAam+r1zobAnGbULXf/Q0SPqmJiKw7UKncBzMERp8476T5By7xRVlgLKVAoFcAIsQj+xyQEQ1CBJW+7xI3BXvPd1+iSKAY6SolZ847ImTJepgFBT2pb5SaqUuP3mSkwKBgD0PraHHAjgV+cZb7X+AwsLvmOpgWHCdbohcfHLDr88Qsaz1+n7tqj5inpPsU7/Fa4nt0vfbqTodePG6vNkojR4AjWWUOpZxWpopIbIYNCcG2kx3hXYKII9lheNYbZ4Thw4uCL2OImI8xZeopVwcQc8VjadkORmh2j3WoqU/HN6xAoGAPjujdihN8Z47WgBfaYyjI2i/FDXjXa4Tm12cc9WW2nULxRK82wwi1ta8EKI1yIZk2UlSDH64keVc9I8+M5AkEN3l03vvJSvK0UfUsFVBBPrXqoJ99nVOprJdH/pNIbuDHL4qVdIItJqmhaZZHSN4+HVB6Dv+HU1bJx9RCr1/fGsCgYEAh5l2zfXPPyQ/IkLQxJXKsZdZpuGUtea9+RGnzWuEesoYT7puEx2PAXWidHpDf2SWkMVr4oHYBi8QI2uepORBA6ZJ8I8dW3xILzqfUUISKVjczNFqG7dJPmyaYuWWEYSVkhbXl3NMcX00FdMCCK+R68I10oAGiK/sugqitJ4Uoz4=';
|
|
|
|
|
|
|
|
- static async getOrderInfo(price:number,appName:string): Promise<string> {
|
|
|
|
|
- const keyValues = OrderInfoUtil.buildOrderParamMap(price,appName);
|
|
|
|
|
|
|
+ static async getOrderInfo(price: number, appName: string, userId: number, planId: string): Promise<string> {
|
|
|
|
|
+ const keyValues = OrderInfoUtil.buildOrderParamMap(price, appName, userId, planId);
|
|
|
|
|
+ console.log('Heanup alipay keyValues:'+JSON.stringify(keyValues))
|
|
|
let orderParam = OrderInfoUtil.buildOrderParam(keyValues);
|
|
let orderParam = OrderInfoUtil.buildOrderParam(keyValues);
|
|
|
let sign = await OrderInfoUtil.getSign(keyValues);
|
|
let sign = await OrderInfoUtil.getSign(keyValues);
|
|
|
return orderParam + '&sign=' + sign;
|
|
return orderParam + '&sign=' + sign;
|
|
@@ -33,44 +44,50 @@ export class OrderInfoUtil {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static async getSign(keyValues: Map<string, string>): Promise<string> {
|
|
static async getSign(keyValues: Map<string, string>): Promise<string> {
|
|
|
- let mapEntries = Array.from(keyValues.keys());
|
|
|
|
|
- mapEntries.sort((a, b) => {
|
|
|
|
|
- return a[0].localeCompare(b[0]);
|
|
|
|
|
- });
|
|
|
|
|
- let sortedKeyValues = new Map<string, string>();
|
|
|
|
|
- mapEntries.forEach(entry => {
|
|
|
|
|
- sortedKeyValues.set(entry[0], entry[1]);
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ let mapKeys = Array.from(keyValues.keys());
|
|
|
|
|
+ mapKeys.sort();
|
|
|
let param = '';
|
|
let param = '';
|
|
|
- keyValues.forEach((value, key) => {
|
|
|
|
|
- param += key + '=' + value + '&';
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ for (const key of mapKeys) {
|
|
|
|
|
+ param += `${key}=${keyValues.get(key)}&`;
|
|
|
|
|
+ }
|
|
|
param = param.substring(0, param.length - 1);
|
|
param = param.substring(0, param.length - 1);
|
|
|
let oriSign = await SignUtils.sign(param, OrderInfoUtil.RSA2_PRIVATE);
|
|
let oriSign = await SignUtils.sign(param, OrderInfoUtil.RSA2_PRIVATE);
|
|
|
return encodeURIComponent(oriSign);
|
|
return encodeURIComponent(oriSign);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- static buildOrderParamMap(price:number,appName:string): Map<string, string> {
|
|
|
|
|
|
|
+ static buildOrderParamMap(price: number, appName: string, userId: number, planId: string): Map<string, string> {
|
|
|
const keyValues = new Map<string, string>()
|
|
const keyValues = new Map<string, string>()
|
|
|
|
|
+ const bizContent: BizContent = {} as BizContent;
|
|
|
|
|
+ bizContent.timeout_express = "30m";
|
|
|
|
|
+ bizContent.product_code = "QUICK_MSECURITY_PAY";
|
|
|
|
|
+ bizContent.total_amount = `${price}`;
|
|
|
|
|
+ bizContent.subject = `${appName}`;
|
|
|
|
|
+ bizContent.body = `uid:${userId},planId:${planId}`;
|
|
|
|
|
+ bizContent.out_trade_no = `${OrderInfoUtil.getOutTradeNo(userId, planId)}`;
|
|
|
|
|
+ bizContent.passback_params = encodeURIComponent(`uid=${userId}&plan_id=${planId}`);
|
|
|
|
|
+
|
|
|
keyValues.set('app_id', OrderInfoUtil.APP_ID);
|
|
keyValues.set('app_id', OrderInfoUtil.APP_ID);
|
|
|
- // 不能包含中文,否则加密会有问题。。。。。。。。。。。。
|
|
|
|
|
- keyValues.set('biz_content', `{"timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"${price}","subject":"${appName}","body":"xxx","out_trade_no":"${OrderInfoUtil.getOutTradeNo()}"}`);
|
|
|
|
|
|
|
+ keyValues.set('biz_content', JSON.stringify(bizContent));
|
|
|
OrderInfoUtil.totalAmount = price + 0.01;
|
|
OrderInfoUtil.totalAmount = price + 0.01;
|
|
|
keyValues.set('charset', 'utf-8');
|
|
keyValues.set('charset', 'utf-8');
|
|
|
keyValues.set('method', 'alipay.trade.app.pay');
|
|
keyValues.set('method', 'alipay.trade.app.pay');
|
|
|
keyValues.set('sign_type', 'RSA2');
|
|
keyValues.set('sign_type', 'RSA2');
|
|
|
keyValues.set('timestamp', DateUtil.getTodayStr());
|
|
keyValues.set('timestamp', DateUtil.getTodayStr());
|
|
|
keyValues.set('version', '1.0');
|
|
keyValues.set('version', '1.0');
|
|
|
|
|
+ keyValues.set('notify_url', 'https://pay.ss5.xyz/alipay/notify');
|
|
|
return keyValues;
|
|
return keyValues;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- static getOutTradeNo() {
|
|
|
|
|
- let date = new Date();
|
|
|
|
|
- let key = (date.getMonth().toString() + date.getDate().toString() + date.getHours().toString() + date.getMinutes()
|
|
|
|
|
- .toString() + date.getSeconds().toString()).toString();
|
|
|
|
|
- let r = Math.random() * 10000000;
|
|
|
|
|
- key = key + r;
|
|
|
|
|
- key = key.substring(0, 15);
|
|
|
|
|
- return key;
|
|
|
|
|
|
|
+ static getOutTradeNo(userId: number, planId: string): string {
|
|
|
|
|
+ const date = new Date();
|
|
|
|
|
+ const timeStr = date.getFullYear().toString() +
|
|
|
|
|
+ (date.getMonth() + 1).toString().padStart(2, '0') +
|
|
|
|
|
+ date.getDate().toString().padStart(2, '0') +
|
|
|
|
|
+ date.getHours().toString().padStart(2, '0') +
|
|
|
|
|
+ date.getMinutes().toString().padStart(2, '0') +
|
|
|
|
|
+ date.getSeconds().toString().padStart(2, '0');
|
|
|
|
|
+ const randomStr = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
|
|
|
|
|
+ const tradeNo = `TTM-u${userId}-p${planId}-${timeStr}-${randomStr}`;
|
|
|
|
|
+ return tradeNo.substring(0, 64);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|