@sense-apps/mantle 0.2.0 → 0.3.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 CHANGED
@@ -87,11 +87,21 @@ const maxBarViews = (subscription?.plan?.features["bar_views"]?.value as number)
87
87
  ```ts
88
88
  const plans = await client.getPlans();
89
89
  // Mantle Plan shape: id, name, total, subtotal, interval ("EVERY_30_DAYS" | "ANNUAL" | "QUARTERLY"),
90
- // trialDays, currencyCode, features, featuresOrder, flexBilling, …
90
+ // trialDays, currencyCode, features, featuresOrder, discounts, autoAppliedDiscount, flexBilling, …
91
91
  ```
92
92
 
93
93
  Eligibility (tag rules, per-shop price/trial overrides) is resolved server-side — the list is exactly what this shop may buy, with override pricing already applied. Money fields (`total`, `subtotal`) are numbers only because that is Mantle's wire shape — treat them as display values.
94
94
 
95
+ **Discounts** work like Mantle's: created in the Mantlekit dashboard as a percentage (`percentage: 20` = 20%) or fixed amount off, optionally limited to specific plans, for a number of billing intervals (or forever / until a date), and auto-applied to shops by tag. When one auto-applies, `plan.autoAppliedDiscount` is set and `plan.total` is already the discounted price, with `plan.subtotal` the original — render a slashed price:
96
+
97
+ ```ts
98
+ if (plan.autoAppliedDiscount) {
99
+ render(`~~$${plan.subtotal}~~ $${plan.total}/mo — ${plan.autoAppliedDiscount.percentage}% off`);
100
+ }
101
+ ```
102
+
103
+ The same discount is forwarded to Shopify at subscribe time (on the recurring line item), so the approval screen and the real charge match what you displayed. Flex-billing plans never get auto-applied discounts (Shopify's discount input can't reach usage lines).
104
+
95
105
  ### 5. Subscribe / upgrade
96
106
 
97
107
  ```ts
package/dist/client.d.ts CHANGED
@@ -59,6 +59,23 @@ export interface UsageCharge {
59
59
  terms: string;
60
60
  cappedAmount: number;
61
61
  }
62
+ export interface Discount {
63
+ id: string;
64
+ name: string;
65
+ description: string | null;
66
+ /** Set for fixed-amount discounts. */
67
+ amount?: number;
68
+ amountCurrencyCode?: string;
69
+ presentmentAmount?: number;
70
+ presentmentCurrencyCode?: string;
71
+ /** Set for percentage discounts — human number, 20 = 20%. */
72
+ percentage?: number;
73
+ /** How many billing intervals the discount lasts; absent = forever. */
74
+ durationLimitInIntervals?: number;
75
+ /** The plan price after this discount. */
76
+ discountedAmount: number;
77
+ presentmentDiscountedAmount: number;
78
+ }
62
79
  export interface Plan {
63
80
  id: string;
64
81
  name: string;
@@ -83,7 +100,14 @@ export interface Plan {
83
100
  usageCharges: UsageCharge[];
84
101
  usageChargeCappedAmount?: number;
85
102
  customFields: Record<string, unknown>;
86
- discounts: never[];
103
+ /** Discounts attached to this plan (auto-apply and manual alike). */
104
+ discounts: Discount[];
105
+ /**
106
+ * The discount that auto-applies to this shop at subscribe time (targeted
107
+ * by plan/tags in the Mantlekit dashboard). `total` already reflects it;
108
+ * `subtotal` is the undiscounted price — render a slashed price when set.
109
+ */
110
+ autoAppliedDiscount?: Discount;
87
111
  flexBilling: boolean;
88
112
  flexBillingTerms: string | null;
89
113
  autoUpgradeToPlanId: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sense-apps/mantle",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Backend-only client for a self-hosted Mantlekit deployment — @heymantle/client-compatible shapes (Customer/Subscription/Plan/Feature) and API (identify, getPlans, getCustomer, subscribe) for Shopify apps.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/client.ts CHANGED
@@ -63,6 +63,24 @@ export interface UsageCharge {
63
63
  cappedAmount: number;
64
64
  }
65
65
 
66
+ export interface Discount {
67
+ id: string;
68
+ name: string;
69
+ description: string | null;
70
+ /** Set for fixed-amount discounts. */
71
+ amount?: number;
72
+ amountCurrencyCode?: string;
73
+ presentmentAmount?: number;
74
+ presentmentCurrencyCode?: string;
75
+ /** Set for percentage discounts — human number, 20 = 20%. */
76
+ percentage?: number;
77
+ /** How many billing intervals the discount lasts; absent = forever. */
78
+ durationLimitInIntervals?: number;
79
+ /** The plan price after this discount. */
80
+ discountedAmount: number;
81
+ presentmentDiscountedAmount: number;
82
+ }
83
+
66
84
  export interface Plan {
67
85
  id: string;
68
86
  name: string;
@@ -87,7 +105,14 @@ export interface Plan {
87
105
  usageCharges: UsageCharge[];
88
106
  usageChargeCappedAmount?: number;
89
107
  customFields: Record<string, unknown>;
90
- discounts: never[];
108
+ /** Discounts attached to this plan (auto-apply and manual alike). */
109
+ discounts: Discount[];
110
+ /**
111
+ * The discount that auto-applies to this shop at subscribe time (targeted
112
+ * by plan/tags in the Mantlekit dashboard). `total` already reflects it;
113
+ * `subtotal` is the undiscounted price — render a slashed price when set.
114
+ */
115
+ autoAppliedDiscount?: Discount;
91
116
  flexBilling: boolean;
92
117
  flexBillingTerms: string | null;
93
118
  autoUpgradeToPlanId: string | null;