@fire-spark/core 0.10.0 → 0.11.1
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.
- package/dist/index.d.ts +58 -4
- package/dist/index.js +183 -6
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Money, PaymentAdapter, PaymentCollectAt, PaymentContext, PaymentResult, PaymentStorage, PaymentUI, RedeemLike, RedeemSource, isRealPaymentMethod, orderRedeems } from "@fire-spark/payments";
|
|
2
|
-
import { AndConditions, CheckoutMode, CheckoutResolved, CmsBlock, Condition, Customer, CustomerIdentifyInput, CustomerRegisterInput, CustomerUpdateInput, Fulfillment, FulfillmentListInput, GroupDisplayType, KioskDeviceConfig, KioskDeviceOverrides, KioskHealthBatchInput, KioskHealthBatchResult, KioskHeartbeatInput, KioskHeartbeatResult, KioskRealtimeToken, MatchResult, MatchableRule, Menu, Menu as Menu$1, MenuLookup, MenuLookup as MenuLookup$1, MerchantPayment, ModifierControlType, ModifierGroup, OrConditions, Order as Order$1, Order as Order$2, OrderDeviceListInput, OrderDeviceListResult, OrderFulfillment, OrderInsertInput, OrderLine, OrderListInput, OrderRecordPaymentInput, OrderRedeem, OrderRedemptionStep, OrderReorderInput, OrderTotals, OrderUpdateInput, OrderValidateInput, OrderValidateOutput, PaymentCollectAt as PaymentCollectAt$1, PaymentIntentPutInput, PaymentMethod, PaymentProvider, PaymentTender, PaymentTenderInput, PlaceOrderResult, PosCatalog, PosFloorInput, PosFloorOccupancy, PosFloorPlan, PosFloorRealtimeToken, PosHealthBatchInput, PosHealthBatchResult, PosHeartbeatInput, PosHeartbeatResult, PosKioskOrder, PosKioskSettleInput, PosKioskSettleResult, PosOrderInput, PosOrderResult, PosTableAttachOrderInput, PosTableCloseInput, PosTableJoinInput, PosTableSeatInput, PosTableSeatReservationInput, PosTableSplitInput, PricingModifier, Product, Product as Product$1, Recommendation, RecurringDateCronResult, RecurringDateCronValues, RulesEngineOrderLine, RulesEngineParams, RulesEngineRuntime, Schedule, SdkLogContext, SdkLogErrorInfo, SdkLogLevel, SdkLogOptions, Store, StoreGetInput, StoreListInput, StoreNearbyInput, StorefrontAvailability, StorefrontMenu, StorefrontMenuScope, StorefrontMenuStreamOptions, StorefrontPaymentsListInput, StorefrontPreferences, TenderRefundInput, TenderReplaceInput, TenderVoidInput, Variant, VariantGroup } from "@fire-spark/types";
|
|
2
|
+
import { AndConditions, CheckoutMode, CheckoutResolved, CmsBlock, Condition, Customer, CustomerIdentifyInput, CustomerRegisterInput, CustomerUpdateInput, Fulfillment, FulfillmentListInput, GroupDisplayType, KioskDeviceConfig, KioskDeviceOverrides, KioskHealthBatchInput, KioskHealthBatchResult, KioskHeartbeatInput, KioskHeartbeatResult, KioskRealtimeToken, MatchResult, MatchableRule, Menu, Menu as Menu$1, MenuLookup, MenuLookup as MenuLookup$1, MerchantPayment, ModifierControlType, ModifierGroup, OrConditions, Order as Order$1, Order as Order$2, OrderCancelInput, OrderCancelInput as OrderCancelInput$1, OrderCancelType, OrderCancelType as OrderCancelType$1, OrderDeviceListInput, OrderDeviceListResult, OrderFulfillment, OrderInsertInput, OrderLine, OrderListInput, OrderRecordPaymentInput, OrderRedeem, OrderRedemptionStep, OrderReorderInput, OrderTotals, OrderUpdateInput, OrderValidateInput, OrderValidateOutput, PaymentCollectAt as PaymentCollectAt$1, PaymentIntentPutInput, PaymentMethod, PaymentProvider, PaymentTender, PaymentTenderInput, PlaceOrderResult, PosCatalog, PosFloorInput, PosFloorOccupancy, PosFloorPlan, PosFloorRealtimeToken, PosHealthBatchInput, PosHealthBatchResult, PosHeartbeatInput, PosHeartbeatResult, PosKioskOrder, PosKioskSettleInput, PosKioskSettleResult, PosOrderInput, PosOrderResult, PosTableAttachOrderInput, PosTableCloseInput, PosTableJoinInput, PosTableSeatInput, PosTableSeatReservationInput, PosTableSplitInput, PricingModifier, Product, Product as Product$1, Recommendation, RecurringDateCronResult, RecurringDateCronValues, RulesEngineOrderLine, RulesEngineParams, RulesEngineRuntime, Schedule, SdkLogContext, SdkLogErrorInfo, SdkLogLevel, SdkLogOptions, Store, StoreGetInput, StoreListInput, StoreNearbyInput, StorefrontAvailability, StorefrontMenu, StorefrontMenuScope, StorefrontMenuStreamOptions, StorefrontPaymentsListInput, StorefrontPreferences, TenderRefundInput, TenderReplaceInput, TenderVoidInput, Variant, VariantGroup } from "@fire-spark/types";
|
|
3
3
|
import { Big } from "big.js";
|
|
4
4
|
//#region src/productCustomization/catalog.utils.d.ts
|
|
5
5
|
/** Image for a product inside one modifier group, else the product image. */
|
|
@@ -272,8 +272,13 @@ declare const refundTender: (id: string, tenderId: string, body: TenderRefundInp
|
|
|
272
272
|
declare const getOrderFulfillment: (id: string, options?: ServiceHttpOptions) => Promise<OrderFulfillment>;
|
|
273
273
|
declare const listOrderFulfillments: (ids: string[], options?: ServiceHttpOptions) => Promise<OrderFulfillment[]>;
|
|
274
274
|
declare const updateOrder: (id: string, body: OrderUpdateInput, options?: ServiceHttpOptions) => Promise<Order$1>;
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
/**
|
|
276
|
+
* `body` is optional: `device` (checked only when sent), `type`
|
|
277
|
+
* (`VOID` / `REVERSE`) and what the device reversed (`tenders`).
|
|
278
|
+
*/
|
|
279
|
+
declare const cancelOrder: (id: string, options?: ServiceHttpOptions, body?: OrderCancelInput$1) => Promise<Order$1>;
|
|
280
|
+
/** Refunds the tenders only; the order status stays. `type` is `REFUND`. */
|
|
281
|
+
declare const refundOrder: (id: string, options?: ServiceHttpOptions, body?: OrderCancelInput$1) => Promise<Order$1>;
|
|
277
282
|
declare const reorderOrder: (id: string, body?: OrderReorderInput, options?: ServiceHttpOptions) => Promise<Order$1>;
|
|
278
283
|
/**
|
|
279
284
|
* `POST /storefront/v1/orders/:id/reopen`: voids every payment of a placed,
|
|
@@ -402,6 +407,25 @@ type ReverseAllOptions = {
|
|
|
402
407
|
declare const coveredAmount: (intents: Intents) => number;
|
|
403
408
|
declare const remainingAmount: (order: Order$1) => number;
|
|
404
409
|
//#endregion
|
|
410
|
+
//#region src/order/cancel.d.ts
|
|
411
|
+
/**
|
|
412
|
+
* The operation an order takes: `VOID` (nothing charged), `REVERSE`
|
|
413
|
+
* (charged, not delivered) or `REFUND` (delivered). An order already
|
|
414
|
+
* cancelled keeps its operation, so a replay stays idempotent.
|
|
415
|
+
*/
|
|
416
|
+
declare const cancelTypeOf: (order: Order$1) => OrderCancelType$1;
|
|
417
|
+
type OrderCancelResult = {
|
|
418
|
+
/** The order the server answered. */
|
|
419
|
+
order: Order$1;
|
|
420
|
+
type: OrderCancelType$1;
|
|
421
|
+
/** Endpoint called: `cancel()` → `cancel`, `refund()` → `refund`. */
|
|
422
|
+
path: "cancel" | "refund";
|
|
423
|
+
/** What the device did with each charge it voided. */
|
|
424
|
+
outcomes: ReversalOutcome[];
|
|
425
|
+
/** Tender ids the device could not void yet (`reversal_pending`). */
|
|
426
|
+
pending: string[];
|
|
427
|
+
};
|
|
428
|
+
//#endregion
|
|
405
429
|
//#region src/order/recommendations.d.ts
|
|
406
430
|
type RecommendationType = Recommendation["type"];
|
|
407
431
|
declare const DEFAULT_RECOMMENDATION_TYPES: RecommendationType[];
|
|
@@ -418,6 +442,13 @@ type OrderDeviceCredential = {
|
|
|
418
442
|
uid: string;
|
|
419
443
|
secret: string;
|
|
420
444
|
};
|
|
445
|
+
type OrderCancelOptions = {
|
|
446
|
+
/** `cancel()` only: forces VOID / REVERSE; omitted, it follows the order. */
|
|
447
|
+
type?: Exclude<OrderCancelType, "REFUND">;
|
|
448
|
+
reason?: string;
|
|
449
|
+
/** Only these charged tenders are voided on the device. */
|
|
450
|
+
tenderIds?: readonly string[];
|
|
451
|
+
};
|
|
421
452
|
type CreateOrderOptions = {
|
|
422
453
|
scope?: OrderScope;
|
|
423
454
|
customer?: OrderCustomerSource;
|
|
@@ -498,6 +529,8 @@ declare class Order {
|
|
|
498
529
|
*/
|
|
499
530
|
private requestedRedeem;
|
|
500
531
|
private readonly device?;
|
|
532
|
+
/** Device voids a failed cancel / refund call did not report yet. */
|
|
533
|
+
private unreported;
|
|
501
534
|
private constructor();
|
|
502
535
|
/**
|
|
503
536
|
* Opens a cart session: reuses an existing OPEN order for the scope, or a
|
|
@@ -514,6 +547,8 @@ declare class Order {
|
|
|
514
547
|
debounceMs?: number;
|
|
515
548
|
persisted?: boolean;
|
|
516
549
|
sleep?: (ms: number) => Promise<void>;
|
|
550
|
+
/** Sent by `cancel()` (and `placeOrder`) when present. */
|
|
551
|
+
device?: CreateOrderOptions["device"];
|
|
517
552
|
}, notify?: () => void): Order;
|
|
518
553
|
/** Whether this session has a server row yet. */
|
|
519
554
|
isPersisted(): boolean;
|
|
@@ -648,6 +683,25 @@ declare class Order {
|
|
|
648
683
|
replaceTender(tenderId: string, payment: MerchantPayment, collectAt?: PaymentCollectAt$1): Promise<Order$1>;
|
|
649
684
|
/** "Cancel and refund": reverses device charges, then cancels the order. */
|
|
650
685
|
cancelAndRefund(options?: ReverseAllOptions): Promise<ReversalOutcome[]>;
|
|
686
|
+
/**
|
|
687
|
+
* Cancels this placed, not delivered order with one call to `/cancel`:
|
|
688
|
+
* `VOID` (nothing charged) or `REVERSE` (charged), decided from the
|
|
689
|
+
* fresh order. Device charges are voided first and their results go in
|
|
690
|
+
* the same body (never `/payments`). The device credential of
|
|
691
|
+
* `createOrder({ device })` / `fromExisting({ device })` is sent when
|
|
692
|
+
* present. A delivered order throws before touching the device: use
|
|
693
|
+
* `refund()`. A forced `type` that does not match throws too.
|
|
694
|
+
*/
|
|
695
|
+
cancel(options?: OrderCancelOptions): Promise<OrderCancelResult>;
|
|
696
|
+
/**
|
|
697
|
+
* Refunds this delivered order with one call to `/refund`
|
|
698
|
+
* (`type: REFUND`): device charges are voided first and reported in the
|
|
699
|
+
* body. Only the tenders change; the order status stays. An order not
|
|
700
|
+
* delivered throws before touching the device: use `cancel()`.
|
|
701
|
+
*/
|
|
702
|
+
refund(options?: Omit<OrderCancelOptions, "type">): Promise<OrderCancelResult>;
|
|
703
|
+
private freshCancelType;
|
|
704
|
+
private runCancel;
|
|
651
705
|
/** Voids one tender (operator flow); idempotent per call. */
|
|
652
706
|
voidTender(tenderId: string, reason?: string): Promise<Order$1>;
|
|
653
707
|
/** Refunds one tender: all of it, an amount, or some units. */
|
|
@@ -1601,4 +1655,4 @@ declare const validateCardholderName: (value: string) => CardholderNameError | n
|
|
|
1601
1655
|
*/
|
|
1602
1656
|
declare const cardPreviewGroups: (value: string) => CardPreviewSlot[][];
|
|
1603
1657
|
//#endregion
|
|
1604
|
-
export { type ApplyRedeemInput, type AuthConfigureOptions, CARD_BRANDS, type CardBrand, type CardBrandSpec, type CardCvcError, type CardExpiry, type CardExpiryError, type CardNumberError, type CardPreviewSlot, type CardholderNameError, type CreateOrderOptions, type CreateSessionOptions, type CustomizationPath, type CustomizationSession, DEFAULT_RECOMMENDATION_TYPES, type DeunaCallbackUrls, type DeunaOrderStatus, type ExchangeOptions, type FailedCharge, type FlatMenuCategory, type GenOrderIdOptions, type GroupDisplayType, ID_HASH_FORMATS, type IdBuilder, type IdHashFormat, type ListMenusStreamOptions, type ListPaymentsOptions, type Menu, type MenuCategoryNode, type MenuLookup, type MilestoneSteps, type MilestoneTrackItem, type ModifierControlType, type ModifierCtx, type ModifierGroupCtx, type NestedMenuCategory, Order, type OrderCustomerSource, type OrderDeviceCredential, type OrderDraft, type OrderIssue, type OrderIssueCode, type OrderLineDiff, type OrderLineIssue, type OrderLineIssueCode, OrderPaymentRequiredError, type OrderScope, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, type OrderValidationResult, type PayIntentOptions, type PayIntentResult, type PayOptions, type PaymentCardBrand, type PaymentProgressEvent, type PaymentProgressListener, type PaymentRunOptions, type PaymentSessionOptions, type PricingModifier, type Product, type ProductCtx, type QuantitiesByPath, type RecommendationType, RecurringDateCron, type RedeemPaymentRow, type RemoveRedeemInput, type ReorderOrderOptions, type ResetOptions, type ReversalOutcome, type ReverseAllOptions, RulesEngine, type ScheduleWindow, type SelectionStatus, type SelectionsByPath, type SerializedError, type ServiceHttpOptions, type SimpleTenderPayment, type Snapshot, type StorefrontAccessToken, type StorefrontErrorDetails, StorefrontHttpError, type TrackWorkflow, type ValidateOptions, type ValidateOrderAgainstMenuInput, type Variant, type VariantGroup, type VariantGroupCtx, type VariantOptionCtx, type VariantSelection, type VerifyWebhookSignatureInput, type VisitedState, addLines, auth, buildCustomerSnapshot, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createDeunaWidgetApi, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isGenId, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, resolveModifierImageUrl, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
|
|
1658
|
+
export { type ApplyRedeemInput, type AuthConfigureOptions, CARD_BRANDS, type CardBrand, type CardBrandSpec, type CardCvcError, type CardExpiry, type CardExpiryError, type CardNumberError, type CardPreviewSlot, type CardholderNameError, type CreateOrderOptions, type CreateSessionOptions, type CustomizationPath, type CustomizationSession, DEFAULT_RECOMMENDATION_TYPES, type DeunaCallbackUrls, type DeunaOrderStatus, type ExchangeOptions, type FailedCharge, type FlatMenuCategory, type GenOrderIdOptions, type GroupDisplayType, ID_HASH_FORMATS, type IdBuilder, type IdHashFormat, type ListMenusStreamOptions, type ListPaymentsOptions, type Menu, type MenuCategoryNode, type MenuLookup, type MilestoneSteps, type MilestoneTrackItem, type ModifierControlType, type ModifierCtx, type ModifierGroupCtx, type NestedMenuCategory, Order, type OrderCancelInput, type OrderCancelOptions, type OrderCancelResult, type OrderCancelType, type OrderCustomerSource, type OrderDeviceCredential, type OrderDraft, type OrderIssue, type OrderIssueCode, type OrderLineDiff, type OrderLineIssue, type OrderLineIssueCode, OrderPaymentRequiredError, type OrderScope, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, type OrderValidationResult, type PayIntentOptions, type PayIntentResult, type PayOptions, type PaymentCardBrand, type PaymentProgressEvent, type PaymentProgressListener, type PaymentRunOptions, type PaymentSessionOptions, type PricingModifier, type Product, type ProductCtx, type QuantitiesByPath, type RecommendationType, RecurringDateCron, type RedeemPaymentRow, type RemoveRedeemInput, type ReorderOrderOptions, type ResetOptions, type ReversalOutcome, type ReverseAllOptions, RulesEngine, type ScheduleWindow, type SelectionStatus, type SelectionsByPath, type SerializedError, type ServiceHttpOptions, type SimpleTenderPayment, type Snapshot, type StorefrontAccessToken, type StorefrontErrorDetails, StorefrontHttpError, type TrackWorkflow, type ValidateOptions, type ValidateOrderAgainstMenuInput, type Variant, type VariantGroup, type VariantGroupCtx, type VariantOptionCtx, type VariantSelection, type VerifyWebhookSignatureInput, type VisitedState, addLines, auth, buildCustomerSnapshot, cancelTypeOf, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createDeunaWidgetApi, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isGenId, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, resolveModifierImageUrl, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
|
package/dist/index.js
CHANGED
|
@@ -2625,11 +2625,24 @@ const updateOrder = (id, body, options) => {
|
|
|
2625
2625
|
options
|
|
2626
2626
|
]);
|
|
2627
2627
|
};
|
|
2628
|
-
const
|
|
2629
|
-
|
|
2628
|
+
const postCancel = (path, options, body) => {
|
|
2629
|
+
const method = "POST";
|
|
2630
|
+
if (!body) return storefrontJson(path, { method }, options);
|
|
2631
|
+
return storefrontJson(path, {
|
|
2632
|
+
method,
|
|
2633
|
+
body: JSON.stringify(body)
|
|
2634
|
+
}, options);
|
|
2630
2635
|
};
|
|
2631
|
-
|
|
2632
|
-
|
|
2636
|
+
/**
|
|
2637
|
+
* `body` is optional: `device` (checked only when sent), `type`
|
|
2638
|
+
* (`VOID` / `REVERSE`) and what the device reversed (`tenders`).
|
|
2639
|
+
*/
|
|
2640
|
+
const cancelOrder = (id, options, body) => {
|
|
2641
|
+
return postCancel(`${orderPath(id)}/cancel`, options, body);
|
|
2642
|
+
};
|
|
2643
|
+
/** Refunds the tenders only; the order status stays. `type` is `REFUND`. */
|
|
2644
|
+
const refundOrder = (id, options, body) => {
|
|
2645
|
+
return postCancel(`${orderPath(id)}/refund`, options, body);
|
|
2633
2646
|
};
|
|
2634
2647
|
const reorderOrder = (id, body = {}, options) => {
|
|
2635
2648
|
return storefrontJson(`${orderPath(id)}/reorder`, {
|
|
@@ -3345,6 +3358,63 @@ const isOrderPaymentRequiredError = (error) => {
|
|
|
3345
3358
|
return error instanceof OrderPaymentRequiredError;
|
|
3346
3359
|
};
|
|
3347
3360
|
//#endregion
|
|
3361
|
+
//#region src/order/cancel.ts
|
|
3362
|
+
const FULFILLED = ["COMPLETED", "FULFILLED"];
|
|
3363
|
+
/** Same rule as the server: `status` or `fulfillment_status` delivered. */
|
|
3364
|
+
const isOrderFulfilled = (order) => {
|
|
3365
|
+
if (FULFILLED.includes(order.status)) return true;
|
|
3366
|
+
return FULFILLED.includes(String(order.fulfillment_status ?? ""));
|
|
3367
|
+
};
|
|
3368
|
+
/** Money was charged at some point (paid, or already given back). */
|
|
3369
|
+
const isOrderCharged = (order) => {
|
|
3370
|
+
if (order.payment_status === "PAID") return true;
|
|
3371
|
+
if (order.payment_status === "REFUNDED") return true;
|
|
3372
|
+
return liveTenders(currentIntent(order.payment_intents)).some((tender) => {
|
|
3373
|
+
if (tender.status === "PAID" || tender.status === "REFUNDED") return true;
|
|
3374
|
+
return (tender.refunded_total ?? 0) > 0;
|
|
3375
|
+
});
|
|
3376
|
+
};
|
|
3377
|
+
/**
|
|
3378
|
+
* The operation an order takes: `VOID` (nothing charged), `REVERSE`
|
|
3379
|
+
* (charged, not delivered) or `REFUND` (delivered). An order already
|
|
3380
|
+
* cancelled keeps its operation, so a replay stays idempotent.
|
|
3381
|
+
*/
|
|
3382
|
+
const cancelTypeOf = (order) => {
|
|
3383
|
+
if (order.status === "VOIDED") return "VOID";
|
|
3384
|
+
if (order.status === "REVERSED") return "REVERSE";
|
|
3385
|
+
if (isOrderFulfilled(order)) return "REFUND";
|
|
3386
|
+
return isOrderCharged(order) ? "REVERSE" : "VOID";
|
|
3387
|
+
};
|
|
3388
|
+
const REVERSED_RESULTS = ["REFUNDED", "CANCELLED"];
|
|
3389
|
+
/** The device gave the money back. */
|
|
3390
|
+
const isDeviceReversed = (reversal) => {
|
|
3391
|
+
return REVERSED_RESULTS.includes(reversal.outcome.result.status);
|
|
3392
|
+
};
|
|
3393
|
+
/** Body `tenders` entry for one device reversal. */
|
|
3394
|
+
const toReportedTender = (reversal) => {
|
|
3395
|
+
const { tender, outcome } = reversal;
|
|
3396
|
+
const { status, metadata: m1, error } = outcome.result;
|
|
3397
|
+
const payment = m1?.payment ?? null;
|
|
3398
|
+
const metadata = { reversal: {
|
|
3399
|
+
kind: outcome.kind,
|
|
3400
|
+
status,
|
|
3401
|
+
payment,
|
|
3402
|
+
error: error ?? null
|
|
3403
|
+
} };
|
|
3404
|
+
const reference = payment?.provider_transaction_id ?? null;
|
|
3405
|
+
const b1 = { tender_id: tender.id };
|
|
3406
|
+
const b2 = { attempt_reference: tender.attempt_reference };
|
|
3407
|
+
const result = isDeviceReversed(reversal) ? "REVERSED" : "NOT_REVERSED";
|
|
3408
|
+
const provider_reference = reference;
|
|
3409
|
+
return {
|
|
3410
|
+
...b1,
|
|
3411
|
+
...b2,
|
|
3412
|
+
result,
|
|
3413
|
+
provider_reference,
|
|
3414
|
+
metadata
|
|
3415
|
+
};
|
|
3416
|
+
};
|
|
3417
|
+
//#endregion
|
|
3348
3418
|
//#region src/order/retry.ts
|
|
3349
3419
|
const defaultSleep$1 = (ms) => {
|
|
3350
3420
|
return new Promise((resolve) => {
|
|
@@ -4788,6 +4858,34 @@ var PaymentSession = class {
|
|
|
4788
4858
|
}
|
|
4789
4859
|
return outcomes;
|
|
4790
4860
|
}
|
|
4861
|
+
/**
|
|
4862
|
+
* Voids the `PAID` device charges of this order without reporting them:
|
|
4863
|
+
* the caller sends the results with one cancel / refund call
|
|
4864
|
+
* (`order.cancel()`), never through `/payments`.
|
|
4865
|
+
*/
|
|
4866
|
+
async reverseOnDevice(options = {}) {
|
|
4867
|
+
const intents = this.deps.getOrder().payment_intents;
|
|
4868
|
+
const reversals = [];
|
|
4869
|
+
const only = options.tenderIds ? new Set(options.tenderIds) : null;
|
|
4870
|
+
for (const tender of chargedTenders(intents)) {
|
|
4871
|
+
if (only && !only.has(tender.id)) continue;
|
|
4872
|
+
if (options.skip?.has(tender.id)) continue;
|
|
4873
|
+
if (tender.status !== "PAID") continue;
|
|
4874
|
+
const found = await this.contextFor(tender);
|
|
4875
|
+
if (!found) continue;
|
|
4876
|
+
await options.onProgress?.({
|
|
4877
|
+
type: "reversing",
|
|
4878
|
+
tender
|
|
4879
|
+
});
|
|
4880
|
+
const { adapter, result, ctx } = found;
|
|
4881
|
+
const outcome = await reversePayment(adapter, ctx, result);
|
|
4882
|
+
reversals.push({
|
|
4883
|
+
tender,
|
|
4884
|
+
outcome
|
|
4885
|
+
});
|
|
4886
|
+
}
|
|
4887
|
+
return reversals;
|
|
4888
|
+
}
|
|
4791
4889
|
/** Runs a terminal operation (init, test, closeBatch, status, extra). */
|
|
4792
4890
|
async runTerminal(payment, key) {
|
|
4793
4891
|
const terminal = this.adapterFor(payment)?.terminal;
|
|
@@ -5528,6 +5626,8 @@ var Order = class Order {
|
|
|
5528
5626
|
*/
|
|
5529
5627
|
requestedRedeem = null;
|
|
5530
5628
|
device;
|
|
5629
|
+
/** Device voids a failed cancel / refund call did not report yet. */
|
|
5630
|
+
unreported = [];
|
|
5531
5631
|
constructor(config, notify) {
|
|
5532
5632
|
this.draft = cloneOrder(config.order);
|
|
5533
5633
|
this.synced = cloneOrder(config.order);
|
|
@@ -5670,7 +5770,10 @@ var Order = class Order {
|
|
|
5670
5770
|
debounceMs,
|
|
5671
5771
|
persisted
|
|
5672
5772
|
};
|
|
5673
|
-
const d2 = {
|
|
5773
|
+
const d2 = {
|
|
5774
|
+
sleep: config.sleep,
|
|
5775
|
+
device: config.device
|
|
5776
|
+
};
|
|
5674
5777
|
return new Order({
|
|
5675
5778
|
...d1,
|
|
5676
5779
|
...d2
|
|
@@ -6138,6 +6241,80 @@ var Order = class Order {
|
|
|
6138
6241
|
await this.cancelOrder();
|
|
6139
6242
|
return outcomes;
|
|
6140
6243
|
}
|
|
6244
|
+
/**
|
|
6245
|
+
* Cancels this placed, not delivered order with one call to `/cancel`:
|
|
6246
|
+
* `VOID` (nothing charged) or `REVERSE` (charged), decided from the
|
|
6247
|
+
* fresh order. Device charges are voided first and their results go in
|
|
6248
|
+
* the same body (never `/payments`). The device credential of
|
|
6249
|
+
* `createOrder({ device })` / `fromExisting({ device })` is sent when
|
|
6250
|
+
* present. A delivered order throws before touching the device: use
|
|
6251
|
+
* `refund()`. A forced `type` that does not match throws too.
|
|
6252
|
+
*/
|
|
6253
|
+
async cancel(options = {}) {
|
|
6254
|
+
const decided = await this.freshCancelType();
|
|
6255
|
+
if (decided === "REFUND") throw new Error("Order is already delivered; use refund()");
|
|
6256
|
+
if (options.type && options.type !== decided) throw new Error(`Order takes ${decided}, not ${options.type}`);
|
|
6257
|
+
return this.runCancel("cancel", decided, options);
|
|
6258
|
+
}
|
|
6259
|
+
/**
|
|
6260
|
+
* Refunds this delivered order with one call to `/refund`
|
|
6261
|
+
* (`type: REFUND`): device charges are voided first and reported in the
|
|
6262
|
+
* body. Only the tenders change; the order status stays. An order not
|
|
6263
|
+
* delivered throws before touching the device: use `cancel()`.
|
|
6264
|
+
*/
|
|
6265
|
+
async refund(options = {}) {
|
|
6266
|
+
if (await this.freshCancelType() !== "REFUND") throw new Error("Order is not delivered; use cancel()");
|
|
6267
|
+
return this.runCancel("refund", "REFUND", options);
|
|
6268
|
+
}
|
|
6269
|
+
async freshCancelType() {
|
|
6270
|
+
if (!this.persisted) throw new Error("Only a placed order is cancelled");
|
|
6271
|
+
this.flush.cancel();
|
|
6272
|
+
this.applyServerOrder(await services.orders.get(this.draft.id, this.http));
|
|
6273
|
+
return cancelTypeOf(this.draft);
|
|
6274
|
+
}
|
|
6275
|
+
async runCancel(path, type, options) {
|
|
6276
|
+
const earlier = this.unreported;
|
|
6277
|
+
const done = new Set(earlier.map((reversal) => reversal.tender.id));
|
|
6278
|
+
const r1 = {
|
|
6279
|
+
tenderIds: options.tenderIds?.filter((id) => !done.has(id)),
|
|
6280
|
+
skip: done
|
|
6281
|
+
};
|
|
6282
|
+
const fresh = type === "VOID" ? [] : await this.payments.reverseOnDevice(r1);
|
|
6283
|
+
const reversals = [...earlier, ...fresh];
|
|
6284
|
+
const b1 = {
|
|
6285
|
+
type,
|
|
6286
|
+
tenders: reversals.map(toReportedTender),
|
|
6287
|
+
idempotency_key: createAttemptReference()
|
|
6288
|
+
};
|
|
6289
|
+
const b2 = options.reason ? { reason: options.reason } : {};
|
|
6290
|
+
const b3 = this.device ? { device: this.device } : {};
|
|
6291
|
+
const body = {
|
|
6292
|
+
...b1,
|
|
6293
|
+
...b2,
|
|
6294
|
+
...b3
|
|
6295
|
+
};
|
|
6296
|
+
const call = path === "refund" ? services.orders.refund : services.orders.cancel;
|
|
6297
|
+
let next;
|
|
6298
|
+
try {
|
|
6299
|
+
next = await call(this.draft.id, this.http, body);
|
|
6300
|
+
} catch (error) {
|
|
6301
|
+
this.unreported = reversals.filter(isDeviceReversed);
|
|
6302
|
+
throw error;
|
|
6303
|
+
}
|
|
6304
|
+
this.unreported = [];
|
|
6305
|
+
this.applyServerOrder(next);
|
|
6306
|
+
this.deleted = true;
|
|
6307
|
+
this.notify();
|
|
6308
|
+
const outcomes = reversals.map((reversal) => reversal.outcome);
|
|
6309
|
+
const pending = reversals.filter((reversal) => !isDeviceReversed(reversal)).map((reversal) => reversal.tender.id);
|
|
6310
|
+
return {
|
|
6311
|
+
order: this.getOrder(),
|
|
6312
|
+
type,
|
|
6313
|
+
path,
|
|
6314
|
+
outcomes,
|
|
6315
|
+
pending
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6141
6318
|
/** Voids one tender (operator flow); idempotent per call. */
|
|
6142
6319
|
async voidTender(tenderId, reason) {
|
|
6143
6320
|
const idempotency_key = createAttemptReference();
|
|
@@ -8982,4 +9159,4 @@ const cardPreviewGroups = (value) => {
|
|
|
8982
9159
|
return groups;
|
|
8983
9160
|
};
|
|
8984
9161
|
//#endregion
|
|
8985
|
-
export { CARD_BRANDS, DEFAULT_RECOMMENDATION_TYPES, ID_HASH_FORMATS, Order, OrderPaymentRequiredError, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, RecurringDateCron, RulesEngine, StorefrontHttpError, addLines, auth, buildCustomerSnapshot, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createDeunaWidgetApi, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isGenId, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, resolveModifierImageUrl, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
|
|
9162
|
+
export { CARD_BRANDS, DEFAULT_RECOMMENDATION_TYPES, ID_HASH_FORMATS, Order, OrderPaymentRequiredError, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, RecurringDateCron, RulesEngine, StorefrontHttpError, addLines, auth, buildCustomerSnapshot, cancelTypeOf, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createDeunaWidgetApi, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isGenId, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, resolveModifierImageUrl, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fire-spark/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Fire Spark headless SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"big.js": "6.2.1",
|
|
21
21
|
"dayjs": "1.11.9",
|
|
22
22
|
"@types/big.js": "6.2.2",
|
|
23
|
-
"@fire-spark/payments": "^0.
|
|
24
|
-
"@fire-spark/types": "^0.
|
|
23
|
+
"@fire-spark/payments": "^0.11.1",
|
|
24
|
+
"@fire-spark/types": "^0.11.1"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsdown": "^0.22.14",
|