import * as gracely from "gracely" import * as isoly from "isoly" import * as selectively from "selectively" import * as model from "@payfunc/model-card" import { Authorization } from "../Authorization" import { Settlement } from "../Settlement" import { Base as MerchantBase } from "./Base" import { Creatable as MerchantCreatable } from "./Creatable" import { Fee as MerchantFee } from "./Fee" import { Operation as MerchantOperation } from "./Operation" import { Processor as MerchantProcessor } from "./Processor" import { Reconciliation as MerchantReconciliation } from "./Reconciliation" import { Risk as MerchantRisk } from "./Risk" import { Rule as MerchantRule } from "./Rule" import { Rules as MerchantRules } from "./Rules" export interface Merchant extends MerchantBase { agent: string created?: isoly.Date processor: MerchantProcessor | { visa: MerchantProcessor; mastercard: MerchantProcessor } risk?: MerchantRisk } export namespace Merchant { export function is(value: any | Merchant): value is Merchant { return ( value && typeof value == "object" && typeof value.agent == "string" && (value.created == undefined || isoly.Date.is(value.created)) && (MerchantProcessor.is(value.processor) || (typeof value.processor == "object" && value.processor && MerchantProcessor.is(value.processor.visa) && MerchantProcessor.is(value.processor.mastercard))) && (value.risk == undefined || MerchantRisk.is(value.risk)) && MerchantBase.is(value) ) } export function flaw(value: any | Merchant): gracely.Flaw { return { type: "Merchant", flaws: typeof value != "object" || !value ? undefined : ([ ...(Base.flaw(value).flaws ?? []), typeof value.agent == "string" || { property: "agent", type: "string" }, value.created == undefined || isoly.Date.is(value.created) || { property: "created", type: "isoly.Date | undefined", }, MerchantProcessor.is(value.processor) || (typeof value.processor == "object" && value.processor && MerchantProcessor.is(value.processor.visa) && MerchantProcessor.is(value.processor.mastercard)) || { property: "processor", type: "Processor | { visa: Processor; mastercard: Processor } ", }, Risk.is(value.risk) || { property: "risk", type: "object" }, ].filter(gracely.Flaw.is) as gracely.Flaw[]), } } export function getDescriptor(merchant: Merchant | Merchant.Creatable): string | undefined { return typeof merchant.descriptor == "object" ? merchant.descriptor.statement : merchant.descriptor } export function getReference( merchant: Merchant | Merchant.Creatable, processor: Settlement.Processor | Authorization.Processor.Name, scheme?: "visa" | "mastercard" ): string | undefined { let result: string | undefined const merchantProcessor = getProcessor(merchant, scheme) switch (processor) { case "omnipay": case "ipg": result = merchantProcessor?.ipg?.reference break case "silverflow": result = merchantProcessor?.silverflow?.reference break case "baboba": result = merchantProcessor?.baboba?.reference break case "clearhaus": result = merchantProcessor?.clearhaus?.reference break default: result = undefined break } return result } export function getProcessor( merchant: Merchant | Merchant.Creatable, scheme?: model.Card.Scheme ): MerchantProcessor | undefined { return ( (scheme == "mastercard" || scheme == "visa" ? getSchemeProcessor(merchant, scheme) : undefined) ?? (MerchantProcessor.is(merchant.processor) ? merchant.processor : undefined) ) } function getSchemeProcessor( merchant: Merchant | Merchant.Creatable, scheme: "visa" | "mastercard" ): MerchantProcessor | undefined { let result: MerchantProcessor | undefined if (merchant.processor == "baboba") result = undefined else if (merchant.processor && ("visa" in merchant.processor || "mastercard" in merchant.processor)) result = merchant.processor[scheme] return result } export function getProcessorName( merchant: Merchant | Merchant.Creatable, scheme?: model.Card.Scheme ): Authorization.Processor.Name | undefined { const processor = !scheme || scheme == "mastercard" || scheme == "visa" ? Merchant.getProcessor(merchant, scheme) : undefined return merchant.processor == "baboba" || processor?.baboba ? "baboba" : processor?.silverflow ? "silverflow" : processor?.ipg || !processor ? "ipg" : processor?.clearhaus ? "clearhaus" : undefined } export function toCsv(merchants: Merchant[]): string { let result = "" result += "id," result += "name," result += "mid," result += "mcc," result += "country," result += "reference," result += "currency," result += "\r\n" for (const merchant of merchants) { const processorName = getProcessorName(merchant) const reference = processorName ? getReference(merchant, processorName) : undefined result += `"${merchant.id}",` result += `"${merchant.name}",` result += `"${(processorName == "ipg" ? "8103" : "") + reference}",` result += `"${merchant.categoryCode}",` result += `"${merchant.country}",` result += `"${reference}",` result += `"${merchant.currency}",` result += `\r\n` } return result } export const template = new selectively.Type.Object({ id: new selectively.Type.String(), number: new selectively.Type.String(), type: new selectively.Type.Union([new selectively.Type.String("test"), new selectively.Type.String("live")]), agent: new selectively.Type.String(), descriptor: new selectively.Type.String(), name: new selectively.Type.String(), currency: new selectively.Type.Union(isoly.Currency.types.map(c => new selectively.Type.String(c))), reconciliation: MerchantReconciliation.template, country: new selectively.Type.Union(isoly.CountryCode.Alpha2.types.map(c => new selectively.Type.String(c))), categoryCode: new selectively.Type.String(), storage: new selectively.Type.Union(["cosmos", "cloudly"].map(c => new selectively.Type.String(c))), created: new selectively.Type.String(), }) export type Base = MerchantBase export namespace Base { export const from = MerchantBase.from export const flaw = MerchantBase.flaw } export type Creatable = MerchantCreatable export namespace Creatable { export const is = MerchantCreatable.is export const flaw = MerchantCreatable.flaw } export type Operation = MerchantOperation export namespace Operation { export const is = MerchantOperation.is export const types = MerchantOperation.types } export type Fee = MerchantFee export namespace Fee { export const is = MerchantFee.is export const apply = MerchantFee.apply export type Transaction = MerchantFee.Transaction export namespace Transaction { export const is = MerchantFee.Transaction.is export const isUnified = MerchantFee.Transaction.isUnified export const apply = MerchantFee.Transaction.apply } } export type Rules = MerchantRules export namespace Rules { export const is = MerchantRules.is export const flaw = MerchantRules.flaw export const apply = MerchantRules.apply export const parse = MerchantRules.parse } export namespace Risk { export type Risk = MerchantRisk export const is = MerchantRisk.is } export type Rule = MerchantRule export namespace Rule { export const is = MerchantRule.is export const apply = MerchantRule.apply export const parse = MerchantRule.parse export const stringify = MerchantRule.stringify export const toFlaw = MerchantRule.toFlaw } export type Reconciliation = MerchantReconciliation export namespace Reconciliation { export const is = MerchantReconciliation.is export const flaw = MerchantReconciliation.flaw export type Transaction = MerchantReconciliation.Transaction export type Account = MerchantReconciliation.Account export namespace Transaction { export const is = MerchantReconciliation.Transaction.is export const toCsv = MerchantReconciliation.Transaction.toCsv } export namespace Account { export const is = MerchantReconciliation.Account.is } } export type Processor = MerchantProcessor export namespace Processor { export type Acceptor = MerchantProcessor.Acceptor export namespace Acceptor { export const is = MerchantProcessor.Acceptor.is export const flaw = MerchantProcessor.Acceptor.flaw } export type Configuration = MerchantProcessor.Configuration export namespace Configuration { export const is = MerchantProcessor.Configuration.is export const flaw = MerchantProcessor.Configuration.flaw } } }