@lucaapp/service-utils 5.15.0 → 5.16.0
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.
|
@@ -1,205 +1,90 @@
|
|
|
1
1
|
import { SupportedCurrencies } from '../../money/supportedCurrencies';
|
|
2
|
-
/**
|
|
3
|
-
* JSON-serialisable value tree.
|
|
4
|
-
*
|
|
5
|
-
* Used for opaque payloads carried across the wire. Anything stored here
|
|
6
|
-
* must round-trip through `JSON.stringify` / `JSON.parse` without loss.
|
|
7
|
-
*/
|
|
8
2
|
export type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
9
3
|
[key: string]: JsonValue;
|
|
10
4
|
};
|
|
11
|
-
/** Legacy 3-letter terminal status code from the original payment provider integration. */
|
|
12
5
|
export type RapydPaymentStatus = 'ACT' | 'CAN' | 'CLO' | 'ERR' | 'EXP' | 'NEW' | 'REV';
|
|
13
|
-
/** Provider-neutral payment lifecycle status. */
|
|
14
6
|
export type PaymentStatus = 'PAID' | 'NEW' | 'ACTIVE' | 'CANCELLED' | 'EXPIRED' | 'REFUNDED' | 'ERROR' | 'UNKNOWN';
|
|
15
|
-
/**
|
|
16
|
-
* Lifecycle timestamps shared by all payment events.
|
|
17
|
-
*
|
|
18
|
-
* Each timestamp marks the first time the payment entered the corresponding
|
|
19
|
-
* state. A null value means the state was never reached.
|
|
20
|
-
*/
|
|
21
7
|
export type PaymentStatusTimings = {
|
|
22
|
-
/** Timestamp when the payment record was created (session start, NOT settlement). */
|
|
23
8
|
paymentCreatedAt: Date;
|
|
24
|
-
/** Payment record created; awaiting consumer action (e.g. order created, link sent, QR displayed). */
|
|
25
9
|
statusNewAt: Date | null;
|
|
26
|
-
/** Consumer engaged with the payment flow (e.g. opened a 3DS challenge, tapped a terminal, clicked the payment link). */
|
|
27
10
|
statusActiveAt: Date | null;
|
|
28
|
-
/** Provider authorised and captured the funds (online auth + capture or terminal sale complete). */
|
|
29
11
|
statusCompleteAt?: Date | null;
|
|
30
|
-
/** Cancelled by consumer or operator before completion. */
|
|
31
12
|
statusCanceledAt: Date | null;
|
|
32
|
-
/** Payment session expired before completion. */
|
|
33
13
|
statusExpiredAt: Date | null;
|
|
34
|
-
/** Provider returned an error or refused the payment. */
|
|
35
14
|
statusErrorAt: Date | null;
|
|
36
|
-
/** Authorised payment was reversed before settlement (e.g. chargeback pre-arbitration). */
|
|
37
15
|
statusReversedAt?: Date | null;
|
|
38
|
-
/** Projected or actual settlement date to the merchant balance. Null until the provider schedules settlement. */
|
|
39
16
|
settleAt?: Date | null;
|
|
40
17
|
};
|
|
41
|
-
/** Fields shared by both the legacy {@link Payment} event and the provider-neutral {@link PaymentEvent}. */
|
|
42
18
|
export type PaymentBase = {
|
|
43
|
-
/** Stable payment id. Uniquely identifies the payment across all systems. */
|
|
44
19
|
uuid: string;
|
|
45
|
-
/** Merchant location id (UUID). */
|
|
46
20
|
locationId: string;
|
|
47
|
-
/** Human-readable location name. Null when not provided. */
|
|
48
21
|
locationName: string | null;
|
|
49
|
-
/** Table or seat identifier from the POS. Null for non-dine-in payments. */
|
|
50
22
|
table: string | null;
|
|
51
|
-
/** Pre-created payment-request id. Null for spontaneous payments. */
|
|
52
23
|
paymentRequestId: string | null;
|
|
53
|
-
/** Short verifier token used by consumer-facing flows to prove ownership of the payment session. */
|
|
54
24
|
paymentVerifier: string;
|
|
55
|
-
/** Net goods/services amount before tip, in the smallest currency subunit. */
|
|
56
25
|
invoiceAmount: number;
|
|
57
|
-
/** Consumer-added gratuity, in the smallest currency subunit. Zero when no tip was given. */
|
|
58
26
|
tipAmount: number;
|
|
59
27
|
} & PaymentStatusTimings;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
*
|
|
63
|
-
* Kept for backward compatibility. New consumers should subscribe to
|
|
64
|
-
* {@link PaymentEvent}.
|
|
65
|
-
*/
|
|
28
|
+
export declare const PAYMENT_LEGACY_VERSION = 1;
|
|
29
|
+
export type PaymentLegacyVersion = typeof PAYMENT_LEGACY_VERSION;
|
|
66
30
|
export type Payment = PaymentBase & {
|
|
67
|
-
|
|
31
|
+
version: PaymentLegacyVersion;
|
|
68
32
|
totalAmount: number;
|
|
69
|
-
/** Timestamp when the payment was marked paid. */
|
|
70
33
|
paidAt: Date | null;
|
|
71
|
-
/** @deprecated Legacy terminal "CLO" state. Use `statusCompleteAt`. */
|
|
72
34
|
statusClosedAt: Date | null;
|
|
73
|
-
/** Fixed processing fee, in the smallest currency subunit. */
|
|
74
35
|
fixedFee: number;
|
|
75
|
-
/** Variable fee (commission + markup), in the smallest currency subunit. */
|
|
76
36
|
variableFee: number;
|
|
77
|
-
/** Legacy provider payment id. */
|
|
78
37
|
rapydPaymentId: string | null;
|
|
79
|
-
/** Legacy provider error code on failure. */
|
|
80
38
|
rapydErrorCode: string | null;
|
|
81
|
-
/** Legacy provider error message on failure. */
|
|
82
39
|
rapydErrorMessage: string | null;
|
|
83
|
-
/** Legacy 3-letter status code from the provider. */
|
|
84
40
|
rapydPaymentStatus: RapydPaymentStatus;
|
|
85
|
-
/** Legacy provider customer / saved-card alias. */
|
|
86
41
|
rapydCustomerId: string | null;
|
|
87
|
-
/** Aggregated payout batch id. Null until the payment is included in a payout. */
|
|
88
42
|
payoutId: string | null;
|
|
89
43
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
*
|
|
93
|
-
* Carries the full domain context needed for fiscalisation, receipt
|
|
94
|
-
* rendering, and downstream reconciliation. Wire format is JSON: monetary
|
|
95
|
-
* fields are integers in the smallest currency subunit and `currency`
|
|
96
|
-
* declares the unit.
|
|
97
|
-
*/
|
|
44
|
+
export declare const PAYMENT_EVENT_VERSION = 2;
|
|
45
|
+
export type PaymentEventVersion = typeof PAYMENT_EVENT_VERSION;
|
|
98
46
|
export type PaymentEvent = PaymentBase & {
|
|
99
|
-
|
|
47
|
+
version: PaymentEventVersion;
|
|
100
48
|
checkoutId?: string;
|
|
101
|
-
/** Order id (e.g. POS / fiscalisation order reference). Absent for payments not tied to an order. */
|
|
102
49
|
orderId?: string;
|
|
103
|
-
/** Operator-added service charge / convenience fee, in the smallest currency subunit. Zero if none. */
|
|
104
50
|
surchargeAmount: number;
|
|
105
|
-
/** ISO 4217 code that applies to every monetary field on this event. Single-currency invariant. */
|
|
106
51
|
currency: SupportedCurrencies;
|
|
107
|
-
/** Lifecycle status at event-emission time. */
|
|
108
52
|
status: PaymentStatus;
|
|
109
|
-
/** Method identifier, e.g. `'CARD'`, `'CASH'`, `'WALLET'`. */
|
|
110
53
|
method: string;
|
|
111
|
-
/** True if `method` is a cash variant. Cash flows skip provider webhooks and short-circuit fiscalisation. */
|
|
112
54
|
isCash: boolean;
|
|
113
|
-
/** Origin service identifier (free-form short string). */
|
|
114
55
|
source: string;
|
|
115
|
-
/** Aggregated payout batch id. Null until included in a payout. */
|
|
116
56
|
payoutId?: string | null;
|
|
117
|
-
/** Provider-side identifiers, errors, and raw provider payload. Absent for cash. */
|
|
118
57
|
merchantDetails?: PaymentMerchantDetails;
|
|
119
|
-
/** Card-specific identifiers and terminal context. Absent for non-card methods. */
|
|
120
58
|
cardDetails?: PaymentCardDetails;
|
|
121
|
-
/** Per-item breakdown for fiscalisation and receipt rendering. */
|
|
122
59
|
lineItems?: PaymentEventLineItem[];
|
|
123
60
|
};
|
|
124
|
-
/** Amount the consumer actually pays = `invoiceAmount + tipAmount + surchargeAmount` (smallest currency subunit). */
|
|
125
61
|
export declare const consumerPayAmount: (event: PaymentEvent) => number;
|
|
126
|
-
/**
|
|
127
|
-
* Amount receivable by the operator before Luca / provider fees are
|
|
128
|
-
* deducted = `invoiceAmount + tipAmount` (smallest currency subunit).
|
|
129
|
-
*
|
|
130
|
-
* Surcharge is excluded — it covers the consumer-side fee, not operator
|
|
131
|
-
* revenue. Net payout to the operator is this minus the per-payment fees.
|
|
132
|
-
*/
|
|
133
62
|
export declare const operatorReceivableAmount: (event: PaymentEvent) => number;
|
|
134
|
-
/**
|
|
135
|
-
* Provider-side metadata for a payment.
|
|
136
|
-
*
|
|
137
|
-
* All fields optional — populated by whichever provider handled the
|
|
138
|
-
* payment. Absent on cash and other non-provider flows.
|
|
139
|
-
*/
|
|
140
63
|
export type PaymentMerchantDetails = {
|
|
141
|
-
/** Payment-processor identifier (lowercase short string). Null when not yet routed to a provider. */
|
|
142
64
|
provider?: string | null;
|
|
143
|
-
/** Provider's payment id. Null until the provider authorises. */
|
|
144
65
|
providerIdentifier?: string | null;
|
|
145
|
-
/** Machine-readable error / decline code from the provider. Null on success. */
|
|
146
66
|
providerErrorCode?: string | null;
|
|
147
|
-
/** Human-readable provider error detail. Null on success. */
|
|
148
67
|
providerErrorMessage?: string | null;
|
|
149
|
-
/** Raw provider payload (notification or response body). Used for audits and chargeback evidence. */
|
|
150
68
|
providerData?: {
|
|
151
69
|
[key: string]: JsonValue;
|
|
152
70
|
} | null;
|
|
153
|
-
/** Provider-facing merchant reference used to reconcile internal records against the provider's records. */
|
|
154
71
|
externalReference?: string | null;
|
|
155
72
|
};
|
|
156
|
-
/**
|
|
157
|
-
* Card and terminal context.
|
|
158
|
-
*
|
|
159
|
-
* Card fields populated for card payments; terminal/consumer fields
|
|
160
|
-
* populated when applicable, regardless of card vs. wallet.
|
|
161
|
-
*/
|
|
162
73
|
export type PaymentCardDetails = {
|
|
163
|
-
/** Last 4 digits of the card. Null for non-card methods. */
|
|
164
74
|
last4?: string | null;
|
|
165
|
-
/** Provider authorisation code. Null until authorised. */
|
|
166
75
|
authCode?: string | null;
|
|
167
|
-
/** Saved-card alias for tokenised cards. Null for one-time payments. */
|
|
168
76
|
consumerAlias?: string | null;
|
|
169
|
-
/** Physical terminal id. Null for online / QR payments. */
|
|
170
77
|
terminalId?: string | null;
|
|
171
|
-
/** Consumer account id. Null for anonymous payments. */
|
|
172
78
|
consumerId?: string | null;
|
|
173
79
|
};
|
|
174
|
-
/**
|
|
175
|
-
* One billable line in the order, used for fiscalisation and receipt
|
|
176
|
-
* rendering.
|
|
177
|
-
*
|
|
178
|
-
* Sub-items represent components of a parent line (e.g. base drink + paid
|
|
179
|
-
* topping) and follow the same shape recursively. Amounts are integers in
|
|
180
|
-
* the smallest currency subunit.
|
|
181
|
-
*/
|
|
182
80
|
export type PaymentEventLineItem = {
|
|
183
|
-
/** Stable line-item id. Omitted on synthetic sub-items that have no own row. */
|
|
184
81
|
uuid?: string;
|
|
185
|
-
/** POS-system menu item / SKU id. Null when not synced from the POS menu. */
|
|
186
82
|
posItemId?: string | null;
|
|
187
|
-
/** Display name (e.g. `'Espresso'`). May be omitted when the consumer can resolve it from `posItemId`. */
|
|
188
83
|
name?: string;
|
|
189
|
-
/** Number of units, e.g. `2` for two coffees. */
|
|
190
84
|
quantity: number;
|
|
191
|
-
/** Price for one unit, in the smallest currency subunit. */
|
|
192
85
|
pricePerUnit: number;
|
|
193
|
-
/** `quantity × pricePerUnit + Σ subItems.totalPrice`, in the smallest currency subunit. */
|
|
194
86
|
totalPrice: number;
|
|
195
|
-
/**
|
|
196
|
-
* VAT / sales-tax rate as a percentage value (e.g. `19` for 19%, `7` for
|
|
197
|
-
* 7%). NOT a decimal fraction — `0.19` would mean 0.19%. Null if
|
|
198
|
-
* tax-exempt or unknown.
|
|
199
|
-
*/
|
|
200
87
|
taxPercentage?: number | null;
|
|
201
|
-
/** Item currency. Typically equals the parent payment currency. */
|
|
202
88
|
currency: SupportedCurrencies;
|
|
203
|
-
/** Recursive components of this line. Each sub-item follows the same shape. */
|
|
204
89
|
subItems?: PaymentEventLineItem[];
|
|
205
90
|
};
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.operatorReceivableAmount = exports.consumerPayAmount = void 0;
|
|
4
|
-
|
|
3
|
+
exports.operatorReceivableAmount = exports.consumerPayAmount = exports.PAYMENT_EVENT_VERSION = exports.PAYMENT_LEGACY_VERSION = void 0;
|
|
4
|
+
exports.PAYMENT_LEGACY_VERSION = 1;
|
|
5
|
+
exports.PAYMENT_EVENT_VERSION = 2;
|
|
5
6
|
const consumerPayAmount = (event) => event.invoiceAmount + event.tipAmount + event.surchargeAmount;
|
|
6
7
|
exports.consumerPayAmount = consumerPayAmount;
|
|
7
|
-
/**
|
|
8
|
-
* Amount receivable by the operator before Luca / provider fees are
|
|
9
|
-
* deducted = `invoiceAmount + tipAmount` (smallest currency subunit).
|
|
10
|
-
*
|
|
11
|
-
* Surcharge is excluded — it covers the consumer-side fee, not operator
|
|
12
|
-
* revenue. Net payout to the operator is this minus the per-payment fees.
|
|
13
|
-
*/
|
|
14
8
|
const operatorReceivableAmount = (event) => event.invoiceAmount + event.tipAmount;
|
|
15
9
|
exports.operatorReceivableAmount = operatorReceivableAmount;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Payment } from './events/payment';
|
|
1
|
+
import type { Payment, PaymentEvent } from './events/payment';
|
|
2
2
|
import type { Consumer } from './events/consumer';
|
|
3
3
|
import type { Operator } from './events/operator';
|
|
4
4
|
import type { LocationGroupEmployees } from './events/locationGroupEmployees';
|
|
@@ -39,7 +39,7 @@ declare enum KafkaTopic {
|
|
|
39
39
|
TOKENIZATION_JOB_ITEM = "tokenization_job_item"
|
|
40
40
|
}
|
|
41
41
|
type MessageFormats = {
|
|
42
|
-
[KafkaTopic.PAYMENTS]: Payment;
|
|
42
|
+
[KafkaTopic.PAYMENTS]: Payment | PaymentEvent;
|
|
43
43
|
[KafkaTopic.CONSUMERS]: Consumer;
|
|
44
44
|
[KafkaTopic.OPERATORS]: Operator;
|
|
45
45
|
[KafkaTopic.OPERATORS_PAY]: OperatorPay;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lucaapp/service-utils",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.16.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"resolutions": {
|
|
87
87
|
"tar": "^7.5.11",
|
|
88
88
|
"lodash": "^4.18.1",
|
|
89
|
-
"qs": "
|
|
89
|
+
"qs": "6.15.2",
|
|
90
90
|
"dottie": "2.0.7",
|
|
91
91
|
"fast-xml-parser": "^5.7.1",
|
|
92
92
|
"yaml": "^2.8.3",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"axios": "1.16.0",
|
|
101
101
|
"path-to-regexp": "0.1.13",
|
|
102
102
|
"ip-address": "10.1.1",
|
|
103
|
-
"fast-xml-builder": "^1.1.7"
|
|
103
|
+
"fast-xml-builder": "^1.1.7",
|
|
104
|
+
"brace-expansion": "2.0.3"
|
|
104
105
|
}
|
|
105
106
|
}
|