@moonbase.sh/storefront 3.9.0 → 3.11.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/README.md +72 -0
- package/dist/moonbase.d.ts +112 -136
- package/dist/moonbase.js +9476 -8912
- package/dist/moonbase.umd.cjs +17 -17
- package/dist-loader/moonbase.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -496,10 +496,82 @@ Available events include:
|
|
|
496
496
|
- `downloaded-product`
|
|
497
497
|
- `activated-product`
|
|
498
498
|
- `added-to-cart`
|
|
499
|
+
- `coupon-rejected`
|
|
499
500
|
- `checkout-initiated`
|
|
501
|
+
- `checkout-billing-details-added`
|
|
502
|
+
- `checkout-coupon-applied`
|
|
503
|
+
- `checkout-coupon-removed`
|
|
504
|
+
- `checkout-payment-started`
|
|
505
|
+
- `checkout-payment-failed`
|
|
500
506
|
- `checkout-closed`
|
|
501
507
|
- `checkout-completed`
|
|
502
508
|
|
|
509
|
+
The checkout's own progress, from billing details to payment, is reported only by the checkout
|
|
510
|
+
that opens on your page:
|
|
511
|
+
|
|
512
|
+
- `checkout-billing-details-added` fires each time the buyer saves their billing details.
|
|
513
|
+
- `checkout-payment-started` fires for each attempt to pay, and is followed by
|
|
514
|
+
`checkout-payment-failed` or `checkout-completed`.
|
|
515
|
+
- `checkout-payment-failed` carries `error`, with `reason` and `paymentMethod` (such as `card`).
|
|
516
|
+
The reason is one of `Declined` (by the card issuer or fraud screening: try another card),
|
|
517
|
+
`AuthenticationFailed` (3-D Secure not passed), `CardDetails` (a wrong number, security code or
|
|
518
|
+
postcode, or an expired card), `ProcessingError` (trying again may work) or `Other`. The card
|
|
519
|
+
issuer's own decline code is never passed on. The checkout stays open for the buyer to try again.
|
|
520
|
+
- `checkout-coupon-applied` and `checkout-coupon-removed` carry the `code`. A code the checkout
|
|
521
|
+
refuses fires `coupon-rejected`, with the `message` the buyer saw.
|
|
522
|
+
- `checkout-closed` carries `completed`, and `checkoutOrder`, the order the checkout was open for.
|
|
523
|
+
Its `order` is the cart, which for a direct purchase is a different order.
|
|
524
|
+
|
|
525
|
+
During a full-page redirect to the hosted checkout (`checkout.redirect`, and on phones by default)
|
|
526
|
+
your page is not loaded, so only `checkout-completed` reaches it, once the buyer is back. To follow
|
|
527
|
+
every checkout, hosted included, subscribe a webhook to `OrderCheckoutInitiated` (billing details
|
|
528
|
+
saved) and `OrderPaymentFailed`.
|
|
529
|
+
|
|
530
|
+
```ts
|
|
531
|
+
Moonbase.on(MoonbaseEvent.CheckoutPaymentFailed, ({ order, error }) => {
|
|
532
|
+
console.log(`Payment for ${order.id} failed: ${error.reason}`)
|
|
533
|
+
})
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
`signed-in` and `signed-up` fire on the page where the customer signs in, including through a link in an email. `signed-out` also fires when the session ends without anyone signing out on the page: in another tab, or elsewhere (for example a password change on another device), which the widget finds out when it next renews the token.
|
|
537
|
+
|
|
538
|
+
## Calling your own API
|
|
539
|
+
|
|
540
|
+
`Moonbase.getAccessToken()` resolves to the signed-in customer's access token, or `null` when nobody is signed in. Send it to your own API to act on the customer's behalf. It's renewed first when it's about to run out, so call it for each request rather than keeping a copy.
|
|
541
|
+
|
|
542
|
+
```ts
|
|
543
|
+
const token = await Moonbase.getAccessToken()
|
|
544
|
+
const response = await fetch('https://api.example.com/presets', {
|
|
545
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {},
|
|
546
|
+
})
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
The token is a JWT signed with your account's key. Verify it on your server against the JWK Set at `https://<account-id>.moonbase.sh/api/key/jwks`, and check all of:
|
|
550
|
+
|
|
551
|
+
- the `typ` header is `at+jwt` and the algorithm is `RS256`
|
|
552
|
+
- the issuer (`iss`) is your Account ID
|
|
553
|
+
- the audience (`aud`) is `https://moonbase.sh`
|
|
554
|
+
- the expiry (`exp`) is present and hasn't passed
|
|
555
|
+
|
|
556
|
+
License tokens are signed with the same key and issuer, so a check that skips the audience or the expiry accepts a license file as a sign-in. The customer's ID is the `sub` claim. With [jose](https://github.com/panva/jose):
|
|
557
|
+
|
|
558
|
+
```ts
|
|
559
|
+
import { createRemoteJWKSet, jwtVerify } from 'jose'
|
|
560
|
+
|
|
561
|
+
const jwks = createRemoteJWKSet(new URL('https://acme.moonbase.sh/api/key/jwks'))
|
|
562
|
+
|
|
563
|
+
const { payload } = await jwtVerify(token, jwks, {
|
|
564
|
+
typ: 'at+jwt',
|
|
565
|
+
algorithms: ['RS256'],
|
|
566
|
+
issuer: 'acme',
|
|
567
|
+
audience: 'https://moonbase.sh',
|
|
568
|
+
requiredClaims: ['exp'],
|
|
569
|
+
})
|
|
570
|
+
// payload.sub is the customer's ID
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
Don't read the widget's `localStorage` entry yourself: it holds the refresh token as well, which must never leave the browser.
|
|
574
|
+
|
|
503
575
|
## Integrations
|
|
504
576
|
|
|
505
577
|
The widget can forward its commerce and auth events to common marketing/analytics SDKs without any extra glue code. Enable a provider by passing its config in `integrations`:
|
package/dist/moonbase.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ActivationRequestFulfillmentType } from '@moonbase.sh/vue';
|
|
2
2
|
import { CartItem } from '@moonbase.sh/vue';
|
|
3
|
+
import { CheckoutPaymentFailure } from '@moonbase.sh/vue';
|
|
3
4
|
import { CheckoutRedirectMode } from '@moonbase.sh/vue';
|
|
4
5
|
import { CurrencyDisplay } from '@moonbase.sh/vue';
|
|
5
6
|
import { Download } from '@moonbase.sh/vue';
|
|
@@ -28,10 +29,7 @@ export declare interface GoogleAnalyticsConfig {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export declare interface GoogleTagManagerConfig {
|
|
31
|
-
/**
|
|
32
|
-
* Informational/reserved. GTM containers read from `window.dataLayer`
|
|
33
|
-
* regardless of which container loaded them, so this is not used at runtime.
|
|
34
|
-
*/
|
|
32
|
+
/** Not used: GTM reads `window.dataLayer` whichever container loaded it. */
|
|
35
33
|
containerId?: string;
|
|
36
34
|
}
|
|
37
35
|
|
|
@@ -88,6 +86,11 @@ export declare enum MoonbaseEvent {
|
|
|
88
86
|
AddedToCart = "added-to-cart",
|
|
89
87
|
CouponRejected = "coupon-rejected",
|
|
90
88
|
CheckoutInitiated = "checkout-initiated",
|
|
89
|
+
CheckoutBillingDetailsAdded = "checkout-billing-details-added",
|
|
90
|
+
CheckoutCouponApplied = "checkout-coupon-applied",
|
|
91
|
+
CheckoutCouponRemoved = "checkout-coupon-removed",
|
|
92
|
+
CheckoutPaymentStarted = "checkout-payment-started",
|
|
93
|
+
CheckoutPaymentFailed = "checkout-payment-failed",
|
|
91
94
|
CheckoutClosed = "checkout-closed",
|
|
92
95
|
CheckoutCompleted = "checkout-completed"
|
|
93
96
|
}
|
|
@@ -166,6 +169,11 @@ export declare interface MoonbaseEventArgs {
|
|
|
166
169
|
};
|
|
167
170
|
[MoonbaseEvent.CouponRejected]: {
|
|
168
171
|
code: string;
|
|
172
|
+
/**
|
|
173
|
+
* Why, as the buyer was told, when the checkout refused a code typed into
|
|
174
|
+
* it. Absent for a code passed to the `purchase` intent.
|
|
175
|
+
*/
|
|
176
|
+
message?: string;
|
|
169
177
|
user?: User | null;
|
|
170
178
|
};
|
|
171
179
|
[MoonbaseEvent.CheckoutInitiated]: {
|
|
@@ -173,8 +181,61 @@ export declare interface MoonbaseEventArgs {
|
|
|
173
181
|
total: Money;
|
|
174
182
|
user?: User | null;
|
|
175
183
|
};
|
|
184
|
+
/**
|
|
185
|
+
* The buyer saved their billing details in the checkout. Sent again each time
|
|
186
|
+
* they change them. Only from the checkout that opens on the page, not the
|
|
187
|
+
* hosted one a redirect goes to.
|
|
188
|
+
*/
|
|
189
|
+
[MoonbaseEvent.CheckoutBillingDetailsAdded]: {
|
|
190
|
+
order: OpenOrder;
|
|
191
|
+
user?: User | null;
|
|
192
|
+
};
|
|
193
|
+
/** The buyer applied a coupon code in the checkout. On-page checkout only. */
|
|
194
|
+
[MoonbaseEvent.CheckoutCouponApplied]: {
|
|
195
|
+
order: OpenOrder;
|
|
196
|
+
code: string;
|
|
197
|
+
user?: User | null;
|
|
198
|
+
};
|
|
199
|
+
/** The buyer took a coupon off the order in the checkout. On-page checkout only. */
|
|
200
|
+
[MoonbaseEvent.CheckoutCouponRemoved]: {
|
|
201
|
+
order: OpenOrder;
|
|
202
|
+
code: string;
|
|
203
|
+
user?: User | null;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* The buyer submitted payment in the checkout. Each attempt is followed by
|
|
207
|
+
* `checkout-payment-failed` or `checkout-completed`. On-page checkout only.
|
|
208
|
+
*/
|
|
209
|
+
[MoonbaseEvent.CheckoutPaymentStarted]: {
|
|
210
|
+
order: OpenOrder;
|
|
211
|
+
user?: User | null;
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* An attempt to pay failed: a declined card, or a 3-D Secure check the buyer
|
|
215
|
+
* did not pass. The checkout stays open for them to try again. `error.reason`
|
|
216
|
+
* says what kind of failure it was; the card issuer's own decline code is
|
|
217
|
+
* never passed on. On-page checkout only: for every checkout, hosted
|
|
218
|
+
* included, subscribe a webhook to `OrderPaymentFailed`.
|
|
219
|
+
*/
|
|
220
|
+
[MoonbaseEvent.CheckoutPaymentFailed]: {
|
|
221
|
+
order: OpenOrder;
|
|
222
|
+
error: CheckoutPaymentFailure;
|
|
223
|
+
user?: User | null;
|
|
224
|
+
};
|
|
176
225
|
[MoonbaseEvent.CheckoutClosed]: {
|
|
226
|
+
/**
|
|
227
|
+
* The cart. For a direct purchase (the `purchase` intent, a buy button)
|
|
228
|
+
* this is not the order the checkout was for: read `checkoutOrder`.
|
|
229
|
+
*/
|
|
177
230
|
order: Order;
|
|
231
|
+
/** The order the checkout was open for. Absent if it closed before it loaded. */
|
|
232
|
+
checkoutOrder?: Order;
|
|
233
|
+
/**
|
|
234
|
+
* Whether the checkout completed the order before it closed, the same
|
|
235
|
+
* moment `checkout-completed` fires. An order that was paid but could not
|
|
236
|
+
* be fulfilled is not completed, and fires neither.
|
|
237
|
+
*/
|
|
238
|
+
completed: boolean;
|
|
178
239
|
user?: User | null;
|
|
179
240
|
};
|
|
180
241
|
[MoonbaseEvent.CheckoutCompleted]: {
|
|
@@ -202,6 +263,7 @@ declare class MoonbaseImpl implements MoonbaseInstance {
|
|
|
202
263
|
setup(url: string, options?: DeepPartial<MoonbaseOptions>): Promise<void>;
|
|
203
264
|
configure(options: DeepPartial<MoonbaseOptions>): void;
|
|
204
265
|
on<TEvent extends MoonbaseEvent>(eventType: TEvent, callback: (event: MoonbaseEventArgs[TEvent]) => void): void;
|
|
266
|
+
getAccessToken(): Promise<string | null>;
|
|
205
267
|
private handleLocationIntent;
|
|
206
268
|
sign_in(parameters?: MoonbaseIntentArgs['sign_in']): void;
|
|
207
269
|
sign_up(parameters?: MoonbaseIntentArgs['sign_up']): void;
|
|
@@ -221,6 +283,7 @@ declare class MoonbaseImpl implements MoonbaseInstance {
|
|
|
221
283
|
redeem_voucher(parameters?: MoonbaseIntentArgs['redeem_voucher']): void;
|
|
222
284
|
view_product(parameters?: MoonbaseIntentArgs['view_product']): void;
|
|
223
285
|
download_product(parameters?: MoonbaseIntentArgs['download_product']): void;
|
|
286
|
+
view_release_history(parameters?: MoonbaseIntentArgs['view_release_history']): void;
|
|
224
287
|
activate_product(parameters?: MoonbaseIntentArgs['activate_product']): void;
|
|
225
288
|
manage_subscription(parameters?: MoonbaseIntentArgs['manage_subscription']): void;
|
|
226
289
|
view_cart(): void;
|
|
@@ -236,6 +299,13 @@ export declare type MoonbaseInstance = MoonbaseInstanceIntents & {
|
|
|
236
299
|
setup: (url: string, options: DeepPartial<MoonbaseOptions>) => Promise<void>;
|
|
237
300
|
configure: (options: DeepPartial<MoonbaseOptions>) => void;
|
|
238
301
|
on: <TEvent extends MoonbaseEvent>(eventType: TEvent, callback: (event: MoonbaseEventArgs[TEvent]) => void) => void;
|
|
302
|
+
/**
|
|
303
|
+
* The signed-in customer's access token, for calling your own API on their behalf, or
|
|
304
|
+
* null when nobody is signed in. Renewed first when it is about to run out, so it is
|
|
305
|
+
* always good for at least the next half minute. Verify it on your server with your
|
|
306
|
+
* account's public key, at `/api/key/jwks` on your Moonbase address.
|
|
307
|
+
*/
|
|
308
|
+
getAccessToken: () => Promise<string | null>;
|
|
239
309
|
};
|
|
240
310
|
|
|
241
311
|
declare type MoonbaseInstanceIntents = {
|
|
@@ -261,6 +331,7 @@ export declare enum MoonbaseIntent {
|
|
|
261
331
|
JoinGroup = "join_group",
|
|
262
332
|
ViewProduct = "view_product",
|
|
263
333
|
DownloadProduct = "download_product",
|
|
334
|
+
ViewReleaseHistory = "view_release_history",
|
|
264
335
|
ActivateProduct = "activate_product",
|
|
265
336
|
ManageSubscription = "manage_subscription",
|
|
266
337
|
ViewCart = "view_cart",
|
|
@@ -341,6 +412,9 @@ export declare interface MoonbaseIntentArgs {
|
|
|
341
412
|
version?: string;
|
|
342
413
|
key?: string;
|
|
343
414
|
};
|
|
415
|
+
[MoonbaseIntent.ViewReleaseHistory]: {
|
|
416
|
+
product_id: string;
|
|
417
|
+
};
|
|
344
418
|
[MoonbaseIntent.ActivateProduct]: {
|
|
345
419
|
token?: string;
|
|
346
420
|
};
|
|
@@ -405,23 +479,10 @@ export declare interface MoonbaseOptions {
|
|
|
405
479
|
};
|
|
406
480
|
};
|
|
407
481
|
/**
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
* registration or a sale. Enrollment is therefore silent too, and there is
|
|
413
|
-
* nothing to label.
|
|
414
|
-
*
|
|
415
|
-
* `signUp` and `subscribe` can be added to per link with `mb_groups`, e.g.
|
|
416
|
-
* `?mb_intent=sign_up&mb_groups=beta,vip`. The two are unioned: the options
|
|
417
|
-
* say which lists everyone signing up through this site joins, the link adds
|
|
418
|
-
* whichever the campaign is for. A host-page `data-moonbase-form="subscribe"`
|
|
419
|
-
* form adds to `subscribe` the same way, with a field named `groups`.
|
|
420
|
-
*
|
|
421
|
-
* `checkout` is options-only. The cart outlives any one intent, and a buyer
|
|
422
|
-
* pressing the drawer's own checkout button never went through a link, so a
|
|
423
|
-
* URL-scoped group there would apply or not depending on which button they
|
|
424
|
-
* happened to press.
|
|
482
|
+
* IDs of the customer groups a visitor joins through each form. A group not open to public
|
|
483
|
+
* sign-ups is skipped silently. A link adds to `signUp` and `subscribe` with `mb_groups`
|
|
484
|
+
* (`?mb_intent=sign_up&mb_groups=beta,vip`), and a `data-moonbase-form="subscribe"` form with a
|
|
485
|
+
* `groups` field. `checkout` is set here only.
|
|
425
486
|
*/
|
|
426
487
|
groups: {
|
|
427
488
|
signUp: string[];
|
|
@@ -430,68 +491,36 @@ export declare interface MoonbaseOptions {
|
|
|
430
491
|
};
|
|
431
492
|
checkout: {
|
|
432
493
|
/**
|
|
433
|
-
* Where checkout happens
|
|
434
|
-
*
|
|
435
|
-
* - `'
|
|
436
|
-
*
|
|
437
|
-
* wallets require the *top-level* domain to be a registered payment-method
|
|
438
|
-
* domain, which it never is when checkout runs in an iframe on the host's
|
|
439
|
-
* own site.
|
|
440
|
-
* - `'always'` / `true` — always redirect to the hosted checkout.
|
|
441
|
-
* - `'never'` / `false` — always use the overlay, wallets included in the cost.
|
|
494
|
+
* Where checkout happens:
|
|
495
|
+
* - `'auto'` (default): an overlay on desktop, the hosted checkout on mobile.
|
|
496
|
+
* - `'always'` / `true`: always the hosted checkout.
|
|
497
|
+
* - `'never'` / `false`: always the overlay, which can't offer Apple Pay or Google Pay.
|
|
442
498
|
*/
|
|
443
499
|
redirect: boolean | CheckoutRedirectMode;
|
|
444
500
|
};
|
|
445
501
|
cart: {
|
|
446
502
|
quantity: 'selectable' | 'single';
|
|
447
503
|
bundles: {
|
|
504
|
+
/**
|
|
505
|
+
* `'replace'` (default) takes a bundle's products out of the cart when it is added, if they are
|
|
506
|
+
* sold the same way (subscription or one-off) as the bundle. `'append'` leaves them in.
|
|
507
|
+
*/
|
|
448
508
|
onAdd: 'append' | 'replace';
|
|
449
509
|
showProducts: boolean;
|
|
450
510
|
};
|
|
451
511
|
offers: {
|
|
452
512
|
label: string;
|
|
453
513
|
/**
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
* Off by default: an offer is a merchant's to give, and applying one unasked discounts a cart
|
|
459
|
-
* the buyer never asked to have discounted. Turn it on to close the one case the upsell cannot
|
|
460
|
-
* reach. The card is hidden once the offer's targets are in the cart, so a cart assembled in
|
|
461
|
-
* that order (target first, then the item that satisfies the offer's condition) leaves a real
|
|
462
|
-
* discount with no way of being claimed.
|
|
463
|
-
*
|
|
464
|
-
* Never adds anything to the cart, and never takes an offer the cart is still selling: an offer
|
|
465
|
-
* that names a product the buyer has not added keeps showing as a card and still takes a press,
|
|
466
|
-
* since an offer is good for one line only and spending it early would remove that card. Nor
|
|
467
|
-
* does it replace an offer a line already carries.
|
|
468
|
-
*
|
|
469
|
-
* That last part governs when an offer is taken, not where it stays. Remove one of the products
|
|
470
|
-
* that qualified an offer and it stays on the line it landed on, exactly as an offer claimed
|
|
471
|
-
* from the card would. A buyer can put a multi-target offer on one product and never add the
|
|
472
|
-
* other, so this is a cart they could have built by hand. Losing the discount because of an
|
|
473
|
-
* unrelated removal would be the surprising behaviour, not keeping it.
|
|
514
|
+
* Put an eligible single-product offer on the line it targets without the buyer pressing its
|
|
515
|
+
* card, which hides once the target is in the cart. Off by default. Never adds to the cart or
|
|
516
|
+
* replaces an offer a line already has.
|
|
474
517
|
*/
|
|
475
518
|
autoApply: boolean;
|
|
476
|
-
/**
|
|
477
|
-
* Offers keyed off the cart as a whole, such as "10% off orders over $50", rather than off a single
|
|
478
|
-
* product. They apply themselves the moment the cart qualifies; there is nothing for the buyer
|
|
479
|
-
* to press.
|
|
480
|
-
*/
|
|
519
|
+
/** Offers on the whole cart, such as "10% off orders over $50". They apply once the cart qualifies. */
|
|
481
520
|
cartWide: {
|
|
482
|
-
/**
|
|
483
|
-
* Show the eligibility meter in the cart: how close the cart is to the offer's threshold
|
|
484
|
-
* while it is short, and the discount confirmed once it is not.
|
|
485
|
-
*
|
|
486
|
-
* Set to `false` to let the offer apply silently: the saving still shows in the totals, the
|
|
487
|
-
* nudge does not. With no such offer configured the meter never renders either way.
|
|
488
|
-
*/
|
|
521
|
+
/** Show how far the cart is from the offer's threshold. `false` applies it without the meter. */
|
|
489
522
|
showProgress: boolean;
|
|
490
|
-
/**
|
|
491
|
-
* Label for the saving row in the cart totals, above `Total`. Kept in the widget's own voice
|
|
492
|
-
* rather than taking the offer's name, so the totals column can't be pushed around by
|
|
493
|
-
* merchant-length copy.
|
|
494
|
-
*/
|
|
523
|
+
/** Label for the saving row in the cart totals. */
|
|
495
524
|
savingLabel: string;
|
|
496
525
|
};
|
|
497
526
|
};
|
|
@@ -499,19 +528,10 @@ export declare interface MoonbaseOptions {
|
|
|
499
528
|
quantity: 'selectable' | 'single';
|
|
500
529
|
};
|
|
501
530
|
/**
|
|
502
|
-
* The smallest order the cart
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
* Per currency because the API picks each visitor's currency and the widget never converts one
|
|
507
|
-
* into another. A currency with no entry has no minimum, so a buyer priced in one you did not
|
|
508
|
-
* list checks out as before.
|
|
509
|
-
*
|
|
510
|
-
* Measured on the cart's own Total: after product discounts and offers, before coupons and tax.
|
|
511
|
-
* A cart of nothing but free items is exempt, since there is no purchase to hold back.
|
|
512
|
-
*
|
|
513
|
-
* The widget enforces this, not the API: `purchase()` and checkouts built outside the widget are
|
|
514
|
-
* not held to it. A value you pass replaces the previous one outright; pass `{}` to remove it.
|
|
531
|
+
* The smallest order the cart checks out, per currency in major units, e.g. `{ USD: 25, EUR: 25 }`.
|
|
532
|
+
* Measured after discounts and offers, before coupons and tax. A currency left out has no
|
|
533
|
+
* minimum, and a cart of only free items is exempt. `purchase()` is not held to it. Pass `{}` to
|
|
534
|
+
* remove it.
|
|
515
535
|
*/
|
|
516
536
|
minimumTotal: Record<string, number>;
|
|
517
537
|
};
|
|
@@ -525,22 +545,13 @@ export declare interface MoonbaseOptions {
|
|
|
525
545
|
};
|
|
526
546
|
promotions: {
|
|
527
547
|
/**
|
|
528
|
-
*
|
|
529
|
-
*
|
|
530
|
-
* off to render the campaign yourself from `Moonbase.on('promotion-shown', …)` or the
|
|
531
|
-
* `usePromotions()` composable in `@moonbase.sh/vue`.
|
|
548
|
+
* Show running promotions as a banner or popup. Turn off to render them yourself from the
|
|
549
|
+
* `promotion-shown` event or `usePromotions()` in `@moonbase.sh/vue`.
|
|
532
550
|
*/
|
|
533
551
|
enabled: boolean;
|
|
534
|
-
/**
|
|
535
|
-
* Where the banner sits when the host page has no `[data-moonbase-promotion]` container for
|
|
536
|
-
* it. Ignored when one exists — then the banner renders inline, wherever you put it.
|
|
537
|
-
*/
|
|
552
|
+
/** Where the banner goes when the page has no `[data-moonbase-promotion]` container. */
|
|
538
553
|
location: 'top' | 'bottom';
|
|
539
|
-
/**
|
|
540
|
-
* The label on the dismiss action, and the primary action when a sale has no destination. The
|
|
541
|
-
* wording for a sale that *does* lead somewhere comes from the promotion itself, since only
|
|
542
|
-
* the merchant knows what the campaign is offering.
|
|
543
|
-
*/
|
|
554
|
+
/** Label for dismissing a promotion, and its only action when it has no link. */
|
|
544
555
|
dismissLabel: string;
|
|
545
556
|
};
|
|
546
557
|
theme: {
|
|
@@ -551,19 +562,11 @@ export declare interface MoonbaseOptions {
|
|
|
551
562
|
};
|
|
552
563
|
fonts: {
|
|
553
564
|
/**
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
* - `'inherit'` — render in whatever font the host page uses at that spot. Loads nothing.
|
|
558
|
-
* - `'system'` — the widget's own system stack. Loads nothing.
|
|
559
|
-
* - `{ family }` — name any family the page already loads.
|
|
560
|
-
* - `{ family, stylesheet }` — name any family and the URL to load the face from.
|
|
561
|
-
*
|
|
562
|
-
* The distinction that catches people out: `'Inter'` means "load Inter for me",
|
|
563
|
-
* `{ family: 'Inter' }` means "the family is Inter, I already load it".
|
|
565
|
+
* A built-in family the widget loads (`'Inter'`), `'inherit'` for the page's font, `'system'`,
|
|
566
|
+
* `{ family }` for one the page already loads, or `{ family, stylesheet }` to load one.
|
|
564
567
|
*/
|
|
565
568
|
heading: MoonbaseFont;
|
|
566
|
-
/** As `heading`, for body
|
|
569
|
+
/** As `heading`, for body text. */
|
|
567
570
|
body: MoonbaseFont;
|
|
568
571
|
};
|
|
569
572
|
corners: 'sharp' | 'soft' | 'round';
|
|
@@ -571,44 +574,17 @@ export declare interface MoonbaseOptions {
|
|
|
571
574
|
cards: 'outlined' | 'shadow' | 'white';
|
|
572
575
|
};
|
|
573
576
|
pricing: {
|
|
574
|
-
/**
|
|
575
|
-
* How to render a price that lands on a whole number.
|
|
576
|
-
* - `'auto'` (default) drops the fraction entirely, so `10` renders `$10`.
|
|
577
|
-
* - `'always'` keeps the currency's own fraction digits, so `10` renders
|
|
578
|
-
* `$10.00` — and still `¥1000` for zero-decimal currencies like JPY.
|
|
579
|
-
*
|
|
580
|
-
* Prices that aren't whole are unaffected; they always show their decimals.
|
|
581
|
-
*/
|
|
577
|
+
/** Whole prices: `'auto'` (default) shows `$10`, `'always'` shows `$10.00`. */
|
|
582
578
|
trailingZeros: TrailingZeros;
|
|
583
|
-
/**
|
|
584
|
-
* Which marker identifies the currency. Taking `10` USD read in a British
|
|
585
|
-
* locale:
|
|
586
|
-
* - `'narrowSymbol'` (default) renders the shortest symbol, `$10`.
|
|
587
|
-
* - `'symbol'` renders the locale's usual symbol, `US$10`.
|
|
588
|
-
* - `'code'` renders the ISO 4217 code, `USD 10`.
|
|
589
|
-
* - `'name'` spells it out in the visitor's language, `10 US dollars`.
|
|
590
|
-
*
|
|
591
|
-
* The symbol and its placement always follow the visitor's own locale;
|
|
592
|
-
* this only picks which of the four forms to use.
|
|
593
|
-
*/
|
|
579
|
+
/** `'narrowSymbol'` (default) `$10`, `'symbol'` `US$10`, `'code'` `USD 10`, `'name'` `10 US dollars`. */
|
|
594
580
|
currencyDisplay: CurrencyDisplay;
|
|
595
581
|
};
|
|
596
582
|
target: HTMLElement | undefined;
|
|
597
|
-
/**
|
|
598
|
-
* When the host page declares a fixed-width mobile viewport (e.g. Wix's
|
|
599
|
-
* legacy `<meta name="viewport" content="width=320, ...">`), the browser
|
|
600
|
-
* upscales every CSS pixel to fit the device. Set this to `true` to opt out
|
|
601
|
-
* of the widget's automatic counter-scaling and match the host's density.
|
|
602
|
-
*/
|
|
583
|
+
/** Turn off the widget's scaling on pages with a fixed-width mobile viewport, such as Wix's `width=320`. */
|
|
603
584
|
disableViewportCompensation: boolean;
|
|
604
585
|
/**
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
* config object. The widget never loads SDK scripts — it only forwards
|
|
608
|
-
* to globals the host page has already initialised (e.g. `window.fbq`,
|
|
609
|
-
* `window.gtag`, `window.dataLayer`, `window.klaviyo`, `window.ttq`).
|
|
610
|
-
* If a provider's global is missing at the time of an event, the
|
|
611
|
-
* forwarding is a silent no-op.
|
|
586
|
+
* Forward storefront events to analytics SDKs the page already loads (`fbq`, `gtag`,
|
|
587
|
+
* `dataLayer`, `klaviyo`, `ttq`). Pass a provider's config to turn it on.
|
|
612
588
|
*/
|
|
613
589
|
integrations: IntegrationsConfig;
|
|
614
590
|
}
|