@putiikkipalvelu/storefront-sdk 0.2.5 → 0.4.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.
- package/dist/index.cjs +400 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +432 -95
- package/dist/index.d.ts +432 -95
- package/dist/index.js +390 -161
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -419,6 +419,10 @@ interface CartResponse {
|
|
|
419
419
|
/** Cart ID for guest users (undefined for logged-in users) */
|
|
420
420
|
cartId?: string;
|
|
421
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Reason why a discount code was removed during validation
|
|
424
|
+
*/
|
|
425
|
+
type DiscountRemovalReason = "CAMPAIGN_ACTIVE" | "MIN_ORDER_NOT_MET" | "CODE_INVALID";
|
|
422
426
|
/**
|
|
423
427
|
* Changes detected during cart validation
|
|
424
428
|
*/
|
|
@@ -429,9 +433,16 @@ interface CartValidationChanges {
|
|
|
429
433
|
quantityAdjusted: number;
|
|
430
434
|
/** Number of items with changed price */
|
|
431
435
|
priceChanged: number;
|
|
436
|
+
/** Whether discount code was removed */
|
|
437
|
+
discountCouponRemoved: boolean;
|
|
438
|
+
/** Reason why discount was removed (only present if discountCouponRemoved is true) */
|
|
439
|
+
discountRemovalReason?: DiscountRemovalReason;
|
|
432
440
|
}
|
|
433
441
|
/**
|
|
434
442
|
* Response from GET /cart/validate
|
|
443
|
+
*
|
|
444
|
+
* Returns validated cart items and change metadata.
|
|
445
|
+
* No totals or discount data - those are calculated client-side or fetched separately.
|
|
435
446
|
*/
|
|
436
447
|
interface CartValidationResponse {
|
|
437
448
|
/** Validated cart items (with auto-fixed quantities/prices) */
|
|
@@ -507,21 +518,6 @@ interface CalculatedCartItem {
|
|
|
507
518
|
/** Total quantity in cart */
|
|
508
519
|
totalQuantity: number;
|
|
509
520
|
}
|
|
510
|
-
/**
|
|
511
|
-
* Free shipping eligibility status
|
|
512
|
-
*/
|
|
513
|
-
interface FreeShippingStatus {
|
|
514
|
-
/** Whether the cart qualifies for free shipping */
|
|
515
|
-
isEligible: boolean;
|
|
516
|
-
/** Minimum spend required for free shipping (in cents) */
|
|
517
|
-
minimumSpend: number;
|
|
518
|
-
/** Amount remaining to qualify for free shipping (in cents) */
|
|
519
|
-
remainingAmount: number;
|
|
520
|
-
/** Name of the free shipping campaign */
|
|
521
|
-
campaignName?: string;
|
|
522
|
-
/** IDs of shipment methods eligible for free shipping (when isEligible is true) */
|
|
523
|
-
eligibleShipmentMethodIds?: string[];
|
|
524
|
-
}
|
|
525
521
|
/**
|
|
526
522
|
* Result of cart calculation with campaigns applied
|
|
527
523
|
*/
|
|
@@ -534,21 +530,18 @@ interface CartCalculationResult {
|
|
|
534
530
|
originalTotal: number;
|
|
535
531
|
/** Total savings from campaigns (in cents) */
|
|
536
532
|
totalSavings: number;
|
|
537
|
-
/** Free shipping eligibility status */
|
|
538
|
-
freeShipping: FreeShippingStatus;
|
|
539
533
|
}
|
|
540
534
|
|
|
541
535
|
/**
|
|
542
536
|
* Shipping Types
|
|
543
537
|
*
|
|
544
538
|
* Types for shipment methods and pickup locations.
|
|
545
|
-
*
|
|
539
|
+
* Uses unified response format that works with any provider (Shipit, custom, future integrations).
|
|
546
540
|
*/
|
|
547
|
-
|
|
548
541
|
/**
|
|
549
542
|
* Opening hours for a pickup location
|
|
550
543
|
*/
|
|
551
|
-
interface
|
|
544
|
+
interface OpeningHours {
|
|
552
545
|
monday: string[];
|
|
553
546
|
tuesday: string[];
|
|
554
547
|
wednesday: string[];
|
|
@@ -559,57 +552,82 @@ interface PickupLocationOpeningHours {
|
|
|
559
552
|
exceptions: string[];
|
|
560
553
|
}
|
|
561
554
|
/**
|
|
562
|
-
* A
|
|
563
|
-
* Returned from Shipit API with shipmentMethodId and price attached
|
|
555
|
+
* A home delivery option (works for any provider)
|
|
564
556
|
*/
|
|
565
|
-
interface
|
|
566
|
-
/**
|
|
557
|
+
interface HomeDeliveryOption {
|
|
558
|
+
/** ShipmentMethods.id - unique identifier for this method */
|
|
567
559
|
id: string;
|
|
568
|
-
/**
|
|
560
|
+
/** Display name (e.g., "Posti Kotipaketti") */
|
|
561
|
+
name: string;
|
|
562
|
+
/** Optional description */
|
|
563
|
+
description: string | null;
|
|
564
|
+
/** Price in cents (0 if free shipping applies) */
|
|
565
|
+
price: number;
|
|
566
|
+
/** Original price in cents (always the base price before free shipping) */
|
|
567
|
+
originalPrice: number;
|
|
568
|
+
/** Free shipping threshold in cents, null = no free shipping available for this method */
|
|
569
|
+
freeShippingThreshold: number | null;
|
|
570
|
+
/** Carrier logo URL */
|
|
571
|
+
logo: string | null;
|
|
572
|
+
/** Provider type */
|
|
573
|
+
provider: "shipit" | "custom";
|
|
574
|
+
/** Carrier name (e.g., "Posti", "Matkahuolto") - null for custom methods */
|
|
575
|
+
carrier: string | null;
|
|
576
|
+
/** Estimated delivery time (e.g., "1-3") - null if not available */
|
|
577
|
+
estimatedDelivery: string | null;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* A pickup point option (parcel locker, service point, etc.)
|
|
581
|
+
* Works for any provider that supports pickup locations.
|
|
582
|
+
*/
|
|
583
|
+
interface PickupPointOption {
|
|
584
|
+
/** Unique pickup point ID from carrier */
|
|
585
|
+
id: string;
|
|
586
|
+
/** ShipmentMethods.id - needed for checkout */
|
|
587
|
+
shipmentMethodId: string;
|
|
588
|
+
/** Shipit service ID - needed for checkout and shipment creation */
|
|
569
589
|
serviceId: string;
|
|
570
|
-
/** Location name */
|
|
590
|
+
/** Location name (e.g., "Lidl Graniittitalo") */
|
|
571
591
|
name: string;
|
|
572
592
|
/** Street address */
|
|
573
|
-
|
|
593
|
+
address: string;
|
|
574
594
|
/** City */
|
|
575
595
|
city: string;
|
|
576
596
|
/** Postal code */
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
|
|
580
|
-
/**
|
|
581
|
-
|
|
597
|
+
postalCode: string;
|
|
598
|
+
/** Price in cents (0 if free shipping applies) */
|
|
599
|
+
price: number;
|
|
600
|
+
/** Original price in cents (always the base price before free shipping) */
|
|
601
|
+
originalPrice: number;
|
|
602
|
+
/** Free shipping threshold in cents, null = no free shipping available for this method */
|
|
603
|
+
freeShippingThreshold: number | null;
|
|
582
604
|
/** Carrier logo URL */
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
|
|
586
|
-
/**
|
|
587
|
-
|
|
588
|
-
/** Distance from postal code in meters */
|
|
589
|
-
|
|
590
|
-
/** Distance from postal code in kilometers */
|
|
591
|
-
distanceInKilometers: number;
|
|
592
|
-
/** Location type (e.g., "parcel_locker", "service_point", "outdoor_parcel_locker") */
|
|
593
|
-
type?: string;
|
|
605
|
+
logo: string | null;
|
|
606
|
+
/** Provider type */
|
|
607
|
+
provider: "shipit" | "custom";
|
|
608
|
+
/** Carrier name (e.g., "Posti", "Matkahuolto") */
|
|
609
|
+
carrier: string | null;
|
|
610
|
+
/** Distance from customer's postal code in meters */
|
|
611
|
+
distance: number | null;
|
|
594
612
|
/** Structured opening hours */
|
|
595
|
-
openingHours
|
|
596
|
-
/**
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
shipmentMethodId: string;
|
|
602
|
-
/** Price in cents (from store settings) */
|
|
603
|
-
price: number;
|
|
613
|
+
openingHours: OpeningHours | null;
|
|
614
|
+
/** GPS coordinates */
|
|
615
|
+
coordinates: {
|
|
616
|
+
lat: number;
|
|
617
|
+
lng: number;
|
|
618
|
+
} | null;
|
|
604
619
|
}
|
|
605
620
|
/**
|
|
606
621
|
* Response from GET /shipment-methods/[postalCode]
|
|
622
|
+
*
|
|
623
|
+
* Returns unified shipping options regardless of provider.
|
|
624
|
+
* Pickup points are sorted by distance, home delivery by price.
|
|
607
625
|
*/
|
|
608
|
-
interface
|
|
609
|
-
/** Home delivery
|
|
610
|
-
|
|
611
|
-
/** Pickup
|
|
612
|
-
|
|
626
|
+
interface ShipmentMethodsResponse {
|
|
627
|
+
/** Home delivery options (sorted by price) */
|
|
628
|
+
homeDelivery: HomeDeliveryOption[];
|
|
629
|
+
/** Pickup point options (sorted by distance) */
|
|
630
|
+
pickupPoints: PickupPointOption[];
|
|
613
631
|
}
|
|
614
632
|
|
|
615
633
|
/**
|
|
@@ -717,7 +735,7 @@ interface Order {
|
|
|
717
735
|
storeId: string;
|
|
718
736
|
/** Order creation timestamp */
|
|
719
737
|
createdAt: string;
|
|
720
|
-
/** Total order amount in cents */
|
|
738
|
+
/** Total order amount in cents (subtotal before discount) */
|
|
721
739
|
totalAmount: number;
|
|
722
740
|
/** Current order status */
|
|
723
741
|
status: OrderStatus;
|
|
@@ -729,6 +747,12 @@ interface Order {
|
|
|
729
747
|
orderCustomerData: ConfirmationOrderCustomerData | null;
|
|
730
748
|
/** Shipment method with tracking info */
|
|
731
749
|
orderShipmentMethod: ConfirmationOrderShipmentMethod | null;
|
|
750
|
+
/** Discount code string (e.g., "SUMMER20") - null if no discount applied */
|
|
751
|
+
discountCodeValue: string | null;
|
|
752
|
+
/** Discount amount in cents - null if no discount applied */
|
|
753
|
+
discountAmount: number | null;
|
|
754
|
+
/** VAT rate used for the discount calculation */
|
|
755
|
+
discountVatRate: number | null;
|
|
732
756
|
}
|
|
733
757
|
|
|
734
758
|
/**
|
|
@@ -1126,6 +1150,8 @@ interface CheckoutShipmentMethod {
|
|
|
1126
1150
|
shipmentMethodId: string;
|
|
1127
1151
|
/** ID of pickup point (for pickup delivery methods) */
|
|
1128
1152
|
pickupId: string | null;
|
|
1153
|
+
/** Shipit service ID (for Shipit pickup points) */
|
|
1154
|
+
serviceId: string | null;
|
|
1129
1155
|
}
|
|
1130
1156
|
/**
|
|
1131
1157
|
* Parameters for creating a checkout session
|
|
@@ -1223,6 +1249,104 @@ interface CheckoutErrorDetails {
|
|
|
1223
1249
|
[key: string]: unknown;
|
|
1224
1250
|
}
|
|
1225
1251
|
|
|
1252
|
+
/**
|
|
1253
|
+
* Discount Code Types
|
|
1254
|
+
*
|
|
1255
|
+
* Types for discount code API endpoints.
|
|
1256
|
+
*/
|
|
1257
|
+
/**
|
|
1258
|
+
* Type of discount
|
|
1259
|
+
*/
|
|
1260
|
+
type DiscountType = "PERCENTAGE" | "FIXED_AMOUNT";
|
|
1261
|
+
/**
|
|
1262
|
+
* Applied discount code information (stored in cart)
|
|
1263
|
+
*/
|
|
1264
|
+
interface AppliedDiscount {
|
|
1265
|
+
/** The discount code string */
|
|
1266
|
+
code: string;
|
|
1267
|
+
/** Type of discount */
|
|
1268
|
+
discountType: DiscountType;
|
|
1269
|
+
/** Discount value (percentage 1-100 or cents for fixed amount) */
|
|
1270
|
+
discountValue: number;
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Parameters for applying a discount code
|
|
1274
|
+
*/
|
|
1275
|
+
interface ApplyDiscountParams {
|
|
1276
|
+
/** The discount code to apply */
|
|
1277
|
+
code: string;
|
|
1278
|
+
/** Cart ID for guest users */
|
|
1279
|
+
cartId?: string;
|
|
1280
|
+
/** Session ID for logged-in users */
|
|
1281
|
+
sessionId?: string;
|
|
1282
|
+
/** Cart items for campaign conflict check (SDK uses this for instant validation) */
|
|
1283
|
+
cartItems?: CartItem[];
|
|
1284
|
+
/** Active campaigns for campaign conflict check (SDK uses this for instant validation) */
|
|
1285
|
+
campaigns?: Campaign[];
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Parameters for removing a discount code
|
|
1289
|
+
*/
|
|
1290
|
+
interface RemoveDiscountParams {
|
|
1291
|
+
/** Cart ID for guest users */
|
|
1292
|
+
cartId?: string;
|
|
1293
|
+
/** Session ID for logged-in users */
|
|
1294
|
+
sessionId?: string;
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Parameters for getting current discount
|
|
1298
|
+
*/
|
|
1299
|
+
interface GetDiscountParams {
|
|
1300
|
+
/** Cart ID for guest users */
|
|
1301
|
+
cartId?: string;
|
|
1302
|
+
/** Session ID for logged-in users */
|
|
1303
|
+
sessionId?: string;
|
|
1304
|
+
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Response from POST /discount-code/apply
|
|
1307
|
+
*
|
|
1308
|
+
* Note: No discountAmount returned - cart can change before checkout.
|
|
1309
|
+
* Calculate locally or get from cart validate if needed.
|
|
1310
|
+
*/
|
|
1311
|
+
interface ApplyDiscountResponse {
|
|
1312
|
+
/** Whether the discount was applied successfully */
|
|
1313
|
+
success: boolean;
|
|
1314
|
+
/** Applied discount details */
|
|
1315
|
+
discount: {
|
|
1316
|
+
code: string;
|
|
1317
|
+
discountType: DiscountType;
|
|
1318
|
+
discountValue: number;
|
|
1319
|
+
/** Minimum order amount for this code (in cents) - for UI display */
|
|
1320
|
+
minOrderAmount: number | null;
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Response from GET /discount-code/apply (get current discount)
|
|
1325
|
+
*
|
|
1326
|
+
* Returns stored discount data without re-validation.
|
|
1327
|
+
* Use /cart/validate for full validation.
|
|
1328
|
+
*/
|
|
1329
|
+
interface GetDiscountResponse {
|
|
1330
|
+
/** Current discount (null if none applied) */
|
|
1331
|
+
discount: AppliedDiscount | null;
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Response from DELETE /discount-code/apply
|
|
1335
|
+
*/
|
|
1336
|
+
interface RemoveDiscountResponse {
|
|
1337
|
+
/** Whether the discount was removed successfully */
|
|
1338
|
+
success: boolean;
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* Error response from discount code endpoints
|
|
1342
|
+
*/
|
|
1343
|
+
interface DiscountCodeError {
|
|
1344
|
+
/** Error message (Finnish, user-friendly) */
|
|
1345
|
+
error: string;
|
|
1346
|
+
/** Error code for programmatic use */
|
|
1347
|
+
code: "MISSING_CODE" | "MISSING_CART_TOTAL" | "CART_MISSING" | "NOT_FOUND" | "INACTIVE" | "NOT_STARTED" | "EXPIRED" | "MAX_USES_REACHED" | "MIN_ORDER_NOT_MET" | "CAMPAIGN_ACTIVE" | "INTERNAL_ERROR";
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1226
1350
|
/**
|
|
1227
1351
|
* Putiikkipalvelu Storefront SDK Types
|
|
1228
1352
|
*
|
|
@@ -1649,28 +1773,35 @@ declare function createCartResource(fetcher: Fetcher): {
|
|
|
1649
1773
|
* Checks product availability, stock levels, and prices.
|
|
1650
1774
|
* Auto-fixes issues (removes unavailable items, adjusts quantities).
|
|
1651
1775
|
*
|
|
1776
|
+
* Campaign conflict detection:
|
|
1777
|
+
* - SDK calculates if BuyXPayY campaigns apply using calculateCartWithCampaigns()
|
|
1778
|
+
* - Sends x-campaigns-apply header to backend
|
|
1779
|
+
* - If campaigns apply AND discount code exists, backend removes it
|
|
1780
|
+
* - Returns changes.discountCouponRemoved = true
|
|
1781
|
+
*
|
|
1652
1782
|
* @param options - Cart session options
|
|
1783
|
+
* @param cartItems - Current cart items for campaign calculation
|
|
1784
|
+
* @param campaigns - Active campaigns for conflict check
|
|
1653
1785
|
* @param fetchOptions - Fetch options
|
|
1654
1786
|
* @returns Validated cart with change metadata
|
|
1655
1787
|
*
|
|
1656
1788
|
* @example Validate before checkout
|
|
1657
1789
|
* ```typescript
|
|
1658
|
-
* const
|
|
1790
|
+
* const result = await client.cart.validate(
|
|
1791
|
+
* { cartId },
|
|
1792
|
+
* cartItems,
|
|
1793
|
+
* storeConfig.campaigns
|
|
1794
|
+
* );
|
|
1659
1795
|
*
|
|
1660
|
-
* if (hasChanges) {
|
|
1661
|
-
* if (changes.
|
|
1662
|
-
* notify(
|
|
1663
|
-
* }
|
|
1664
|
-
* if (changes.quantityAdjusted > 0) {
|
|
1665
|
-
* notify('Some quantities were adjusted');
|
|
1666
|
-
* }
|
|
1667
|
-
* if (changes.priceChanged > 0) {
|
|
1668
|
-
* notify('Some prices have changed');
|
|
1796
|
+
* if (result.hasChanges) {
|
|
1797
|
+
* if (result.changes.discountCouponRemoved) {
|
|
1798
|
+
* notify("Alennuskoodi poistettu - kampanja-alennus aktivoitui");
|
|
1669
1799
|
* }
|
|
1800
|
+
* // Handle other changes...
|
|
1670
1801
|
* }
|
|
1671
1802
|
* ```
|
|
1672
1803
|
*/
|
|
1673
|
-
validate(options?: CartSessionOptions, fetchOptions?: FetchOptions): Promise<CartValidationResponse>;
|
|
1804
|
+
validate(options?: CartSessionOptions, cartItems?: CartItem[], campaigns?: Campaign[], fetchOptions?: FetchOptions): Promise<CartValidationResponse>;
|
|
1674
1805
|
};
|
|
1675
1806
|
/**
|
|
1676
1807
|
* Type for the cart resource
|
|
@@ -1686,9 +1817,15 @@ type CartResource = ReturnType<typeof createCartResource>;
|
|
|
1686
1817
|
/**
|
|
1687
1818
|
* Options for fetching shipment methods with weight-based filtering
|
|
1688
1819
|
*/
|
|
1689
|
-
interface
|
|
1690
|
-
/** Cart items - weight will be calculated automatically */
|
|
1820
|
+
interface GetShippingOptionsParams extends FetchOptions {
|
|
1821
|
+
/** Cart items - weight and total will be calculated automatically */
|
|
1691
1822
|
cartItems?: CartItem[];
|
|
1823
|
+
/** Active campaigns - used to calculate cart total with discounts for free shipping */
|
|
1824
|
+
campaigns?: Campaign[];
|
|
1825
|
+
/** Discount amount in cents (from discount code) - subtracted from cart total for free shipping threshold */
|
|
1826
|
+
discountAmount?: number;
|
|
1827
|
+
/** Country code (default: "FI") */
|
|
1828
|
+
country?: string;
|
|
1692
1829
|
}
|
|
1693
1830
|
/**
|
|
1694
1831
|
* Shipping resource for fetching shipment methods and pickup locations
|
|
@@ -1696,40 +1833,55 @@ interface GetMethodsOptions extends FetchOptions {
|
|
|
1696
1833
|
declare function createShippingResource(fetcher: Fetcher): {
|
|
1697
1834
|
/**
|
|
1698
1835
|
* Get shipping options for a specific postal code.
|
|
1699
|
-
* Returns home delivery
|
|
1836
|
+
* Returns pickup points and home delivery options in a unified format.
|
|
1837
|
+
*
|
|
1838
|
+
* **Pickup points are returned first** as they are more popular in Finland.
|
|
1700
1839
|
*
|
|
1701
1840
|
* @param postalCode - Customer's postal code (e.g., "00100")
|
|
1702
1841
|
* @param options - Fetch options including optional cartItems for weight-based filtering
|
|
1703
|
-
* @returns
|
|
1842
|
+
* @returns Unified shipping options (pickupPoints sorted by distance, homeDelivery sorted by price)
|
|
1704
1843
|
*
|
|
1705
1844
|
* @example
|
|
1706
1845
|
* ```typescript
|
|
1707
|
-
* const {
|
|
1708
|
-
*
|
|
1709
|
-
* // Show
|
|
1710
|
-
*
|
|
1711
|
-
* console.log(`${
|
|
1846
|
+
* const { pickupPoints, homeDelivery } = await client.shipping.getOptions("00100");
|
|
1847
|
+
*
|
|
1848
|
+
* // Show pickup points (more popular in Finland)
|
|
1849
|
+
* pickupPoints.forEach(point => {
|
|
1850
|
+
* console.log(`${point.name} - ${point.carrier}`);
|
|
1851
|
+
* console.log(` ${point.address}, ${point.city}`);
|
|
1852
|
+
* console.log(` ${(point.distance! / 1000).toFixed(1)} km away`);
|
|
1853
|
+
* console.log(` Price: ${point.price / 100}€`);
|
|
1712
1854
|
* });
|
|
1713
1855
|
*
|
|
1714
|
-
* // Show
|
|
1715
|
-
*
|
|
1716
|
-
* console.log(`${
|
|
1717
|
-
*
|
|
1718
|
-
*
|
|
1719
|
-
*
|
|
1856
|
+
* // Show home delivery options
|
|
1857
|
+
* homeDelivery.forEach(option => {
|
|
1858
|
+
* console.log(`${option.name}: ${option.price / 100}€`);
|
|
1859
|
+
* if (option.estimatedDelivery) {
|
|
1860
|
+
* console.log(` Delivery: ${option.estimatedDelivery} days`);
|
|
1861
|
+
* }
|
|
1720
1862
|
* });
|
|
1721
1863
|
* ```
|
|
1722
1864
|
*
|
|
1723
1865
|
* @example Weight-based filtering
|
|
1724
1866
|
* ```typescript
|
|
1725
|
-
* const
|
|
1726
|
-
*
|
|
1727
|
-
*
|
|
1728
|
-
* );
|
|
1867
|
+
* const options = await client.shipping.getOptions("00100", {
|
|
1868
|
+
* cartItems: cartItems
|
|
1869
|
+
* });
|
|
1729
1870
|
* // Only shows methods that support the cart's total weight
|
|
1730
1871
|
* ```
|
|
1872
|
+
*
|
|
1873
|
+
* @example International shipping
|
|
1874
|
+
* ```typescript
|
|
1875
|
+
* const options = await client.shipping.getOptions("112 22", {
|
|
1876
|
+
* country: "SE"
|
|
1877
|
+
* });
|
|
1878
|
+
* ```
|
|
1731
1879
|
*/
|
|
1732
|
-
|
|
1880
|
+
getOptions(postalCode: string, options?: GetShippingOptionsParams): Promise<ShipmentMethodsResponse>;
|
|
1881
|
+
/**
|
|
1882
|
+
* @deprecated Use getOptions() instead. This method is kept for backwards compatibility.
|
|
1883
|
+
*/
|
|
1884
|
+
getWithLocations(postalCode: string, options?: GetShippingOptionsParams): Promise<ShipmentMethodsResponse>;
|
|
1733
1885
|
};
|
|
1734
1886
|
/**
|
|
1735
1887
|
* Type for the shipping resource
|
|
@@ -2275,6 +2427,70 @@ declare function createCheckoutResource(fetcher: Fetcher): {
|
|
|
2275
2427
|
*/
|
|
2276
2428
|
type CheckoutResource = ReturnType<typeof createCheckoutResource>;
|
|
2277
2429
|
|
|
2430
|
+
/**
|
|
2431
|
+
* Discount Code Resource
|
|
2432
|
+
*
|
|
2433
|
+
* Provides methods for managing discount codes in the cart.
|
|
2434
|
+
*/
|
|
2435
|
+
|
|
2436
|
+
/**
|
|
2437
|
+
* Creates the discount code resource with methods for managing discount codes.
|
|
2438
|
+
*/
|
|
2439
|
+
declare function createDiscountCodeResource(fetcher: Fetcher): {
|
|
2440
|
+
/**
|
|
2441
|
+
* Apply a discount code to the cart
|
|
2442
|
+
*
|
|
2443
|
+
* Checks for BuyXPayY campaign conflict before calling API.
|
|
2444
|
+
* Discount codes cannot be used when a campaign discount is active.
|
|
2445
|
+
*
|
|
2446
|
+
* @param params - Parameters including code, session info, and cart/campaign data for conflict check
|
|
2447
|
+
* @returns Applied discount details
|
|
2448
|
+
* @throws {StorefrontError} With code "CAMPAIGN_ACTIVE" if a BuyXPayY campaign is active
|
|
2449
|
+
*
|
|
2450
|
+
* @example
|
|
2451
|
+
* ```typescript
|
|
2452
|
+
* const result = await client.discountCode.apply({
|
|
2453
|
+
* code: "SUMMER20",
|
|
2454
|
+
* cartId: cartId,
|
|
2455
|
+
* cartItems: cart.items,
|
|
2456
|
+
* campaigns: storeConfig.campaigns,
|
|
2457
|
+
* });
|
|
2458
|
+
* ```
|
|
2459
|
+
*/
|
|
2460
|
+
apply(params: ApplyDiscountParams): Promise<ApplyDiscountResponse>;
|
|
2461
|
+
/**
|
|
2462
|
+
* Get the currently applied discount code
|
|
2463
|
+
*
|
|
2464
|
+
* @param params - Session info (cartId or sessionId)
|
|
2465
|
+
* @returns Current discount or null if none applied
|
|
2466
|
+
*
|
|
2467
|
+
* @example
|
|
2468
|
+
* ```typescript
|
|
2469
|
+
* const { discount } = await client.discountCode.get({ cartId });
|
|
2470
|
+
* if (discount) {
|
|
2471
|
+
* console.log(`Code ${discount.code}: ${discount.discountValue}${discount.discountType === 'PERCENTAGE' ? '%' : '¢'} off`);
|
|
2472
|
+
* }
|
|
2473
|
+
* ```
|
|
2474
|
+
*/
|
|
2475
|
+
get(params?: GetDiscountParams): Promise<GetDiscountResponse>;
|
|
2476
|
+
/**
|
|
2477
|
+
* Remove the currently applied discount code
|
|
2478
|
+
*
|
|
2479
|
+
* @param params - Session info (cartId or sessionId)
|
|
2480
|
+
* @returns Success status
|
|
2481
|
+
*
|
|
2482
|
+
* @example
|
|
2483
|
+
* ```typescript
|
|
2484
|
+
* await client.discountCode.remove({ cartId });
|
|
2485
|
+
* ```
|
|
2486
|
+
*/
|
|
2487
|
+
remove(params?: RemoveDiscountParams): Promise<RemoveDiscountResponse>;
|
|
2488
|
+
};
|
|
2489
|
+
/**
|
|
2490
|
+
* Type for the discount code resource
|
|
2491
|
+
*/
|
|
2492
|
+
type DiscountCodeResource = ReturnType<typeof createDiscountCodeResource>;
|
|
2493
|
+
|
|
2278
2494
|
/**
|
|
2279
2495
|
* The Storefront API client
|
|
2280
2496
|
*/
|
|
@@ -2315,6 +2531,10 @@ interface StorefrontClient {
|
|
|
2315
2531
|
* Checkout resource for payment processing
|
|
2316
2532
|
*/
|
|
2317
2533
|
readonly checkout: CheckoutResource;
|
|
2534
|
+
/**
|
|
2535
|
+
* Discount code resource for applying/removing discount codes
|
|
2536
|
+
*/
|
|
2537
|
+
readonly discountCode: DiscountCodeResource;
|
|
2318
2538
|
}
|
|
2319
2539
|
/**
|
|
2320
2540
|
* Create a new Storefront API client
|
|
@@ -2378,13 +2598,11 @@ declare function getPriceInfo(product: ProductDetail, variation?: ProductVariati
|
|
|
2378
2598
|
/**
|
|
2379
2599
|
* Calculate cart totals with campaign discounts applied.
|
|
2380
2600
|
*
|
|
2381
|
-
* Supports
|
|
2382
|
-
* - **FREE_SHIPPING**: Free shipping when cart total exceeds minimum spend
|
|
2383
|
-
* - **BUY_X_PAY_Y**: Buy X items, pay for Y (e.g., Buy 3 Pay 2 = 1 free item)
|
|
2601
|
+
* Supports BUY_X_PAY_Y campaigns: Buy X items, pay for Y (e.g., Buy 3 Pay 2 = 1 free item)
|
|
2384
2602
|
*
|
|
2385
2603
|
* @param items - Cart items to calculate
|
|
2386
2604
|
* @param campaigns - Active campaigns to apply
|
|
2387
|
-
* @returns Calculation result with totals
|
|
2605
|
+
* @returns Calculation result with totals and savings
|
|
2388
2606
|
*
|
|
2389
2607
|
* @example
|
|
2390
2608
|
* ```typescript
|
|
@@ -2392,7 +2610,6 @@ declare function getPriceInfo(product: ProductDetail, variation?: ProductVariati
|
|
|
2392
2610
|
*
|
|
2393
2611
|
* console.log(result.cartTotal); // 4990 (cents)
|
|
2394
2612
|
* console.log(result.totalSavings); // 1990 (cents)
|
|
2395
|
-
* console.log(result.freeShipping.isEligible); // true
|
|
2396
2613
|
*
|
|
2397
2614
|
* // Render calculated items
|
|
2398
2615
|
* result.calculatedItems.forEach(({ item, paidQuantity, freeQuantity }) => {
|
|
@@ -2402,6 +2619,126 @@ declare function getPriceInfo(product: ProductDetail, variation?: ProductVariati
|
|
|
2402
2619
|
*/
|
|
2403
2620
|
declare function calculateCartWithCampaigns(items: CartItem[], campaigns: Campaign[]): CartCalculationResult;
|
|
2404
2621
|
|
|
2622
|
+
/**
|
|
2623
|
+
* Discount Code Utilities
|
|
2624
|
+
*
|
|
2625
|
+
* Helper functions for working with discount codes.
|
|
2626
|
+
*/
|
|
2627
|
+
|
|
2628
|
+
/**
|
|
2629
|
+
* Options for formatting discount values
|
|
2630
|
+
*/
|
|
2631
|
+
interface FormatDiscountOptions {
|
|
2632
|
+
/**
|
|
2633
|
+
* Currency symbol to use for fixed amount discounts
|
|
2634
|
+
* @default "€"
|
|
2635
|
+
*/
|
|
2636
|
+
currencySymbol?: string;
|
|
2637
|
+
/**
|
|
2638
|
+
* Whether to show the currency symbol before or after the value
|
|
2639
|
+
* @default "after"
|
|
2640
|
+
*/
|
|
2641
|
+
currencyPosition?: "before" | "after";
|
|
2642
|
+
/**
|
|
2643
|
+
* Number of decimal places for fixed amount
|
|
2644
|
+
* @default 2
|
|
2645
|
+
*/
|
|
2646
|
+
decimals?: number;
|
|
2647
|
+
/**
|
|
2648
|
+
* Whether to include the minus sign prefix
|
|
2649
|
+
* @default true
|
|
2650
|
+
*/
|
|
2651
|
+
showMinus?: boolean;
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* Format a discount value for display.
|
|
2655
|
+
*
|
|
2656
|
+
* @param discount - The applied discount (or just type and value)
|
|
2657
|
+
* @param options - Formatting options
|
|
2658
|
+
* @returns Formatted discount string (e.g., "-20%" or "-5,00 €")
|
|
2659
|
+
*
|
|
2660
|
+
* @example
|
|
2661
|
+
* ```typescript
|
|
2662
|
+
* // Percentage discount
|
|
2663
|
+
* formatDiscountValue({ discountType: "PERCENTAGE", discountValue: 20 });
|
|
2664
|
+
* // Returns: "-20%"
|
|
2665
|
+
*
|
|
2666
|
+
* // Fixed amount discount (value in cents)
|
|
2667
|
+
* formatDiscountValue({ discountType: "FIXED_AMOUNT", discountValue: 500 });
|
|
2668
|
+
* // Returns: "-5,00 €"
|
|
2669
|
+
*
|
|
2670
|
+
* // Custom currency
|
|
2671
|
+
* formatDiscountValue(
|
|
2672
|
+
* { discountType: "FIXED_AMOUNT", discountValue: 1000 },
|
|
2673
|
+
* { currencySymbol: "$", currencyPosition: "before" }
|
|
2674
|
+
* );
|
|
2675
|
+
* // Returns: "-$10.00"
|
|
2676
|
+
* ```
|
|
2677
|
+
*/
|
|
2678
|
+
declare function formatDiscountValue(discount: Pick<AppliedDiscount, "discountType" | "discountValue">, options?: FormatDiscountOptions): string;
|
|
2679
|
+
/**
|
|
2680
|
+
* Calculate the discount amount in cents.
|
|
2681
|
+
*
|
|
2682
|
+
* @param subtotal - Cart subtotal in cents (before discount)
|
|
2683
|
+
* @param discount - The applied discount
|
|
2684
|
+
* @returns Discount amount in cents (always positive)
|
|
2685
|
+
*
|
|
2686
|
+
* @example
|
|
2687
|
+
* ```typescript
|
|
2688
|
+
* // 20% off 100€ subtotal
|
|
2689
|
+
* calculateDiscountAmount(10000, { discountType: "PERCENTAGE", discountValue: 20 });
|
|
2690
|
+
* // Returns: 2000 (20€ in cents)
|
|
2691
|
+
*
|
|
2692
|
+
* // Fixed 5€ discount
|
|
2693
|
+
* calculateDiscountAmount(10000, { discountType: "FIXED_AMOUNT", discountValue: 500 });
|
|
2694
|
+
* // Returns: 500 (5€ in cents)
|
|
2695
|
+
*
|
|
2696
|
+
* // Fixed discount larger than subtotal (capped)
|
|
2697
|
+
* calculateDiscountAmount(300, { discountType: "FIXED_AMOUNT", discountValue: 500 });
|
|
2698
|
+
* // Returns: 300 (capped to subtotal)
|
|
2699
|
+
* ```
|
|
2700
|
+
*/
|
|
2701
|
+
declare function calculateDiscountAmount(subtotal: number, discount: Pick<AppliedDiscount, "discountType" | "discountValue">): number;
|
|
2702
|
+
/**
|
|
2703
|
+
* Supported locales for error messages
|
|
2704
|
+
*/
|
|
2705
|
+
type DiscountMessageLocale = "fi" | "en";
|
|
2706
|
+
/**
|
|
2707
|
+
* Get a user-friendly message for discount removal reason.
|
|
2708
|
+
*
|
|
2709
|
+
* @param reason - The removal reason from cart validation
|
|
2710
|
+
* @param locale - Locale for the message (fi or en)
|
|
2711
|
+
* @returns Localized user-friendly message
|
|
2712
|
+
*
|
|
2713
|
+
* @example
|
|
2714
|
+
* ```typescript
|
|
2715
|
+
* getDiscountRemovalMessage("CAMPAIGN_ACTIVE", "fi");
|
|
2716
|
+
* // Returns: "Alennuskoodi poistettu - kampanja-alennus aktivoitui"
|
|
2717
|
+
*
|
|
2718
|
+
* getDiscountRemovalMessage("MIN_ORDER_NOT_MET", "en");
|
|
2719
|
+
* // Returns: "Discount code removed - cart total below minimum order"
|
|
2720
|
+
* ```
|
|
2721
|
+
*/
|
|
2722
|
+
declare function getDiscountRemovalMessage(reason: DiscountRemovalReason | undefined, locale?: DiscountMessageLocale): string;
|
|
2723
|
+
/**
|
|
2724
|
+
* Error codes from discount code apply endpoint
|
|
2725
|
+
*/
|
|
2726
|
+
type DiscountApplyErrorCode = "NOT_FOUND" | "INACTIVE" | "NOT_STARTED" | "EXPIRED" | "MAX_USES_REACHED" | "MIN_ORDER_NOT_MET" | "CAMPAIGN_ACTIVE";
|
|
2727
|
+
/**
|
|
2728
|
+
* Get a user-friendly message for discount apply error.
|
|
2729
|
+
*
|
|
2730
|
+
* @param errorCode - The error code from apply endpoint
|
|
2731
|
+
* @param locale - Locale for the message (fi or en)
|
|
2732
|
+
* @returns Localized user-friendly message
|
|
2733
|
+
*
|
|
2734
|
+
* @example
|
|
2735
|
+
* ```typescript
|
|
2736
|
+
* getDiscountApplyErrorMessage("EXPIRED", "fi");
|
|
2737
|
+
* // Returns: "Alennuskoodi on vanhentunut"
|
|
2738
|
+
* ```
|
|
2739
|
+
*/
|
|
2740
|
+
declare function getDiscountApplyErrorMessage(errorCode: DiscountApplyErrorCode | string | undefined, locale?: DiscountMessageLocale): string;
|
|
2741
|
+
|
|
2405
2742
|
/**
|
|
2406
2743
|
* Base error class for all Storefront API errors
|
|
2407
2744
|
*/
|
|
@@ -2445,4 +2782,4 @@ declare class VerificationRequiredError extends StorefrontError {
|
|
|
2445
2782
|
constructor(message: string, customerId: string);
|
|
2446
2783
|
}
|
|
2447
2784
|
|
|
2448
|
-
export { type AddToCartParams, type AddToWishlistResponse, AuthError, type BuyXPayYCampaign, type CalculatedCartItem, type Campaign, type CampaignType, type CartCalculationResult, type CartItem, type CartResponse, type CartSessionOptions, type CartValidationChanges, type CartValidationResponse, type Category, type CategoryReference, type CategoryResponse, type CheckoutCustomerData, type CheckoutErrorCode, type CheckoutErrorDetails, type CheckoutOptions, type CheckoutParams, type CheckoutShipmentMethod, type ConfirmationItemType, type ConfirmationOrderCustomerData, type ConfirmationOrderLineItem, type ConfirmationOrderShipmentMethod, type Customer, type CustomerOrder, type DeleteAccountResponse, type FeatureFlags, type FetchOptions, type ForgotPasswordResponse, type
|
|
2785
|
+
export { type AddToCartParams, type AddToWishlistResponse, type AppliedDiscount, type ApplyDiscountParams, type ApplyDiscountResponse, AuthError, type BuyXPayYCampaign, type CalculatedCartItem, type Campaign, type CampaignType, type CartCalculationResult, type CartItem, type CartResponse, type CartSessionOptions, type CartValidationChanges, type CartValidationResponse, type Category, type CategoryReference, type CategoryResponse, type CheckoutCustomerData, type CheckoutErrorCode, type CheckoutErrorDetails, type CheckoutOptions, type CheckoutParams, type CheckoutShipmentMethod, type ConfirmationItemType, type ConfirmationOrderCustomerData, type ConfirmationOrderLineItem, type ConfirmationOrderShipmentMethod, type Customer, type CustomerOrder, type DeleteAccountResponse, type DiscountApplyErrorCode, type DiscountCodeError, type DiscountMessageLocale, type DiscountRemovalReason, type DiscountType, type FeatureFlags, type FetchOptions, type ForgotPasswordResponse, type FormatDiscountOptions, type GetDiscountParams, type GetDiscountResponse, type GetOrdersResponse, type GetUserResponse, type HomeDeliveryOption, type LoginOptions, type LoginResponse, type LoginVerificationRequiredResponse, type LogoutResponse, NotFoundError, type OpeningHours, type Order, type OrderLineItem, type OrderProductInfo, type OrderShipmentMethod, type OrderStatus, type PaymentConfig, type PaytrailCheckoutResponse, type PaytrailGroup, type PaytrailProvider, type PickupPointOption, type PriceInfo, type Product, type ProductCountResponse, type ProductDetail, type ProductListParams, type ProductListResponse, type ProductSortOption, type ProductVariation, type ProductVariationListing, RateLimitError, type RegisterData, type RegisterResponse, type RemoveDiscountParams, type RemoveDiscountResponse, type RemoveFromCartParams, type RemoveFromWishlistResponse, type ResendVerificationResponse, type ResetPasswordResponse, type ShipitShippingMethod, type ShipmentMethod, type ShipmentMethodsResponse, type StoreConfig, type StoreInfo, type StoreSeo, type StorefrontClient, type StorefrontClientConfig, StorefrontError, type StripeCheckoutResponse, type UpdateCartQuantityParams, type UpdateProfileData, type UpdateProfileResponse, ValidationError, type VariationOption, VerificationRequiredError, type VerifyEmailResponse, type WishlistItem, type WishlistProduct, type WishlistResponse, type WishlistVariation, type WishlistVariationOption, calculateCartWithCampaigns, calculateDiscountAmount, createStorefrontClient, formatDiscountValue, getDiscountApplyErrorMessage, getDiscountRemovalMessage, getPriceInfo, isSaleActive };
|