@pax2pay/model-banking 0.1.567 → 0.1.569

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/Account/Charge/Fx/index.ts +29 -0
  2. package/Account/Charge/Merchant/index.ts +42 -0
  3. package/Account/Charge/Preset/index.ts +15 -0
  4. package/Account/Charge/index.ts +13 -40
  5. package/Account/index.ts +2 -2
  6. package/Authorization/index.ts +2 -4
  7. package/Card/Restriction/Merchant.ts +9 -0
  8. package/Client/Accounts/Charge.ts +2 -6
  9. package/Rule/State/Authorization.ts +2 -3
  10. package/Settlement/Entry/index.ts +4 -4
  11. package/Transaction/Amount/Charge/index.ts +86 -0
  12. package/Transaction/{Amount.ts → Amount/index.ts} +13 -21
  13. package/Transaction/Creatable.ts +2 -2
  14. package/Transaction/Exchange.ts +6 -2
  15. package/Transaction/index.ts +3 -3
  16. package/dist/cjs/Account/Charge/Fx/index.d.ts +10 -0
  17. package/dist/cjs/Account/Charge/Fx/index.js +23 -0
  18. package/dist/cjs/Account/Charge/Fx/index.js.map +1 -0
  19. package/dist/cjs/Account/Charge/Merchant/index.d.ts +15 -0
  20. package/dist/cjs/Account/Charge/Merchant/index.js +34 -0
  21. package/dist/cjs/Account/Charge/Merchant/index.js.map +1 -0
  22. package/dist/cjs/Account/Charge/Preset/index.d.ts +8 -0
  23. package/dist/cjs/Account/Charge/Preset/index.js +15 -0
  24. package/dist/cjs/Account/Charge/Preset/index.js.map +1 -0
  25. package/dist/cjs/Account/Charge/index.d.ts +10 -18
  26. package/dist/cjs/Account/Charge/index.js +11 -33
  27. package/dist/cjs/Account/Charge/index.js.map +1 -1
  28. package/dist/cjs/Account/index.d.ts +1 -1
  29. package/dist/cjs/Account/index.js +1 -1
  30. package/dist/cjs/Account/index.js.map +1 -1
  31. package/dist/cjs/Authorization/index.d.ts +1 -3
  32. package/dist/cjs/Authorization/index.js +1 -3
  33. package/dist/cjs/Authorization/index.js.map +1 -1
  34. package/dist/cjs/Card/Restriction/Merchant.d.ts +1 -0
  35. package/dist/cjs/Card/Restriction/Merchant.js +10 -0
  36. package/dist/cjs/Card/Restriction/Merchant.js.map +1 -1
  37. package/dist/cjs/Client/Accounts/Charge.d.ts +2 -2
  38. package/dist/cjs/Client/Accounts/Charge.js.map +1 -1
  39. package/dist/cjs/Client/Transactions/index.d.ts +1 -1
  40. package/dist/cjs/Rail/index.d.ts +2 -2
  41. package/dist/cjs/Rule/State/Authorization.d.ts +1 -2
  42. package/dist/cjs/Rule/State/Authorization.js +1 -2
  43. package/dist/cjs/Rule/State/Authorization.js.map +1 -1
  44. package/dist/cjs/Settlement/Entry/index.d.ts +1 -1
  45. package/dist/cjs/Settlement/Entry/index.js +2 -2
  46. package/dist/cjs/Settlement/Entry/index.js.map +1 -1
  47. package/dist/cjs/Transaction/Amount/Charge/index.d.ts +39 -0
  48. package/dist/cjs/Transaction/Amount/Charge/index.js +58 -0
  49. package/dist/cjs/Transaction/Amount/Charge/index.js.map +1 -0
  50. package/dist/cjs/Transaction/Amount/index.d.ts +17 -0
  51. package/dist/cjs/Transaction/{Amount.js → Amount/index.js} +6 -17
  52. package/dist/cjs/Transaction/Amount/index.js.map +1 -0
  53. package/dist/cjs/Transaction/Creatable.d.ts +1 -1
  54. package/dist/cjs/Transaction/Creatable.js +2 -2
  55. package/dist/cjs/Transaction/Creatable.js.map +1 -1
  56. package/dist/cjs/Transaction/Exchange.d.ts +3 -1
  57. package/dist/cjs/Transaction/Exchange.js +3 -1
  58. package/dist/cjs/Transaction/Exchange.js.map +1 -1
  59. package/dist/cjs/Transaction/index.d.ts +2 -2
  60. package/dist/cjs/Transaction/index.js.map +1 -1
  61. package/dist/mjs/Account/Charge/Fx/index.d.ts +10 -0
  62. package/dist/mjs/Account/Charge/Fx/index.js +20 -0
  63. package/dist/mjs/Account/Charge/Fx/index.js.map +1 -0
  64. package/dist/mjs/Account/Charge/Merchant/index.d.ts +15 -0
  65. package/dist/mjs/Account/Charge/Merchant/index.js +31 -0
  66. package/dist/mjs/Account/Charge/Merchant/index.js.map +1 -0
  67. package/dist/mjs/Account/Charge/Preset/index.d.ts +8 -0
  68. package/dist/mjs/Account/Charge/Preset/index.js +12 -0
  69. package/dist/mjs/Account/Charge/Preset/index.js.map +1 -0
  70. package/dist/mjs/Account/Charge/index.d.ts +10 -18
  71. package/dist/mjs/Account/Charge/index.js +11 -33
  72. package/dist/mjs/Account/Charge/index.js.map +1 -1
  73. package/dist/mjs/Account/index.d.ts +1 -1
  74. package/dist/mjs/Account/index.js +1 -1
  75. package/dist/mjs/Account/index.js.map +1 -1
  76. package/dist/mjs/Authorization/index.d.ts +1 -3
  77. package/dist/mjs/Authorization/index.js +1 -3
  78. package/dist/mjs/Authorization/index.js.map +1 -1
  79. package/dist/mjs/Card/Restriction/Merchant.d.ts +1 -0
  80. package/dist/mjs/Card/Restriction/Merchant.js +10 -0
  81. package/dist/mjs/Card/Restriction/Merchant.js.map +1 -1
  82. package/dist/mjs/Client/Accounts/Charge.d.ts +2 -2
  83. package/dist/mjs/Client/Accounts/Charge.js.map +1 -1
  84. package/dist/mjs/Client/Transactions/index.d.ts +1 -1
  85. package/dist/mjs/Rail/index.d.ts +2 -2
  86. package/dist/mjs/Rule/State/Authorization.d.ts +1 -2
  87. package/dist/mjs/Rule/State/Authorization.js +1 -2
  88. package/dist/mjs/Rule/State/Authorization.js.map +1 -1
  89. package/dist/mjs/Settlement/Entry/index.d.ts +1 -1
  90. package/dist/mjs/Settlement/Entry/index.js +2 -2
  91. package/dist/mjs/Settlement/Entry/index.js.map +1 -1
  92. package/dist/mjs/Transaction/Amount/Charge/index.d.ts +39 -0
  93. package/dist/mjs/Transaction/Amount/Charge/index.js +55 -0
  94. package/dist/mjs/Transaction/Amount/Charge/index.js.map +1 -0
  95. package/dist/mjs/Transaction/Amount/index.d.ts +17 -0
  96. package/dist/mjs/Transaction/{Amount.js → Amount/index.js} +6 -17
  97. package/dist/mjs/Transaction/Amount/index.js.map +1 -0
  98. package/dist/mjs/Transaction/Creatable.d.ts +1 -1
  99. package/dist/mjs/Transaction/Creatable.js +2 -2
  100. package/dist/mjs/Transaction/Creatable.js.map +1 -1
  101. package/dist/mjs/Transaction/Exchange.d.ts +3 -1
  102. package/dist/mjs/Transaction/Exchange.js +3 -1
  103. package/dist/mjs/Transaction/Exchange.js.map +1 -1
  104. package/dist/mjs/Transaction/index.d.ts +2 -2
  105. package/dist/mjs/Transaction/index.js.map +1 -1
  106. package/package.json +1 -1
  107. package/Account/Charge/Applies.ts +0 -53
  108. package/Authorization/Exchange.ts +0 -13
  109. package/dist/cjs/Account/Charge/Applies.d.ts +0 -23
  110. package/dist/cjs/Account/Charge/Applies.js +0 -44
  111. package/dist/cjs/Account/Charge/Applies.js.map +0 -1
  112. package/dist/cjs/Authorization/Exchange.d.ts +0 -8
  113. package/dist/cjs/Authorization/Exchange.js +0 -13
  114. package/dist/cjs/Authorization/Exchange.js.map +0 -1
  115. package/dist/cjs/Transaction/Amount.d.ts +0 -24
  116. package/dist/cjs/Transaction/Amount.js.map +0 -1
  117. package/dist/mjs/Account/Charge/Applies.d.ts +0 -23
  118. package/dist/mjs/Account/Charge/Applies.js +0 -41
  119. package/dist/mjs/Account/Charge/Applies.js.map +0 -1
  120. package/dist/mjs/Authorization/Exchange.d.ts +0 -8
  121. package/dist/mjs/Authorization/Exchange.js +0 -10
  122. package/dist/mjs/Authorization/Exchange.js.map +0 -1
  123. package/dist/mjs/Transaction/Amount.d.ts +0 -24
  124. package/dist/mjs/Transaction/Amount.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ import { isoly } from "isoly"
2
+ import { Card } from "../../../Card"
3
+ import { Amount } from "../../../Transaction/Amount"
4
+ import { Exchange } from "../../../Transaction/Exchange"
5
+ import { Preset } from "../Preset"
6
+
7
+ export type Fx = Preset
8
+
9
+ export namespace Fx {
10
+ export const type = Preset.type
11
+ export function evaluate(
12
+ charge: Fx,
13
+ currency: isoly.Currency,
14
+ amount: number,
15
+ preset?: Card.Preset,
16
+ exchange?: Exchange
17
+ ): Amount.Charge.Fx | undefined {
18
+ let result: Amount.Charge.Fx | undefined
19
+ const chargePreset = preset && charge[preset] ? preset : "default"
20
+ const chargeRate = charge[chargePreset] ?? 0
21
+ if (exchange)
22
+ result = {
23
+ preset: chargePreset,
24
+ rate: chargeRate,
25
+ amount: -isoly.Currency.multiply(currency, amount, chargeRate),
26
+ }
27
+ return result
28
+ }
29
+ }
@@ -0,0 +1,42 @@
1
+ import { isoly } from "isoly"
2
+ import { isly } from "isly"
3
+ import { Card } from "../../../Card"
4
+ import { Rail } from "../../../Rail"
5
+ import { Amount } from "../../../Transaction/Amount"
6
+ import { Preset } from "../Preset"
7
+
8
+ export interface Merchant {
9
+ destination: { account: string }
10
+ merchants: Partial<Record<Card.Restriction.Merchant, Preset>>
11
+ }
12
+ export namespace Merchant {
13
+ export const type = isly.object<Merchant>({
14
+ destination: isly.object({
15
+ account: isly.string(),
16
+ }),
17
+ merchants: isly.record<Card.Restriction.Merchant, Preset>(Card.Restriction.Merchant.type, Preset.type),
18
+ })
19
+
20
+ export function evaluate(
21
+ charge: Merchant,
22
+ currency: isoly.Currency,
23
+ amount: number,
24
+ counterpart: Rail.Address.Card.Counterpart,
25
+ preset?: Card.Preset
26
+ ): Amount.Charge.Merchant | undefined {
27
+ let result: Amount.Charge.Merchant | undefined
28
+ const merchant = Card.Restriction.Merchant.resolve(counterpart)
29
+ if (merchant) {
30
+ const chargePreset = preset && charge.merchants?.[merchant]?.[preset] ? preset : "default"
31
+ const chargeRate = charge.merchants?.[merchant]?.[chargePreset] ?? 0
32
+ result = {
33
+ merchant,
34
+ preset: chargePreset,
35
+ destination: charge.destination,
36
+ rate: chargeRate,
37
+ amount: -isoly.Currency.multiply(currency, amount, chargeRate),
38
+ }
39
+ }
40
+ return result
41
+ }
42
+ }
@@ -0,0 +1,15 @@
1
+ import { isly } from "isly"
2
+ import { Card } from "../../../Card"
3
+
4
+ export type Preset = Partial<Record<Card.Preset, number>> & {
5
+ default: number
6
+ }
7
+
8
+ export namespace Preset {
9
+ const recordType = isly.record<Preset>(isly.string(Card.Preset.names), isly.number())
10
+ const defaultType = isly.object<{ default: number }>({ default: isly.number() })
11
+ function is(value: unknown): value is Preset {
12
+ return defaultType.is(value) && recordType.is((({ default: _, ...rest }) => rest)(value))
13
+ }
14
+ export const type = isly.fromIs("Preset", is)
15
+ }
@@ -1,58 +1,31 @@
1
- import { cryptly } from "cryptly"
2
1
  import { isoly } from "isoly"
3
2
  import { isly } from "isly"
4
3
  import type { Card } from "../../Card"
5
4
  import type { Rail } from "../../Rail"
6
5
  import type { Transaction } from "../../Transaction"
7
- import { Applies } from "./Applies"
6
+ import { Fx as ChargeFx } from "./Fx"
7
+ import { Merchant as ChargeMerchant } from "./Merchant"
8
8
 
9
- export interface Charge extends Charge.Creatable {
10
- id: string
11
- }
9
+ export type Charge = { merchant?: Charge.Merchant; fx?: Charge.Fx }
12
10
  export namespace Charge {
13
- export interface Creatable {
14
- destination: { account: string }
15
- rate: number // rate: 0.01 for 1%
16
- applies: Applies
17
- }
18
- export namespace Creatable {
19
- export const type = isly.object<Creatable>({
20
- destination: isly.object({ account: isly.string() }),
21
- rate: isly.number(),
22
- applies: Applies.type,
23
- })
24
- }
25
- export const type = Creatable.type.extend<Charge>({
26
- id: isly.string(),
27
- })
28
- export function fromCreatable(creatable: Creatable): Charge {
29
- return { ...creatable, id: cryptly.Identifier.generate(4) }
30
- }
11
+ export import Merchant = ChargeMerchant
12
+ export import Fx = ChargeFx
13
+ export const type = isly.object<Charge>({ merchant: ChargeMerchant.type, fx: ChargeFx.type })
31
14
  export function evaluate(
32
- charges: Charge[] = [],
33
15
  counterpart: Rail.Address.Card.Counterpart,
34
16
  currency: isoly.Currency,
35
17
  amount: number,
36
18
  preset?: Card.Preset,
19
+ charges?: Charge,
37
20
  exchange?: Transaction.Exchange
38
- ): Transaction.Amount.Charge[] {
39
- const result: Transaction.Amount.Charge[] = []
40
- for (const charge of charges)
41
- if (Applies.evaluate(charge.applies, counterpart, preset, exchange))
42
- result.push(toTransactionAmountCharge(currency, amount, charge))
43
- return result
44
- }
45
- function toTransactionAmountCharge(
46
- currency: isoly.Currency,
47
- amount: number,
48
- charge: Charge
49
21
  ): Transaction.Amount.Charge {
22
+ const merchant =
23
+ charges?.merchant && ChargeMerchant.evaluate(charges.merchant, currency, amount, counterpart, preset)
24
+ const fx = charges?.fx && ChargeFx.evaluate(charges.fx, currency, amount, preset, exchange)
25
+
50
26
  return {
51
- amount: -isoly.Currency.multiply(currency, amount, charge.rate),
52
- charge,
27
+ ...(merchant && { merchant }),
28
+ ...(fx && { fx }),
53
29
  }
54
30
  }
55
- export function sum(charges: Transaction.Amount.Charge[], currency: isoly.Currency): number {
56
- return charges.reduce((sum, charge) => isoly.Currency.add(currency, sum, charge.amount), 0)
57
- }
58
31
  }
package/Account/index.ts CHANGED
@@ -19,7 +19,7 @@ export interface Account extends Account.Creatable {
19
19
  details?: Account.Details
20
20
  counterparts?: Record<string, Rail.Address>
21
21
  key?: string
22
- charges?: AccountCharge[]
22
+ charges?: AccountCharge
23
23
  rules?: Rule[]
24
24
  status: Account.Status
25
25
  }
@@ -42,7 +42,7 @@ export namespace Account {
42
42
  details: Details.type.optional(),
43
43
  counterparts: isly.record<Record<string, Rail.Address>>(isly.string(), Rail.Address.type).optional(),
44
44
  key: isly.string().optional(),
45
- charges: AccountCharge.type.array().optional(),
45
+ charges: AccountCharge.type.optional(),
46
46
  rules: Rule.type.array().optional(),
47
47
  status: AccountStatus.type,
48
48
  })
@@ -5,7 +5,6 @@ import { Acquirer } from "../Acquirer"
5
5
  import { Amount } from "../Amount"
6
6
  import { Merchant } from "../Merchant"
7
7
  import { Transaction } from "../Transaction"
8
- import { Exchange as AuthorizationExchange } from "./Exchange"
9
8
  import { Status as AuthorizationStatus } from "./Status"
10
9
 
11
10
  export interface Authorization {
@@ -15,7 +14,7 @@ export interface Authorization {
15
14
  reference: string
16
15
  approvalCode?: string
17
16
  amount: Amount
18
- exchange?: AuthorizationExchange
17
+ exchange?: Transaction.Exchange
19
18
  card: {
20
19
  id: string
21
20
  token?: string
@@ -33,7 +32,6 @@ export interface Authorization {
33
32
  description: string
34
33
  }
35
34
  export namespace Authorization {
36
- export import Exchange = AuthorizationExchange
37
35
  export import Status = AuthorizationStatus
38
36
  export const type = isly.object<Authorization>({
39
37
  id: isly.fromIs("Authorization.id", cryptly.Identifier.is),
@@ -45,7 +43,7 @@ export namespace Authorization {
45
43
  description: isly.string(),
46
44
  })
47
45
  .optional(),
48
- exchange: AuthorizationExchange.type.optional(),
46
+ exchange: Transaction.Exchange.type.optional(),
49
47
  card: isly.object<Authorization["card"]>({
50
48
  id: isly.string(),
51
49
  token: isly.string().optional(),
@@ -27,4 +27,13 @@ export namespace Merchant {
27
27
  result = false
28
28
  return result
29
29
  }
30
+ export function resolve(counterpart: Rail.Address.Card.Counterpart): Merchant | undefined {
31
+ let result: Merchant | undefined
32
+ for (const merchant of values)
33
+ if (check(merchant, counterpart)) {
34
+ result = merchant
35
+ break
36
+ }
37
+ return result
38
+ }
30
39
  }
@@ -4,17 +4,13 @@ import { Account } from "../../Account"
4
4
 
5
5
  export class Charge {
6
6
  constructor(private readonly client: http.Client) {}
7
- async create(account: string, charge: Account.Charge.Creatable): Promise<Account.Charge | gracely.Error> {
7
+ async create(account: string, charge: Account.Charge): Promise<Account.Charge | gracely.Error> {
8
8
  return this.client.post<Account.Charge>(`/account/${account}/charge`, charge)
9
9
  }
10
10
  async remove(account: string, id: string): Promise<Account.Charge | gracely.Error> {
11
11
  return this.client.delete<Account.Charge>(`/account/${account}/charge/${id}`)
12
12
  }
13
- async replace(
14
- account: string,
15
- id: string,
16
- charge: Account.Charge.Creatable
17
- ): Promise<Account.Charge | gracely.Error> {
13
+ async replace(account: string, id: string, charge: Account.Charge): Promise<Account.Charge | gracely.Error> {
18
14
  return this.client.put<Account.Charge>(`/account/${account}/charge/${id}`, charge)
19
15
  }
20
16
  }
@@ -1,7 +1,6 @@
1
1
  import { isoly } from "isoly"
2
2
  import { isly } from "isly"
3
3
  import { Acquirer } from "../../Acquirer"
4
- import { Exchange } from "../../Authorization/Exchange"
5
4
  import { Merchant } from "../../Merchant"
6
5
  import { Rail } from "../../Rail"
7
6
  import type { Transaction } from "../../Transaction"
@@ -9,7 +8,7 @@ import type { Transaction } from "../../Transaction"
9
8
  export interface Authorization {
10
9
  card: string
11
10
  account: string
12
- exchange?: Exchange
11
+ exchange?: Transaction.Exchange
13
12
  acquirer: Acquirer
14
13
  description: string
15
14
  approvalCode?: string
@@ -62,7 +61,7 @@ export namespace Authorization {
62
61
  export const type = isly.object<Authorization>({
63
62
  card: isly.string(),
64
63
  account: isly.string(),
65
- exchange: Exchange.type.optional(),
64
+ exchange: isly.any().optional(),
66
65
  acquirer: Acquirer.type,
67
66
  description: isly.string(),
68
67
  approvalCode: isly.string().optional(),
@@ -25,17 +25,17 @@ export namespace Entry {
25
25
  export const type = entryType
26
26
  export const from = fromCreatable
27
27
  export function charge(
28
- charges: Account.Charge[] = [],
29
28
  counterpart: Rail.Address.Card.Counterpart,
30
29
  capture: Creatable.Capture,
31
- preset?: Preset
32
- ): Transaction.Amount.Charge[] {
30
+ preset?: Preset,
31
+ charges?: Account.Charge
32
+ ): Transaction.Amount.Charge {
33
33
  return Account.Charge.evaluate(
34
- charges,
35
34
  counterpart,
36
35
  capture.amount[0],
37
36
  isoly.Currency.add(capture.amount[0], capture.amount[1], capture.fee.other[capture.amount[0]] ?? 0),
38
37
  preset,
38
+ charges,
39
39
  capture.exchange
40
40
  )
41
41
  }
@@ -0,0 +1,86 @@
1
+ import { isoly } from "isoly"
2
+ import { isly } from "isly"
3
+ import { Card } from "../../../Card"
4
+ import { Rail } from "../../../Rail"
5
+ import { PreTransaction } from "../../PreTransaction"
6
+
7
+ export interface Charge {
8
+ merchant?: Charge.Merchant
9
+ fx?: Charge.Fx
10
+ }
11
+ export namespace Charge {
12
+ export interface Fx {
13
+ amount: number
14
+ rate: number
15
+ preset: Card.Preset | "default"
16
+ }
17
+ export namespace Fx {
18
+ export const type = isly.object<Fx>({
19
+ amount: isly.number(),
20
+ rate: isly.number(),
21
+ preset: isly.union(Card.Preset.type, isly.string("default")),
22
+ })
23
+ }
24
+ export interface Merchant {
25
+ amount: number
26
+ rate: number
27
+ merchant: Card.Restriction.Merchant
28
+ preset: Card.Preset | "default"
29
+ destination: { account: string }
30
+ }
31
+ export namespace Merchant {
32
+ export const type = isly.object<Merchant>({
33
+ amount: isly.number(),
34
+ rate: isly.number(),
35
+ merchant: Card.Restriction.Merchant.type,
36
+ preset: isly.union(Card.Preset.type, isly.string("default")),
37
+ destination: isly.object({
38
+ account: isly.string(),
39
+ }),
40
+ })
41
+ }
42
+ export type ChargeTransaction = PreTransaction.Incoming & { counterpart: Rail.Address.Internal }
43
+ export function total(currency: isoly.Currency, charges: Charge): number {
44
+ return isoly.Currency.add(currency, charges.fx?.amount ?? 0, charges.merchant?.amount ?? 0)
45
+ }
46
+ export function toTransactions(
47
+ charge: Charge,
48
+ account: string,
49
+ id: string,
50
+ currency: isoly.Currency,
51
+ fxCollectAccount: string
52
+ ): {
53
+ merchant: ChargeTransaction | undefined
54
+ fx: ChargeTransaction | undefined
55
+ } {
56
+ const merchant =
57
+ charge.merchant && toTransaction(charge.merchant, account, id, currency, fxCollectAccount, "merchant")
58
+ const fx = charge.fx && toTransaction(charge.fx, account, id, currency, fxCollectAccount, "fx")
59
+ return { merchant, fx }
60
+ }
61
+ function toTransaction(
62
+ charge: Charge.Merchant | Charge.Fx,
63
+ account: string,
64
+ id: string,
65
+ currency: isoly.Currency,
66
+ fxCollectAccount: string,
67
+ type: "merchant" | "fx"
68
+ ): ChargeTransaction {
69
+ const accountId = Merchant.type.is(charge) ? charge.destination.account : fxCollectAccount
70
+ return {
71
+ type: "incoming",
72
+ account: { type: "internal", identifier: accountId },
73
+ counterpart: { type: "internal", identifier: account },
74
+ currency: currency,
75
+ amount: charge.amount,
76
+ description: `${type} charge for transaction ${id}`,
77
+ posted: isoly.DateTime.now(),
78
+ rail: "internal",
79
+ reference: { reference: id, returnId: id },
80
+ }
81
+ }
82
+ export const type = isly.object<Charge>({
83
+ merchant: Charge.Merchant.type.optional(),
84
+ fx: Charge.Fx.type.optional(),
85
+ })
86
+ }
@@ -1,47 +1,39 @@
1
1
  import { isoly } from "isoly"
2
2
  import { isly } from "isly"
3
- import { Charge as AccountCharge } from "../Account/Charge"
4
- import type { Rule } from "../Rule"
5
- import { Exchange } from "./Exchange"
3
+ import type { Rule } from "../../Rule"
4
+ import { Exchange } from "../Exchange"
5
+ import { Charge as AmountCharge } from "./Charge"
6
6
 
7
7
  export interface Amount {
8
8
  original: number
9
9
  charge: number //Legacy
10
- charges?: Amount.Charge[]
10
+ charges?: Amount.Charge
11
11
  total: number
12
12
  exchange?: Exchange
13
13
  }
14
14
  export namespace Amount {
15
- export interface Charge {
16
- amount: number
17
- charge: AccountCharge
18
- }
19
- export namespace Charge {
20
- export const type = isly.object<Charge>({
21
- amount: isly.number(),
22
- charge: AccountCharge.type,
23
- })
24
- export function total(currency: isoly.Currency, charges: Charge[] = []): number {
25
- return charges.reduce((r, c) => isoly.Currency.add(currency, r, c.amount), 0)
26
- }
27
- }
15
+ export import Charge = AmountCharge
28
16
  export const type = isly.object<Amount>({
29
17
  original: isly.number(),
30
18
  charge: isly.number(),
31
- charges: Charge.type.array().optional(),
19
+ charges: Amount.Charge.type.optional(),
32
20
  total: isly.number(),
33
21
  exchange: Exchange.type.optional(),
34
22
  })
35
- export function fromState(state: Rule.State, charges?: Charge[]): Amount {
23
+ export function fromState(state: Rule.State, charges?: Charge): Amount {
36
24
  const sign = ["outbound", "authorization", "capture"].some(direction => direction == state.transaction.kind)
37
25
  ? -1
38
26
  : 1
39
- const charge = Amount.Charge.total(state.transaction.original.currency, charges)
27
+
40
28
  return {
41
29
  original: sign * state.transaction.original.amount,
42
30
  charge: 0,
43
31
  charges,
44
- total: isoly.Currency.add(state.transaction.original.currency, sign * state.transaction.original.total, charge),
32
+ total: isoly.Currency.add(
33
+ state.transaction.original.currency,
34
+ sign * state.transaction.original.total,
35
+ Amount.Charge.total(state.transaction.original.currency, charges ?? {})
36
+ ),
45
37
  exchange: state?.transaction.exchange ?? state.authorization?.exchange,
46
38
  }
47
39
  }
@@ -37,13 +37,13 @@ export namespace Creatable {
37
37
  reference: isly.object<{ reference: string }>({ reference: isly.string() }),
38
38
  approvalCode: isly.string().optional(),
39
39
  })
40
- export function charge(charges: Account.Charge[], creatable: CardTransaction, preset?: Preset): Amount.Charge[] {
40
+ export function charge(creatable: CardTransaction, preset: Preset, charges?: Account.Charge): Amount.Charge {
41
41
  return Account.Charge.evaluate(
42
- charges,
43
42
  creatable.counterpart,
44
43
  creatable.currency,
45
44
  creatable.amount,
46
45
  preset,
46
+ charges,
47
47
  creatable.exchange
48
48
  )
49
49
  }
@@ -3,11 +3,15 @@ import { Amount } from "../Amount"
3
3
 
4
4
  export interface Exchange {
5
5
  rate: number
6
- from: Amount
6
+ to?: Amount
7
+ from?: Amount
8
+ quote?: string
7
9
  }
8
10
  export namespace Exchange {
9
11
  export const type = isly.object<Exchange>({
10
12
  rate: isly.number(),
11
- from: Amount.type,
13
+ to: Amount.type.optional(),
14
+ from: Amount.type.optional(),
15
+ quote: isly.string().optional(),
12
16
  })
13
17
  }
@@ -89,7 +89,7 @@ export namespace Transaction {
89
89
  export function amountFromOperations(
90
90
  transaction: Transaction,
91
91
  operations: Operation[],
92
- charges?: Amount.Charge[]
92
+ charges?: Amount.Charge
93
93
  ): Amount {
94
94
  const changes = Operation.sum(operations)
95
95
  const reserved = isoly.Currency.add(
@@ -148,8 +148,8 @@ export namespace Transaction {
148
148
  account: { id: string; name: string; organization: string; address: Rail.Address },
149
149
  balance: { actual: number; reserved: number; available: number },
150
150
  operation: Operation | Status.Reason,
151
- charges: Amount.Charge[],
152
- by: string | undefined
151
+ charges?: Amount.Charge,
152
+ by?: string
153
153
  ): Transaction {
154
154
  const status: Status =
155
155
  typeof operation == "string"
@@ -0,0 +1,10 @@
1
+ import { isoly } from "isoly";
2
+ import { Card } from "../../../Card";
3
+ import { Amount } from "../../../Transaction/Amount";
4
+ import { Exchange } from "../../../Transaction/Exchange";
5
+ import { Preset } from "../Preset";
6
+ export type Fx = Preset;
7
+ export declare namespace Fx {
8
+ const type: import("isly/dist/cjs/Type").Type<Preset>;
9
+ function evaluate(charge: Fx, currency: isoly.Currency, amount: number, preset?: Card.Preset, exchange?: Exchange): Amount.Charge.Fx | undefined;
10
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Fx = void 0;
4
+ const isoly_1 = require("isoly");
5
+ const Preset_1 = require("../Preset");
6
+ var Fx;
7
+ (function (Fx) {
8
+ Fx.type = Preset_1.Preset.type;
9
+ function evaluate(charge, currency, amount, preset, exchange) {
10
+ let result;
11
+ const chargePreset = preset && charge[preset] ? preset : "default";
12
+ const chargeRate = charge[chargePreset] ?? 0;
13
+ if (exchange)
14
+ result = {
15
+ preset: chargePreset,
16
+ rate: chargeRate,
17
+ amount: -isoly_1.isoly.Currency.multiply(currency, amount, chargeRate),
18
+ };
19
+ return result;
20
+ }
21
+ Fx.evaluate = evaluate;
22
+ })(Fx || (exports.Fx = Fx = {}));
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../Account/Charge/Fx/index.ts"],"names":[],"mappings":";;;AAAA,iCAA6B;AAI7B,sCAAkC;AAIlC,IAAiB,EAAE,CAoBlB;AApBD,WAAiB,EAAE;IACL,OAAI,GAAG,eAAM,CAAC,IAAI,CAAA;IAC/B,SAAgB,QAAQ,CACvB,MAAU,EACV,QAAwB,EACxB,MAAc,EACd,MAAoB,EACpB,QAAmB;QAEnB,IAAI,MAAoC,CAAA;QACxC,MAAM,YAAY,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;QAClE,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QAC5C,IAAI,QAAQ;YACX,MAAM,GAAG;gBACR,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,CAAC,aAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;aAC9D,CAAA;QACF,OAAO,MAAM,CAAA;IACd,CAAC;IAjBe,WAAQ,WAiBvB,CAAA;AACF,CAAC,EApBgB,EAAE,kBAAF,EAAE,QAoBlB"}
@@ -0,0 +1,15 @@
1
+ import { isoly } from "isoly";
2
+ import { Card } from "../../../Card";
3
+ import { Rail } from "../../../Rail";
4
+ import { Amount } from "../../../Transaction/Amount";
5
+ import { Preset } from "../Preset";
6
+ export interface Merchant {
7
+ destination: {
8
+ account: string;
9
+ };
10
+ merchants: Partial<Record<Card.Restriction.Merchant, Preset>>;
11
+ }
12
+ export declare namespace Merchant {
13
+ const type: import("isly/dist/cjs/object").IslyObject<Merchant, object>;
14
+ function evaluate(charge: Merchant, currency: isoly.Currency, amount: number, counterpart: Rail.Address.Card.Counterpart, preset?: Card.Preset): Amount.Charge.Merchant | undefined;
15
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Merchant = void 0;
4
+ const isoly_1 = require("isoly");
5
+ const isly_1 = require("isly");
6
+ const Card_1 = require("../../../Card");
7
+ const Preset_1 = require("../Preset");
8
+ var Merchant;
9
+ (function (Merchant) {
10
+ Merchant.type = isly_1.isly.object({
11
+ destination: isly_1.isly.object({
12
+ account: isly_1.isly.string(),
13
+ }),
14
+ merchants: isly_1.isly.record(Card_1.Card.Restriction.Merchant.type, Preset_1.Preset.type),
15
+ });
16
+ function evaluate(charge, currency, amount, counterpart, preset) {
17
+ let result;
18
+ const merchant = Card_1.Card.Restriction.Merchant.resolve(counterpart);
19
+ if (merchant) {
20
+ const chargePreset = preset && charge.merchants?.[merchant]?.[preset] ? preset : "default";
21
+ const chargeRate = charge.merchants?.[merchant]?.[chargePreset] ?? 0;
22
+ result = {
23
+ merchant,
24
+ preset: chargePreset,
25
+ destination: charge.destination,
26
+ rate: chargeRate,
27
+ amount: -isoly_1.isoly.Currency.multiply(currency, amount, chargeRate),
28
+ };
29
+ }
30
+ return result;
31
+ }
32
+ Merchant.evaluate = evaluate;
33
+ })(Merchant || (exports.Merchant = Merchant = {}));
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../Account/Charge/Merchant/index.ts"],"names":[],"mappings":";;;AAAA,iCAA6B;AAC7B,+BAA2B;AAC3B,wCAAoC;AAGpC,sCAAkC;AAMlC,IAAiB,QAAQ,CA8BxB;AA9BD,WAAiB,QAAQ;IACX,aAAI,GAAG,WAAI,CAAC,MAAM,CAAW;QACzC,WAAW,EAAE,WAAI,CAAC,MAAM,CAAC;YACxB,OAAO,EAAE,WAAI,CAAC,MAAM,EAAE;SACtB,CAAC;QACF,SAAS,EAAE,WAAI,CAAC,MAAM,CAAoC,WAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAM,CAAC,IAAI,CAAC;KACtG,CAAC,CAAA;IAEF,SAAgB,QAAQ,CACvB,MAAgB,EAChB,QAAwB,EACxB,MAAc,EACd,WAA0C,EAC1C,MAAoB;QAEpB,IAAI,MAA0C,CAAA;QAC9C,MAAM,QAAQ,GAAG,WAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QAC/D,IAAI,QAAQ,EAAE,CAAC;YACd,MAAM,YAAY,GAAG,MAAM,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;YAC1F,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;YACpE,MAAM,GAAG;gBACR,QAAQ;gBACR,MAAM,EAAE,YAAY;gBACpB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,IAAI,EAAE,UAAU;gBAChB,MAAM,EAAE,CAAC,aAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;aAC9D,CAAA;QACF,CAAC;QACD,OAAO,MAAM,CAAA;IACd,CAAC;IArBe,iBAAQ,WAqBvB,CAAA;AACF,CAAC,EA9BgB,QAAQ,wBAAR,QAAQ,QA8BxB"}
@@ -0,0 +1,8 @@
1
+ import { isly } from "isly";
2
+ import { Card } from "../../../Card";
3
+ export type Preset = Partial<Record<Card.Preset, number>> & {
4
+ default: number;
5
+ };
6
+ export declare namespace Preset {
7
+ const type: isly.Type<Preset>;
8
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Preset = void 0;
4
+ const isly_1 = require("isly");
5
+ const Card_1 = require("../../../Card");
6
+ var Preset;
7
+ (function (Preset) {
8
+ const recordType = isly_1.isly.record(isly_1.isly.string(Card_1.Card.Preset.names), isly_1.isly.number());
9
+ const defaultType = isly_1.isly.object({ default: isly_1.isly.number() });
10
+ function is(value) {
11
+ return defaultType.is(value) && recordType.is((({ default: _, ...rest }) => rest)(value));
12
+ }
13
+ Preset.type = isly_1.isly.fromIs("Preset", is);
14
+ })(Preset || (exports.Preset = Preset = {}));
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../Account/Charge/Preset/index.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAC3B,wCAAoC;AAMpC,IAAiB,MAAM,CAOtB;AAPD,WAAiB,MAAM;IACtB,MAAM,UAAU,GAAG,WAAI,CAAC,MAAM,CAAS,WAAI,CAAC,MAAM,CAAC,WAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,WAAI,CAAC,MAAM,EAAE,CAAC,CAAA;IACrF,MAAM,WAAW,GAAG,WAAI,CAAC,MAAM,CAAsB,EAAE,OAAO,EAAE,WAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAChF,SAAS,EAAE,CAAC,KAAc;QACzB,OAAO,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1F,CAAC;IACY,WAAI,GAAG,WAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;AAC9C,CAAC,EAPgB,MAAM,sBAAN,MAAM,QAOtB"}