import * as isoly from "isoly" import * as model from "@payfunc/model-card" import { Operation } from "../../Merchant/Operation" //Cost of a transaction export type Transaction = { [scheme in model.Card.Scheme]?: | { debit: { percentage: number minimum?: number } credit: { percentage: number minimum?: number } } | { percentage: number minimum?: number } } export namespace Transaction { export function is(value: any | Transaction): value is Transaction { return ( typeof value == "object" && Object.keys(value).every( scheme => model.Card.Scheme.is(scheme) && (value[scheme] == undefined || (typeof value[scheme] == "object" && typeof value[scheme].percentage == "number" && (value[scheme].minimum == undefined || typeof value[scheme].minimum == "number")) || (typeof value[scheme] == "object" && typeof value[scheme].debit == "object" && typeof value[scheme].debit.percentage == "number" && (value[scheme].debit.minimum == undefined || typeof value[scheme].debit.minimum == "number") && typeof value[scheme].credit == "object" && typeof value[scheme].credit.percentage == "number" && (value[scheme].credit.minimum == undefined || typeof value[scheme].credit.minimum == "number"))) ) ) } export function isUnified(value: any): value is { percentage: number; minimum?: number } { return typeof value == "object" && value.debit == undefined && value.credit == undefined } export function apply( scheme: model.Card.Scheme, card: "debit" | "credit", type: Operation, transaction: Transaction, gross: number, currency: isoly.Currency, rate: number, fixedFee: number ): number { let result: number let feeModel = transaction[scheme] if (!feeModel || type == "authorization" || type == "void") result = 0 else { feeModel = isUnified(feeModel) ? feeModel : feeModel[card] const minimum = isoly.Currency.multiply(currency, feeModel.minimum ?? 0, rate) const fee = Math.abs( isoly.Currency.add(currency, isoly.Currency.multiply(currency, gross, feeModel.percentage / 100), fixedFee) ) result = fee < minimum ? minimum : fee } return result } }