Browse Source

feat: 换汇手续费 3-11

max 4 months ago
parent
commit
e2edf7c2b3
2 changed files with 156 additions and 84 deletions
  1. 24 2
      src/modules/api/service/admin/applications.ts
  2. 132 82
      src/modules/api/service/webhook.ts

+ 24 - 2
src/modules/api/service/admin/applications.ts

@@ -11,7 +11,11 @@ import { OpenAccountEntity } from '../../entity/open_account';
 import { EasyPayAdapter } from '../../../payment/adapter/easypay.adapter';
 import { OpenApplicationsEntity } from '../../entity/open_applications';
 import { Utils } from '../../../../comm/utils';
-import { OrderType, OrderTypeEnum, StatusTypeEnum } from '../../entity/open_payment_order';
+import {
+  OrderType,
+  OrderTypeEnum,
+  StatusTypeEnum,
+} from '../../entity/open_payment_order';
 import * as md5 from 'md5';
 import { PayeeAddressEntity } from '../../../payment/entity/payee_address';
 import { EasyOpenService } from '../open';
@@ -51,7 +55,7 @@ export class applicationsService extends BaseService {
 
   @Inject()
   easyPayAdapter: EasyPayAdapter;
-  
+
   @Inject()
   easyOpenService: EasyOpenService;
 
@@ -219,6 +223,8 @@ export class applicationsService extends BaseService {
   }
   // 付款
   async payments(params) {
+    // 余额 判断是否足以支持交易手续费
+    // 获取指定币种的余额
     /* 
       amount : 12312
       beneficiary_id : 10
@@ -280,4 +286,20 @@ export class applicationsService extends BaseService {
     });
     return merchantInfo;
   }
+
+  // amount 单位为分
+  async getAccountsBalancesByCurrency(account_id, currency) {
+     const balances = await this.easyPayAdapter.request(
+      'GET',
+      `/v3/accounts/${account_id}/balances`,
+      {}
+    );
+    let amount = 0;
+    balances.data.forEach(elm => {
+      if(elm.currency === currency && !amount ) {
+        amount = elm.amount
+      }
+    })
+    return amount
+  }
 }

+ 132 - 82
src/modules/api/service/webhook.ts

@@ -16,6 +16,7 @@ import { OpenAccountEntity } from '../entity/open_account';
 import { EasyPayAdapter } from '../../payment/adapter/easypay.adapter';
 import * as md5 from 'md5';
 import { OpenUserEntity } from '../entity/open_user';
+import { applicationsService } from './admin/applications';
 
 /**
  * 描述
@@ -43,6 +44,9 @@ export class OpenApiWebhookService extends BaseService {
   @Inject()
   paymentService: PaymentService;
 
+  @Inject()
+  applicationsService: applicationsService;
+
   @Inject()
   sunPayAdapter: SunPayAdapter;
 
@@ -206,6 +210,10 @@ export class OpenApiWebhookService extends BaseService {
 
   // 入账成功 的手续费处理
   async deposit_success(params) {
+    // 获取回调用户的详情
+    let accountInfo = null;
+    // 获取回调用户的详情
+    let withdrawChannelFee = null;
     try {
       /*
     2025-03-11 16:58:09.069 INFO 113849 [-/::ffff:127.0.0.1/-/1ms POST /api/open/easypay-webhook/notification] easypay的webhook_notification: params{"type":"deposit_success","data":{"id":"85a2e73b90d94354b14b925c8e23b876","bank_account_id":"7021a5e645574004b5678213f94df8a5","order_no":"20250311165807046795","account_id":"590f080eb299590385c7aa628274e73c","bic_number":null,"account_number":"79765000168","inward_amount":90000,"fee":0,"amount":90000,"currency":"EUR","payer":"付款信息 格式:{sender.name};{sender.address};{sender.country};{sender.account_number} or {sender.iban};{sender.bic};{sender.routing_code};附言","comment":"附言","payment_type":"SWIFT","order_type":"DEPOSIT","payment_id":null,"clearing_system":null,"status":"SUCCESS","create_time":"2025-03-11T16:58:08+08:00","update_time":"2025-03-11T16:58:08+08:00","completed_time":"2025-03-11T16:58:08+08:00"}}
@@ -237,7 +245,7 @@ export class OpenApiWebhookService extends BaseService {
     }
     */
       // 获取回调用户的详情
-      const accountInfo = await this.getAccountInfo(params.data.account_id);
+      accountInfo = await this.getAccountInfo(params.data.account_id);
       if (!accountInfo) {
         // TODO 如果不存在的话,则为白标用户
         // 转账延迟4秒处理
@@ -248,7 +256,7 @@ export class OpenApiWebhookService extends BaseService {
       }
 
       // 获取费率信息
-      const withdrawChannelFee = await this.getWithdrawChannelFee({
+      withdrawChannelFee = await this.getWithdrawChannelFee({
         account_id: params.data.account_id,
         currency: params.data.currency,
         order_type: 'DEPOSIT',
@@ -258,6 +266,12 @@ export class OpenApiWebhookService extends BaseService {
       });
       // 查询用户的资金
 
+      // 获取余额
+      const { before_balance, balance } = await this.getBalanceDiffByCurrency({
+        account_id: params.data.account_id,
+        currency: params.data.currency,
+        amount: params.data.amount,
+      });
       // 记录入账流水
       const openPaymentOrderParams = {
         mch_id: accountInfo.mch_id,
@@ -273,50 +287,61 @@ export class OpenApiWebhookService extends BaseService {
         order_id: params.data.order_no,
         fee: withdrawChannelFee,
         additional_info: {},
+        before_balance: before_balance / 100,
+        balance: balance / 100,
       };
       await this.openPaymentOrderEntity.insert(openPaymentOrderParams);
       this.logger.info(
         `记录入账流水, ${JSON.stringify(openPaymentOrderParams)}`
       );
-      // 收取手续费: 转账
-      // /v1/transfers
-      const transfers_params = {
-        // ...openOrderObj,
-        request_id: md5(`${accountInfo.mch_id}_${params.data.id}`),
-        from_account_id: params.data.account_id,
-        to_account_id: this.easyPayAdapter.baseInfo.account_id,
-        currency: params.data.currency,
-        amount: withdrawChannelFee * 100,
-        purpose: '收取手续费用',
-      };
-      this.logger.info(
-        `记录入账流水的费率, ${JSON.stringify(transfers_params)}`
-      );
-      // 截取流水的转账
-      const res = await this.easyPayAdapter.request(
-        'POST',
-        '/v1/transfers',
-        transfers_params
-      );
-      // 记录入账手续费的流水
-      await this.openPaymentOrderEntity.insert({
-        request_id: transfers_params.request_id,
-        mch_id: accountInfo.mch_id,
-        amount: withdrawChannelFee,
-        account_id: params.data.account_id,
-        from_account_id: params.data.account_id,
-        to_account_id: this.easyPayAdapter.baseInfo.account_id,
-        event_id: params.data.id,
-        currency: params.data.currency,
-        status: params.data.status,
-        order_type: OrderType.TRANSACTION_FEE_ORDER,
-        payment_type: params.data.payment_type,
-        order_id: res.data.order_no, // 这里是转账的订单编号
-        fee: 0,
-        additional_info: {},
-      });
       this.ctx.status = 200;
       this.ctx.body = {};
+      // 通知上游之后,间隔10秒执行利润截取操作
+      Promise.resolve().then(async () => {
+        await this.waitByTime(10000);
+        let accountInfo = null;
+        // 获取回调用户的详情
+        let withdrawChannelFee = null;
+        if (accountInfo && withdrawChannelFee) {
+          // 收取手续费: 转账
+          // /v1/transfers
+          const transfers_params = {
+            // ...openOrderObj,
+            request_id: md5(`${accountInfo.mch_id}_${params.data.id}`),
+            from_account_id: params.data.account_id,
+            to_account_id: this.easyPayAdapter.baseInfo.account_id,
+            currency: params.data.currency,
+            amount: withdrawChannelFee * 100,
+            purpose: '收取手续费用',
+          };
+          this.logger.info(
+            `记录入账流水的费率, ${JSON.stringify(transfers_params)}`
+          );
+          // 截取流水的转账
+          const res = await this.easyPayAdapter.request(
+            'POST',
+            '/v1/transfers',
+            transfers_params
+          );
+          // 记录入账手续费的流水
+          await this.openPaymentOrderEntity.insert({
+            request_id: transfers_params.request_id,
+            mch_id: accountInfo.mch_id,
+            amount: withdrawChannelFee,
+            account_id: params.data.account_id,
+            from_account_id: params.data.account_id,
+            to_account_id: this.easyPayAdapter.baseInfo.account_id,
+            event_id: params.data.id,
+            currency: params.data.currency,
+            status: params.data.status,
+            order_type: OrderType.TRANSACTION_FEE_ORDER,
+            payment_type: params.data.payment_type,
+            order_id: res.data.order_no, // 这里是转账的订单编号
+            fee: 0,
+            additional_info: {},
+          });
+        }
+      });
       return;
     } catch (error) {
       this.logger.error(`记录入账流水失败, ${JSON.stringify(params)}`);
@@ -376,6 +401,13 @@ export class OpenApiWebhookService extends BaseService {
         mch_id: accountInfo.mch_id,
       });
 
+      // 获取余额
+      const { before_balance, balance } = await this.getBalanceDiffByCurrency({
+        account_id: params.data.account_id,
+        currency: params.data.buy_currency,
+        amount: params.data.buy_amount,
+      });
+
       // 记录入账流水
       const openPaymentOrderParams = {
         mch_id: accountInfo.mch_id,
@@ -393,49 +425,54 @@ export class OpenApiWebhookService extends BaseService {
         order_id: params.data.order_no,
         fee: withdrawChannelFee,
         additional_info: {},
+        before_balance: before_balance / 100,
+        balance: balance / 100,
       };
       await this.openPaymentOrderEntity.insert(openPaymentOrderParams);
       this.logger.info(
         `记录换汇流水, ${JSON.stringify(openPaymentOrderParams)}`
       );
-
-      // 收取手续费: 换汇
-      // /v1/transfers
-      const transfers_params = {
-        request_id: md5(`${accountInfo.mch_id}_${params.data.id}`),
-        from_account_id: params.data.account_id,
-        to_account_id: this.easyPayAdapter.baseInfo.account_id,
-        currency: params.data.buy_currency, // 收取买入的币种费用
-        target_amount: params.data.buy_amount / 100,
-        amount: withdrawChannelFee * 100, // 分
-        purpose: '收取手续费用',
-      };
-      this.logger.info(
-        `记录入账流水的费率, ${JSON.stringify(transfers_params)}`
-      );
-      // 截取流水的转账
-      const res = await this.easyPayAdapter.request(
-        'POST',
-        '/v1/transfers',
-        transfers_params
-      );
-      // 记录入账手续费的流水
-      await this.openPaymentOrderEntity.insert({
-        request_id: transfers_params.request_id,
-        mch_id: accountInfo.mch_id,
-        amount: withdrawChannelFee,
-        account_id: params.data.account_id,
-        from_account_id: params.data.account_id,
-        to_account_id: this.easyPayAdapter.baseInfo.account_id,
-        event_id: params.data.id,
-        currency: transfers_params.currency,
-        status: params.data.status,
-        order_type: OrderType.TRANSACTION_FEE_ORDER,
-        payment_type: params.data.payment_type,
-        order_id: res.data.order_no, // 这里是转账的订单编号
-        fee: 0,
-        additional_info: {},
-      });
+      // 通知上游之后,间隔10秒执行利润截取操作
+      Promise.resolve().then(async () => {
+        await this.waitByTime(10000);
+        //  收取手续费: 换汇
+        // /v1/transfers
+        const transfers_params = {
+          request_id: md5(`${accountInfo.mch_id}_${params.data.id}`),
+          from_account_id: params.data.account_id,
+          to_account_id: this.easyPayAdapter.baseInfo.account_id,
+          currency: params.data.buy_currency, // 收取买入的币种费用
+          target_amount: params.data.buy_amount / 100,
+          amount: withdrawChannelFee * 100, // 分
+          purpose: '收取手续费用',
+        };
+        this.logger.info(
+          `记录入账流水的费率, ${JSON.stringify(transfers_params)}`
+        );
+        // 截取流水的转账
+        const res = await this.easyPayAdapter.request(
+          'POST',
+          '/v1/transfers',
+          transfers_params
+        );
+        // 记录入账手续费的流水
+        await this.openPaymentOrderEntity.insert({
+          request_id: transfers_params.request_id,
+          mch_id: accountInfo.mch_id,
+          amount: withdrawChannelFee,
+          account_id: params.data.account_id,
+          from_account_id: params.data.account_id,
+          to_account_id: this.easyPayAdapter.baseInfo.account_id,
+          event_id: params.data.id,
+          currency: transfers_params.currency,
+          status: params.data.status,
+          order_type: OrderType.TRANSACTION_FEE_ORDER,
+          payment_type: params.data.payment_type,
+          order_id: res.data.order_no, // 这里是转账的订单编号
+          fee: 0,
+          additional_info: {},
+        });
+      })
       this.ctx.status = 200;
       this.ctx.body = {};
       return;
@@ -452,18 +489,18 @@ export class OpenApiWebhookService extends BaseService {
         account_id,
       },
     });
-    if(openAccount) {
-      return openAccount
+    if (openAccount) {
+      return openAccount;
     }
     const openUser = await this.openUserEntity.findOne({
       where: {
         account_id,
       },
     });
-    if(openUser) {
-      return openUser
+    if (openUser) {
+      return openUser;
     }
-    return null
+    return null;
   }
 
   async getWithdrawChannelFee({
@@ -492,4 +529,17 @@ export class OpenApiWebhookService extends BaseService {
     const feeMin = withdrawChannel.feeMin;
     return Math.max(fee, basicFee, feeMin); // 取最大值
   }
+  // 获取流水记录前后的余额差异
+
+  async getBalanceDiffByCurrency({ account_id, currency, amount }) {
+    const userBalance =
+      await this.applicationsService.getAccountsBalancesByCurrency(
+        account_id,
+        currency
+      );
+    return {
+      before_balance: userBalance,
+      balance: userBalance + amount,
+    };
+  }
 }