Files
sub2apipay/src/lib/order/fee.ts

45 lines
1.7 KiB
TypeScript
Raw Normal View History

import { initPaymentProviders, paymentRegistry } from '@/lib/payment';
import { Prisma } from '@prisma/client';
/**
*
* FEE_RATE_{TYPE} > FEE_RATE_PROVIDER_{KEY} > 0
*/
export function getMethodFeeRate(paymentType: string): number {
// 渠道级别FEE_RATE_ALIPAY / FEE_RATE_WXPAY / FEE_RATE_STRIPE
const methodRaw = process.env[`FEE_RATE_${paymentType.toUpperCase()}`];
if (methodRaw !== undefined && methodRaw !== '') {
const num = Number(methodRaw);
if (Number.isFinite(num) && num >= 0) return num;
}
// 提供商级别FEE_RATE_PROVIDER_EASYPAY / FEE_RATE_PROVIDER_STRIPE
initPaymentProviders();
const providerKey = paymentRegistry.getProviderKey(paymentType);
if (providerKey) {
const providerRaw = process.env[`FEE_RATE_PROVIDER_${providerKey.toUpperCase()}`];
if (providerRaw !== undefined && providerRaw !== '') {
const num = Number(providerRaw);
if (Number.isFinite(num) && num >= 0) return num;
}
}
return 0;
}
/** decimal.js ROUND_UP = 0远离零方向取整 */
const ROUND_UP = 0;
/**
* 使 Decimal
* feeAmount = ceil(rechargeAmount * feeRate / 100, 2)
* payAmount = rechargeAmount + feeAmount
*/
export function calculatePayAmount(rechargeAmount: number, feeRate: number): string {
if (feeRate <= 0) return rechargeAmount.toFixed(2);
const amount = new Prisma.Decimal(rechargeAmount);
const rate = new Prisma.Decimal(feeRate.toString());
const feeAmount = amount.mul(rate).div(100).toDecimalPlaces(2, ROUND_UP);
return amount.plus(feeAmount).toFixed(2);
}