Эх сурвалжийг харах

集成会员中心:微信支付、支付宝支付自动添加会员时长

chendeben 1 жил өмнө
parent
commit
14409e7255

+ 41 - 24
entry/src/main/ets/alipay/OrderInfoUtil.ets

@@ -1,6 +1,16 @@
 import { DateUtil } from '@pura/harmony-utils';
 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 {
   static readonly APP_ID = '2019091067184257';//七梦支付宝appid
   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 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 sign = await OrderInfoUtil.getSign(keyValues);
     return orderParam + '&sign=' + sign;
@@ -33,44 +44,50 @@ export class OrderInfoUtil {
   }
 
   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 = '';
-    keyValues.forEach((value, key) => {
-      param += key + '=' + value + '&';
-    });
+    for (const key of mapKeys) {
+      param += `${key}=${keyValues.get(key)}&`;
+    }
     param = param.substring(0, param.length - 1);
     let oriSign = await SignUtils.sign(param, OrderInfoUtil.RSA2_PRIVATE);
     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 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('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;
     keyValues.set('charset', 'utf-8');
     keyValues.set('method', 'alipay.trade.app.pay');
     keyValues.set('sign_type', 'RSA2');
     keyValues.set('timestamp', DateUtil.getTodayStr());
     keyValues.set('version', '1.0');
+    keyValues.set('notify_url', 'https://pay.ss5.xyz/alipay/notify');
     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);
   }
 }

+ 7 - 3
entry/src/main/ets/pages/UserCenter.ets

@@ -18,6 +18,7 @@ import { RandomUtil, Base64Util } from '@pura/harmony-utils';
 import { CommonConstants } from '../common/constants/CommonConstants';
 import { PayReq } from '@tencent/wechat_open_sdk';
 import { cryptoFramework } from '@kit.CryptoArchitectureKit';
+import json from '@ohos.util.json';
 
 
 interface WechatUserInfo {
@@ -268,7 +269,8 @@ export struct UserCenter {
         // 微信支付成功回调
         ToastUtil.showToast('支付成功!');
         // 可在此处刷新会员状态或其他支付成功后的业务逻辑
-        this.fetchVipPlans(); // 刷新会员套餐信息
+        // this.fetchVipPlans(); // 刷新会员套餐信息
+        void this.fetchUserInfo(this.userToken);
       } else {
         // 其他类型的成功回调
         ToastUtil.showToast('操作成功!');
@@ -694,7 +696,7 @@ export struct UserCenter {
         // 跳转到历史记录页面
       })
       Line().width('90%').height(0.5).backgroundColor(0xFFEFEFEF)
-      this.menuItem($r('app.media.setting'), '设置', () => {
+      this.menuItem($r('app.media.setting_red'), '设置', () => {
         // 跳转到设置页面
       })
     }
@@ -926,10 +928,12 @@ export struct UserCenter {
 
   async doAliPay(plan: VipPlanApi) {
     const appName = PreferencesUtil.getStringSync('appName', 'TTMusic');
-    OrderInfoUtil.getOrderInfo(Number(plan.price), appName).then((orderInfo) => {
+    OrderInfoUtil.getOrderInfo(Number(plan.price), appName, this.userId, plan.id).then((orderInfo) => {
+      console.log('Heanup: alipay orderInfo = '+json.stringify(orderInfo))
       new Pay().pay(orderInfo, true).then(async (result) => {
         if (result.get('resultStatus') === '9000') {
           ToastUtil.showToast('支付成功!');
+          void this.fetchUserInfo(this.userToken);
           // 可在此处刷新会员状态
         } else {
           ToastUtil.showToast('取消支付!');

+ 1 - 1
entry/src/main/ets/pages/VipPage.ets

@@ -638,7 +638,7 @@ export  struct  VipPage{
       *
       * orderInfo 的获取必须来自服务端;
       */
-    OrderInfoUtil.getOrderInfo(this.payPrice,this.appName).then((orderInfo) => {
+    OrderInfoUtil.getOrderInfo(this.payPrice,this.appName,0,"0").then((orderInfo) => {
       new Pay().pay(orderInfo, true).then(async (result) => {
         let message =
           `resultStatus: ${result.get('resultStatus')} memo: ${result.get('memo')} result: ${result.get('result')}`;

+ 1 - 1
entry/src/main/ets/viewmodel/MainViewModel.ets

@@ -67,7 +67,7 @@ export  class  MainViewModel{
   getDrawerData2(): Array<ItemData> {
     let drawerGridData: ItemData[] = [
       new ItemData($r('app.string.local_music'), { type: 'symbol', value: $r('sys.symbol.music') }, MainViewModel.MENU_MUSIC, false),
-      // new ItemData($r('app.string.user_center'), { type: 'symbol', value: $r('sys.symbol.person') }, MainViewModel.MENU_USER, false),
+      new ItemData($r('app.string.user_center'), { type: 'symbol', value: $r('sys.symbol.person') }, MainViewModel.MENU_USER, false),
       new ItemData($r('app.string.file_scan'), { type: 'symbol', value: $r('sys.symbol.doc_text_badge_magnifyingglass') },MainViewModel.MENU_FILE_SCAN,false),
       new ItemData($r('app.string.vip'), { type: 'symbol', value: $r('sys.symbol.vip_hand') }, MainViewModel.MENU_VIP, false),
       new ItemData($r('app.string.haoping'), { type: 'symbol', value: $r('sys.symbol.flower') },MainViewModel.MENU_HAOPING,false),