@owlmeans/server-payment 0.1.18-rc.2 → 0.1.18-rc.20

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.
Files changed (160) hide show
  1. package/README.md +109 -25
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/server-payment/SKILL.md +329 -48
  4. package/build/actions/index.d.ts +1 -0
  5. package/build/actions/index.d.ts.map +1 -1
  6. package/build/actions/index.js +1 -0
  7. package/build/actions/index.js.map +1 -1
  8. package/build/actions/resync-subscriptions.d.ts +3 -0
  9. package/build/actions/resync-subscriptions.d.ts.map +1 -0
  10. package/build/actions/resync-subscriptions.js +7 -0
  11. package/build/actions/resync-subscriptions.js.map +1 -0
  12. package/build/actions/resync.d.ts +1 -0
  13. package/build/actions/resync.d.ts.map +1 -1
  14. package/build/actions/resync.js +7 -3
  15. package/build/actions/resync.js.map +1 -1
  16. package/build/actions/webhook.d.ts.map +1 -1
  17. package/build/actions/webhook.js +6 -3
  18. package/build/actions/webhook.js.map +1 -1
  19. package/build/config.d.ts +46 -5
  20. package/build/config.d.ts.map +1 -1
  21. package/build/config.js +140 -4
  22. package/build/config.js.map +1 -1
  23. package/build/consts.d.ts +48 -3
  24. package/build/consts.d.ts.map +1 -1
  25. package/build/consts.js +67 -5
  26. package/build/consts.js.map +1 -1
  27. package/build/entitlement.d.ts +10 -0
  28. package/build/entitlement.d.ts.map +1 -0
  29. package/build/entitlement.js +69 -0
  30. package/build/entitlement.js.map +1 -0
  31. package/build/entrypoints.d.ts +1 -1
  32. package/build/entrypoints.d.ts.map +1 -1
  33. package/build/entrypoints.js +2 -1
  34. package/build/entrypoints.js.map +1 -1
  35. package/build/gate.d.ts +32 -4
  36. package/build/gate.d.ts.map +1 -1
  37. package/build/gate.js +59 -19
  38. package/build/gate.js.map +1 -1
  39. package/build/index.d.ts +16 -3
  40. package/build/index.d.ts.map +1 -1
  41. package/build/index.js +13 -3
  42. package/build/index.js.map +1 -1
  43. package/build/limit.d.ts +13 -0
  44. package/build/limit.d.ts.map +1 -0
  45. package/build/limit.js +47 -0
  46. package/build/limit.js.map +1 -0
  47. package/build/model.d.ts +5 -1
  48. package/build/model.d.ts.map +1 -1
  49. package/build/model.js +85 -17
  50. package/build/model.js.map +1 -1
  51. package/build/observer.d.ts +5 -0
  52. package/build/observer.d.ts.map +1 -1
  53. package/build/observer.js +25 -12
  54. package/build/observer.js.map +1 -1
  55. package/build/plan.d.ts +22 -0
  56. package/build/plan.d.ts.map +1 -0
  57. package/build/plan.js +72 -0
  58. package/build/plan.js.map +1 -0
  59. package/build/plugins/estimate.d.ts +43 -0
  60. package/build/plugins/estimate.d.ts.map +1 -0
  61. package/build/plugins/estimate.js +235 -0
  62. package/build/plugins/estimate.js.map +1 -0
  63. package/build/plugins/events.d.ts +43 -10
  64. package/build/plugins/events.d.ts.map +1 -1
  65. package/build/plugins/events.js +487 -135
  66. package/build/plugins/events.js.map +1 -1
  67. package/build/plugins/fx.d.ts +26 -0
  68. package/build/plugins/fx.d.ts.map +1 -0
  69. package/build/plugins/fx.js +56 -0
  70. package/build/plugins/fx.js.map +1 -0
  71. package/build/plugins/portal.d.ts +37 -0
  72. package/build/plugins/portal.d.ts.map +1 -0
  73. package/build/plugins/portal.js +255 -0
  74. package/build/plugins/portal.js.map +1 -0
  75. package/build/plugins/refunds.d.ts +33 -0
  76. package/build/plugins/refunds.d.ts.map +1 -0
  77. package/build/plugins/refunds.js +80 -0
  78. package/build/plugins/refunds.js.map +1 -0
  79. package/build/plugins/stripe.d.ts +17 -4
  80. package/build/plugins/stripe.d.ts.map +1 -1
  81. package/build/plugins/stripe.js +147 -88
  82. package/build/plugins/stripe.js.map +1 -1
  83. package/build/plugins/webhook-manager.d.ts +46 -0
  84. package/build/plugins/webhook-manager.d.ts.map +1 -0
  85. package/build/plugins/webhook-manager.js +231 -0
  86. package/build/plugins/webhook-manager.js.map +1 -0
  87. package/build/reconcile.d.ts +15 -0
  88. package/build/reconcile.d.ts.map +1 -0
  89. package/build/reconcile.js +88 -0
  90. package/build/reconcile.js.map +1 -0
  91. package/build/resource.d.ts +5 -1
  92. package/build/resource.d.ts.map +1 -1
  93. package/build/resource.js +40 -6
  94. package/build/resource.js.map +1 -1
  95. package/build/service.d.ts +27 -3
  96. package/build/service.d.ts.map +1 -1
  97. package/build/service.js +123 -19
  98. package/build/service.js.map +1 -1
  99. package/build/subscription.d.ts +42 -0
  100. package/build/subscription.d.ts.map +1 -0
  101. package/build/subscription.js +175 -0
  102. package/build/subscription.js.map +1 -0
  103. package/build/sync.d.ts +21 -1
  104. package/build/sync.d.ts.map +1 -1
  105. package/build/sync.js +108 -24
  106. package/build/sync.js.map +1 -1
  107. package/build/types.d.ts +412 -36
  108. package/build/types.d.ts.map +1 -1
  109. package/build/usage.d.ts +63 -0
  110. package/build/usage.d.ts.map +1 -0
  111. package/build/usage.js +363 -0
  112. package/build/usage.js.map +1 -0
  113. package/build/utils.d.ts +31 -1
  114. package/build/utils.d.ts.map +1 -1
  115. package/build/utils.js +43 -7
  116. package/build/utils.js.map +1 -1
  117. package/package.json +16 -13
  118. package/src/actions/index.ts +1 -0
  119. package/src/actions/resync-subscriptions.ts +10 -0
  120. package/src/actions/resync.ts +6 -3
  121. package/src/actions/webhook.ts +5 -3
  122. package/src/config.ts +159 -7
  123. package/src/consts.ts +80 -6
  124. package/src/entitlement.ts +84 -0
  125. package/src/entrypoints.ts +2 -1
  126. package/src/gate.ts +88 -21
  127. package/src/index.ts +22 -3
  128. package/src/limit.ts +57 -0
  129. package/src/model.ts +95 -18
  130. package/src/observer.ts +31 -11
  131. package/src/plan.ts +89 -0
  132. package/src/plugins/estimate.ts +299 -0
  133. package/src/plugins/events.ts +552 -120
  134. package/src/plugins/fx.ts +93 -0
  135. package/src/plugins/portal.ts +296 -0
  136. package/src/plugins/refunds.ts +108 -0
  137. package/src/plugins/stripe.ts +157 -88
  138. package/src/plugins/webhook-manager.ts +270 -0
  139. package/src/reconcile.ts +103 -0
  140. package/src/resource.ts +69 -7
  141. package/src/service.ts +152 -18
  142. package/src/subscription.ts +224 -0
  143. package/src/sync.ts +135 -22
  144. package/src/types.ts +476 -31
  145. package/src/usage.ts +453 -0
  146. package/src/utils.ts +78 -10
  147. package/tests/checkout.spec.ts +184 -83
  148. package/tests/context.ts +91 -0
  149. package/tests/entitlement.spec.ts +103 -0
  150. package/tests/estimate.spec.ts +240 -0
  151. package/tests/events.spec.ts +356 -0
  152. package/tests/fake-stripe.ts +802 -0
  153. package/tests/gate.spec.ts +62 -72
  154. package/tests/limit-gate.spec.ts +68 -0
  155. package/tests/portal.spec.ts +200 -0
  156. package/tests/protocol.spec.ts +23 -6
  157. package/tests/sync.spec.ts +114 -0
  158. package/tests/usage.integration.spec.ts +101 -0
  159. package/tests/usage.spec.ts +171 -0
  160. package/tests/webhook-manager.spec.ts +152 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resync-subscriptions.d.ts","sourceRoot":"","sources":["../../src/actions/resync-subscriptions.ts"],"names":[],"mappings":"AAOA,+FAA+F;AAC/F,eAAO,MAAM,mBAAmB,uKACY,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { handlers } from '@owlmeans/server-api';
2
+ import { paymentGate } from '../consts.js';
3
+ import { gateway } from '../utils.js';
4
+ const bind = handlers();
5
+ /** Re-read every live paygate subscription — the manually or periodically triggered repair. */
6
+ export const resyncSubscriptions = bind.request(paymentGate.resyncSubscriptions, async (_request, context) => await gateway(context).resyncAll(context));
7
+ //# sourceMappingURL=resync-subscriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resync-subscriptions.js","sourceRoot":"","sources":["../../src/actions/resync-subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAGrC,MAAM,IAAI,GAAG,QAAQ,EAAW,CAAA;AAEhC,+FAA+F;AAC/F,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,CAC3G,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA"}
@@ -1,2 +1,3 @@
1
+ /** Forget every sync fingerprint and bring Stripe back to the declared catalogue, portal and webhook. */
1
2
  export declare const resync: import("@owlmeans/server-entrypoint").BoundEntrypointHandler<import("@owlmeans/entrypoint").EntrypointProtocol<{}, import("../consts.js").ResyncResult>>;
2
3
  //# sourceMappingURL=resync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resync.d.ts","sourceRoot":"","sources":["../../src/actions/resync.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,MAAM,0JAIjB,CAAA"}
1
+ {"version":3,"file":"resync.d.ts","sourceRoot":"","sources":["../../src/actions/resync.ts"],"names":[],"mappings":"AASA,yGAAyG;AACzG,eAAO,MAAM,MAAM,0JAKjB,CAAA"}
@@ -1,11 +1,15 @@
1
+ import { PaygateError } from '@owlmeans/payment';
1
2
  import { handlers } from '@owlmeans/server-api';
2
3
  import { paymentGate } from '../consts.js';
3
- import { fingerprints } from '../utils.js';
4
- import { initialize } from '../sync.js';
4
+ import { bootstrapStripe } from '../service.js';
5
+ import { fingerprints, gateway, stripeClient } from '../utils.js';
5
6
  const bind = handlers();
7
+ /** Forget every sync fingerprint and bring Stripe back to the declared catalogue, portal and webhook. */
6
8
  export const resync = bind.request(paymentGate.resync, async (_request, context) => {
9
+ if (!gateway(context).managed)
10
+ throw new PaygateError('unmanaged');
7
11
  await fingerprints(context).clear();
8
- await initialize(context);
12
+ await bootstrapStripe(context, await stripeClient(context), { force: true });
9
13
  return { ok: true };
10
14
  });
11
15
  //# sourceMappingURL=resync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resync.js","sourceRoot":"","sources":["../../src/actions/resync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGvC,MAAM,IAAI,GAAG,QAAQ,EAAW,CAAA;AAEhC,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IACjF,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAA;IACnC,MAAM,UAAU,CAAC,OAAO,CAAC,CAAA;IACzB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AACrB,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"resync.js","sourceRoot":"","sources":["../../src/actions/resync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGjE,MAAM,IAAI,GAAG,QAAQ,EAAW,CAAA;AAEhC,yGAAyG;AACzG,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IACjF,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,WAAW,CAAC,CAAA;IAClE,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAA;IACnC,MAAM,eAAe,CAAC,OAAO,EAAE,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AACrB,CAAC,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/actions/webhook.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,OAAO;;cAGlB,CAAA"}
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/actions/webhook.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,OAAO;;cAIlB,CAAA"}
@@ -1,11 +1,14 @@
1
- import { UnknownPaygate } from '@owlmeans/payment';
1
+ import { PaygateError, UnknownPaygate } from '@owlmeans/payment';
2
2
  import { handlers } from '@owlmeans/server-api';
3
3
  import { paymentGate, STRIPE_PAYGATE_ALIAS } from '../consts.js';
4
- import { stripePlugin } from '../plugins/stripe.js';
4
+ import { handleStripeWebhook } from '../plugins/stripe.js';
5
+ import { gateway, stripeClient } from '../utils.js';
5
6
  const bind = handlers();
6
7
  export const webhook = bind.params(paymentGate.webhook, async ({ paygate }, context, request) => {
7
8
  if (paygate !== STRIPE_PAYGATE_ALIAS)
8
9
  throw new UnknownPaygate(paygate);
9
- await stripePlugin.handleWebhook(request, context);
10
+ if (!gateway(context).managed)
11
+ throw new PaygateError('unmanaged');
12
+ await handleStripeWebhook(context, await stripeClient(context), request);
10
13
  });
11
14
  //# sourceMappingURL=webhook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/actions/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAGnD,MAAM,IAAI,GAAG,QAAQ,EAAW,CAAA;AAEhC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAC9F,IAAI,OAAO,KAAK,oBAAoB;QAAE,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,CAAA;IACvE,MAAM,YAAY,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACpD,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/actions/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGnD,MAAM,IAAI,GAAG,QAAQ,EAAW,CAAA;AAEhC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAC9F,IAAI,OAAO,KAAK,oBAAoB;QAAE,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,CAAA;IACvE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,WAAW,CAAC,CAAA;IAClE,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,YAAY,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;AAC1E,CAAC,CAAC,CAAA"}
package/build/config.d.ts CHANGED
@@ -1,8 +1,49 @@
1
- import type { Config, PaymentPlanDef, PaymentProductDef } from './types.js';
1
+ import type { Config, PaymentPlan, PaymentPlanDef, PaymentProductDef, PortalBrandingDef, PricingDef, StripeSecretsDef } from './types.js';
2
2
  export declare const declarePaymentProduct: (cfg: Config, def: PaymentProductDef) => void;
3
+ /**
4
+ * Declare a plan into the configuration catalogue.
5
+ *
6
+ * Validated before anything is pushed: `rank` a safe integer `>= 0`; a `free` plan costs nothing
7
+ * and is sold through no gateway; no capability set under the reserved `limit` scope; every limit
8
+ * well-formed (a `window` limit names its window, the others do not, the ceiling is a safe
9
+ * integer, a promo ends at a real `Date`). Amount and quantity policies are asserted as before.
10
+ */
3
11
  export declare const declarePaymentPlan: (cfg: Config, def: PaymentPlanDef) => void;
4
- export declare const stripeSecrets: (cfg: Config, paths: {
5
- api: string;
6
- webhook: string;
7
- }) => void;
12
+ /** Every plan declared into a configuration. */
13
+ export declare const declaredPlansOf: (cfg: Config) => PaymentPlan[];
14
+ /**
15
+ * Cross-plan rules a single declaration cannot see:
16
+ *
17
+ * - at most one free plan per rank;
18
+ * - no two paid plans of one product at the same rank (one-time `consumable` plans are never an
19
+ * entity's plan and are not ranked against each other).
20
+ *
21
+ * A limit key MAY change kind between plans (lifetime on one, a monthly window on another): counters
22
+ * are keyed by `(entity, key, window)` and the window is derived from the kind, so each kind keeps its
23
+ * own counter and a lifetime count still sticks to the entity across plan changes.
24
+ *
25
+ * @throws PlanRankConflict
26
+ */
27
+ export declare const assertPlanDeclarations: (cfg: Config) => void;
28
+ /**
29
+ * Where the Stripe secrets live. A value that looks like a path is read into the configuration at
30
+ * boot. The webhook secret is an optional override of the one the managed endpoint stores.
31
+ */
32
+ export declare const stripeSecrets: (cfg: Config, paths: StripeSecretsDef) => void;
33
+ /** Branding and the default return URL of the managed customer portal configuration. */
34
+ export declare const portalBranding: (cfg: Config, def: PortalBrandingDef) => void;
35
+ /**
36
+ * Declare the pricing policy: whether checkout collects tax and a VAT/GST id, what `tax_behavior`
37
+ * synced prices are given, Adaptive Pricing, and whether the estimate endpoints are served. A
38
+ * config never carries more than one — a second call replaces the first, so re-declaring (a test, a
39
+ * config module re-run) is safe rather than silently ignored (a config resource resolves an id to
40
+ * its FIRST match).
41
+ *
42
+ * `def.stripe` (the FX Quotes preview version, the unspecified-price migration switch) is
43
+ * Stripe-only and goes to a backend plugin, never the advertised `PricingPolicy` record.
44
+ *
45
+ * @throws PaymentError (`assertPricingPolicy`) when an estimate is declared without the tax or
46
+ * currency capability it requires.
47
+ */
48
+ export declare const declarePaymentPricing: (cfg: Config, def: PricingDef) => void;
8
49
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAe,cAAc,EAAkB,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAExG,eAAO,MAAM,qBAAqB,QAAS,MAAM,OAAO,iBAAiB,KAAG,IAS3E,CAAA;AAED,eAAO,MAAM,kBAAkB,QAAS,MAAM,OAAO,cAAc,KAAG,IA4BrE,CAAA;AAED,eAAO,MAAM,aAAa,QAAS,MAAM,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,IAEpF,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACV,MAAM,EAAE,WAAW,EAAE,cAAc,EAAkB,iBAAiB,EAAE,iBAAiB,EACzF,UAAU,EAAE,gBAAgB,EAC7B,MAAM,YAAY,CAAA;AAEnB,eAAO,MAAM,qBAAqB,QAAS,MAAM,OAAO,iBAAiB,KAAG,IAS3E,CAAA;AA8BD;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAS,MAAM,OAAO,cAAc,KAAG,IA2CrE,CAAA;AAED,gDAAgD;AAChD,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,WAAW,EACiD,CAAA;AAE1G;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG,IAmBpD,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAS,MAAM,SAAS,gBAAgB,KAAG,IAIpE,CAAA;AAED,wFAAwF;AACxF,eAAO,MAAM,cAAc,QAAS,MAAM,OAAO,iBAAiB,KAAG,IAOpE,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,QAAS,MAAM,OAAO,UAAU,KAAG,IAwBpE,CAAA"}
package/build/config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { toConfigRecord } from '@owlmeans/server-app';
2
2
  import { plugin } from '@owlmeans/config';
3
- import { assertAmountCheckoutPolicy, assertQuantityCheckoutPolicy, CheckoutPricingMode, PLAN_RECORD_PREFIX, PLAN_RECORD_TYPE, PlanStatus, PRODUCT_RECORD_PREFIX, PRODUCT_RECORD_TYPE, } from '@owlmeans/payment';
4
- import { STRIPE_PAYGATE_ALIAS, STRIPE_PLUGIN_CONFIG } from './consts.js';
3
+ import { assertAmountCheckoutPolicy, assertPricingPolicy, assertQuantityCheckoutPolicy, CAPABILITY_LIMIT_SCOPE, CheckoutPricingMode, LimitKind, LimitMisdeclared, LimitWindow, PLAN_RECORD_PREFIX, PLAN_RECORD_TYPE, PaymentError, PlanDuration, PlanRankConflict, PlanStatus, PRICING_POLICY_RECORD_ID, PRICING_POLICY_RECORD_TYPE, PRODUCT_RECORD_PREFIX, PRODUCT_RECORD_TYPE, } from '@owlmeans/payment';
4
+ import { STRIPE_PAYGATE_ALIAS, STRIPE_PLUGIN_CONFIG, STRIPE_PORTAL_PLUGIN_CONFIG, STRIPE_PRICING_PLUGIN_CONFIG, } from './consts.js';
5
5
  export const declarePaymentProduct = (cfg, def) => {
6
6
  cfg.records = cfg.records ?? [];
7
7
  const product = {
@@ -12,8 +12,52 @@ export const declarePaymentProduct = (cfg, def) => {
12
12
  };
13
13
  cfg.records.push({ ...toConfigRecord(product), recordType: PRODUCT_RECORD_TYPE, id: `${PRODUCT_RECORD_PREFIX}:${def.sku}` });
14
14
  };
15
+ const isSafeCount = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
16
+ const LIMIT_KINDS = Object.values(LimitKind);
17
+ const LIMIT_WINDOWS = Object.values(LimitWindow);
18
+ const assertLimitDeclaration = (key, limit) => {
19
+ if (!LIMIT_KINDS.includes(limit.kind)) {
20
+ throw new LimitMisdeclared(`${key}:kind`);
21
+ }
22
+ if (limit.kind === LimitKind.Window) {
23
+ if (limit.window == null) {
24
+ throw new LimitMisdeclared(`${key}:window-missing`);
25
+ }
26
+ if (!LIMIT_WINDOWS.includes(limit.window)) {
27
+ throw new LimitMisdeclared(`${key}:window`);
28
+ }
29
+ }
30
+ else if (limit.window != null) {
31
+ throw new LimitMisdeclared(`${key}:window-forbidden`);
32
+ }
33
+ if (!isSafeCount(limit.limit)) {
34
+ throw new LimitMisdeclared(`${key}:limit`);
35
+ }
36
+ if (limit.promo != null && !(limit.promo.until instanceof Date && !Number.isNaN(limit.promo.until.getTime()))) {
37
+ throw new LimitMisdeclared(`${key}:promo-until`);
38
+ }
39
+ };
40
+ /**
41
+ * Declare a plan into the configuration catalogue.
42
+ *
43
+ * Validated before anything is pushed: `rank` a safe integer `>= 0`; a `free` plan costs nothing
44
+ * and is sold through no gateway; no capability set under the reserved `limit` scope; every limit
45
+ * well-formed (a `window` limit names its window, the others do not, the ceiling is a safe
46
+ * integer, a promo ends at a real `Date`). Amount and quantity policies are asserted as before.
47
+ */
15
48
  export const declarePaymentPlan = (cfg, def) => {
16
- cfg.records = cfg.records ?? [];
49
+ if (def.rank != null && !isSafeCount(def.rank)) {
50
+ throw new PlanRankConflict(`rank:${def.sku}`);
51
+ }
52
+ if (def.free === true && (def.price !== 0 || (def.gateways ?? []).length > 0)) {
53
+ throw new PlanRankConflict(`free:${def.sku}`);
54
+ }
55
+ if ((def.capabilities ?? []).some(set => set.scope === CAPABILITY_LIMIT_SCOPE)) {
56
+ throw new LimitMisdeclared(`${def.sku}:reserved-scope`);
57
+ }
58
+ for (const [key, limit] of Object.entries(def.limits ?? {})) {
59
+ assertLimitDeclaration(key, limit);
60
+ }
17
61
  const pricingMode = def.pricingMode;
18
62
  if (pricingMode === CheckoutPricingMode.Amount) {
19
63
  if (def.amountPolicy == null)
@@ -29,8 +73,11 @@ export const declarePaymentPlan = (cfg, def) => {
29
73
  : undefined);
30
74
  if (quantityPolicy != null)
31
75
  assertQuantityCheckoutPolicy(quantityPolicy);
76
+ cfg.records = cfg.records ?? [];
32
77
  const plan = {
33
78
  productSku: def.productSku, sku: def.sku, status: PlanStatus.Active,
79
+ ...(def.rank != null ? { rank: def.rank } : {}),
80
+ ...(def.free === true ? { free: true, gateways: [] } : def.gateways != null ? { gateways: def.gateways } : {}),
34
81
  duration: def.duration, price: def.price, currency: def.currency ?? def.amountPolicy?.currency ?? 'usd',
35
82
  order: def.order ?? 0, title: def.title ?? def.sku, capabilities: def.capabilities,
36
83
  limits: def.limits, recurring: def.recurring, pricingMode, amountPolicy: def.amountPolicy,
@@ -40,7 +87,96 @@ export const declarePaymentPlan = (cfg, def) => {
40
87
  };
41
88
  cfg.records.push({ ...toConfigRecord(plan), recordType: PLAN_RECORD_TYPE, id: `${PLAN_RECORD_PREFIX}:${def.sku}` });
42
89
  };
90
+ /** Every plan declared into a configuration. */
91
+ export const declaredPlansOf = (cfg) => (cfg.records ?? []).filter(record => record.recordType === PLAN_RECORD_TYPE);
92
+ /**
93
+ * Cross-plan rules a single declaration cannot see:
94
+ *
95
+ * - at most one free plan per rank;
96
+ * - no two paid plans of one product at the same rank (one-time `consumable` plans are never an
97
+ * entity's plan and are not ranked against each other).
98
+ *
99
+ * A limit key MAY change kind between plans (lifetime on one, a monthly window on another): counters
100
+ * are keyed by `(entity, key, window)` and the window is derived from the kind, so each kind keeps its
101
+ * own counter and a lifetime count still sticks to the entity across plan changes.
102
+ *
103
+ * @throws PlanRankConflict
104
+ */
105
+ export const assertPlanDeclarations = (cfg) => {
106
+ const plans = declaredPlansOf(cfg);
107
+ const freeRanks = new Set();
108
+ const paidRanks = new Set();
109
+ for (const plan of plans) {
110
+ const rank = plan.rank ?? 0;
111
+ if (plan.free === true) {
112
+ if (freeRanks.has(rank)) {
113
+ throw new PlanRankConflict(`free:${rank}`);
114
+ }
115
+ freeRanks.add(rank);
116
+ }
117
+ else if (plan.duration !== PlanDuration.Consumable) {
118
+ const key = `${plan.productSku}:${rank}`;
119
+ if (paidRanks.has(key)) {
120
+ throw new PlanRankConflict(key);
121
+ }
122
+ paidRanks.add(key);
123
+ }
124
+ }
125
+ };
126
+ /**
127
+ * Where the Stripe secrets live. A value that looks like a path is read into the configuration at
128
+ * boot. The webhook secret is an optional override of the one the managed endpoint stores.
129
+ */
43
130
  export const stripeSecrets = (cfg, paths) => {
44
- plugin(cfg, { api: paths.api, webhook: paths.webhook }, STRIPE_PLUGIN_CONFIG);
131
+ plugin(cfg, {
132
+ api: paths.api, ...(paths.webhook != null && paths.webhook !== '' ? { webhook: paths.webhook } : {}),
133
+ }, STRIPE_PLUGIN_CONFIG);
134
+ };
135
+ /** Branding and the default return URL of the managed customer portal configuration. */
136
+ export const portalBranding = (cfg, def) => {
137
+ plugin(cfg, {
138
+ returnUrl: def.returnUrl,
139
+ ...(def.headline != null ? { headline: def.headline } : {}),
140
+ ...(def.privacyPolicyUrl != null ? { privacyPolicyUrl: def.privacyPolicyUrl } : {}),
141
+ ...(def.termsOfServiceUrl != null ? { termsOfServiceUrl: def.termsOfServiceUrl } : {}),
142
+ }, STRIPE_PORTAL_PLUGIN_CONFIG);
143
+ };
144
+ /**
145
+ * Declare the pricing policy: whether checkout collects tax and a VAT/GST id, what `tax_behavior`
146
+ * synced prices are given, Adaptive Pricing, and whether the estimate endpoints are served. A
147
+ * config never carries more than one — a second call replaces the first, so re-declaring (a test, a
148
+ * config module re-run) is safe rather than silently ignored (a config resource resolves an id to
149
+ * its FIRST match).
150
+ *
151
+ * `def.stripe` (the FX Quotes preview version, the unspecified-price migration switch) is
152
+ * Stripe-only and goes to a backend plugin, never the advertised `PricingPolicy` record.
153
+ *
154
+ * @throws PaymentError (`assertPricingPolicy`) when an estimate is declared without the tax or
155
+ * currency capability it requires.
156
+ */
157
+ export const declarePaymentPricing = (cfg, def) => {
158
+ const { stripe, ...policy } = def;
159
+ assertPricingPolicy(policy);
160
+ cfg.records = (cfg.records ?? []).filter(record => record.id !== PRICING_POLICY_RECORD_ID);
161
+ cfg.records.push({
162
+ ...toConfigRecord(policy), recordType: PRICING_POLICY_RECORD_TYPE, id: PRICING_POLICY_RECORD_ID,
163
+ });
164
+ if (stripe != null) {
165
+ const settlementCurrency = stripe.settlementCurrency?.toLowerCase();
166
+ if (settlementCurrency != null && !/^[a-z]{3}$/.test(settlementCurrency)) {
167
+ throw new PaymentError('pricing-policy:settlement-currency');
168
+ }
169
+ const subscriptionPaymentMethodTypes = stripe.subscriptionPaymentMethodTypes?.map(type => type.toLowerCase());
170
+ if (subscriptionPaymentMethodTypes != null && (subscriptionPaymentMethodTypes.length === 0
171
+ || subscriptionPaymentMethodTypes.some(type => !/^[a-z][a-z0-9_]*$/.test(type))
172
+ || new Set(subscriptionPaymentMethodTypes).size !== subscriptionPaymentMethodTypes.length)) {
173
+ throw new PaymentError('pricing-policy:subscription-payment-methods');
174
+ }
175
+ plugin(cfg, {
176
+ ...stripe,
177
+ ...(settlementCurrency != null ? { settlementCurrency } : {}),
178
+ ...(subscriptionPaymentMethodTypes != null ? { subscriptionPaymentMethodTypes } : {}),
179
+ }, STRIPE_PRICING_PLUGIN_CONFIG);
180
+ }
45
181
  };
46
182
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/build/consts.d.ts CHANGED
@@ -1,26 +1,71 @@
1
+ import { INTERNAL_PAYGATE, LIMIT_GATE } from '@owlmeans/payment';
2
+ export { INTERNAL_PAYGATE, LIMIT_GATE };
1
3
  export declare const STRIPE_PAYGATE_ALIAS = "stripe";
2
4
  export declare const STRIPE_PLUGIN_CONFIG = "_external:stripe";
5
+ export declare const STRIPE_PORTAL_PLUGIN_CONFIG = "_external:stripe-portal";
6
+ /** Stripe-only pricing settings (FX Quotes API version, the unspecified-price migration switch) — never advertised to the browser, unlike the `PricingPolicy` record itself. */
7
+ export declare const STRIPE_PRICING_PLUGIN_CONFIG = "_external:stripe-pricing";
3
8
  export declare const STRIPE_SIGNATURE = "Stripe-Signature";
9
+ /**
10
+ * The FX Quotes API is a Stripe PREVIEW endpoint as of this writing: it answers only a
11
+ * `Stripe-Version` header naming a preview version, never the SDK's pinned stable one. Verify this
12
+ * string against https://docs.stripe.com/api/fx_quotes/create before relying on it, and override it
13
+ * with `declarePaymentPricing({ stripe: { fxApiVersion } })` once Stripe moves the API or renames
14
+ * the preview.
15
+ */
16
+ export declare const STRIPE_FX_QUOTES_API_VERSION = "2025-07-30.preview";
4
17
  export declare const GATEWAY_SERVICE = "payment-gateway";
5
18
  export declare const PAYMENT_OBSERVER = "payment-observer";
19
+ export declare const ENTITLEMENT_SERVICE = "payment-entitlement";
6
20
  export declare const RES_PAYGATE_CUSTOMER = "payment-paygate-customer";
7
21
  export declare const RES_PAYMENT_SUBSCRIPTION = "payment-subscription";
22
+ export declare const RES_PAYMENT_FULFILLMENT = "payment-fulfillment";
23
+ export declare const RES_PAYMENT_WEBHOOK = "payment-webhook";
24
+ export declare const RES_PAYMENT_USAGE = "payment-usage";
25
+ export declare const RES_PAYMENT_USAGE_COUNTER = "payment-usage-counter";
8
26
  export declare const RES_PAYMENT_FINGERPRINT = "payment-fingerprint";
9
- export declare const COMPLETION_TOP_UP = "top-up";
10
- export declare const COMPLETION_SUBSCRIPTION = "subscription";
27
+ /** Fingerprint sku prefix of a portal configuration: `portal:<service>`. */
28
+ export declare const FINGERPRINT_PORTAL = "portal";
29
+ /**
30
+ * The metadata every Stripe object this package creates carries (`{ owlmeans: 'payment', service }`).
31
+ * It labels the object for an operator; several deployments of one service share it, so it never
32
+ * decides on its own that an object belongs to this deployment.
33
+ */
34
+ export declare const STRIPE_OWNER_KEY = "owlmeans";
35
+ export declare const STRIPE_OWNER_VALUE = "payment";
36
+ /**
37
+ * The metadata key naming the ONE deployment a portal configuration belongs to, valued with that
38
+ * deployment's webhook URL (`webhookUrlOf`). Only an exact match lets a deployment adopt a
39
+ * configuration it holds no fingerprint row for.
40
+ */
41
+ export declare const STRIPE_DEPLOYMENT_KEY = "deployment";
42
+ /**
43
+ * Every Stripe event the managed webhook endpoint subscribes to.
44
+ *
45
+ * `invoice.upcoming` is enabled although nothing handles it (it carries no invoice id and nothing
46
+ * is due), so an application can observe it without a Stripe dashboard change.
47
+ */
48
+ export declare const WEBHOOK_EVENTS: readonly string[];
11
49
  export interface PaygateParams {
12
50
  paygate: string;
13
51
  }
14
52
  export interface ResyncResult {
15
53
  ok: boolean;
16
54
  }
55
+ export interface ResyncSubscriptionsResult {
56
+ scanned: number;
57
+ updated: number;
58
+ }
17
59
  /** Embedded gateway protocol tree; the alias strings are private adapter details. */
18
60
  export declare const paymentGate: {
19
61
  readonly base: import("@owlmeans/entrypoint").EntrypointProtocol<{}, undefined>;
62
+ /** Public: Stripe signs the raw body, so no application guard may sit in front of it. */
20
63
  readonly webhook: import("@owlmeans/entrypoint").EntrypointProtocol<{
21
64
  params: PaygateParams;
22
65
  }, undefined>;
66
+ /** Re-sync products, prices, the portal configuration and the webhook endpoint. */
23
67
  readonly resync: import("@owlmeans/entrypoint").EntrypointProtocol<{}, ResyncResult>;
68
+ /** Re-read every live paygate subscription and apply it as a webhook would. */
69
+ readonly resyncSubscriptions: import("@owlmeans/entrypoint").EntrypointProtocol<{}, ResyncSubscriptionsResult>;
24
70
  };
25
- export declare const paymentGateProtocols: import("@owlmeans/entrypoint").EntrypointProtocolDeclaration[];
26
71
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,WAAW,CAAA;AAC5C,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AACtD,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAClD,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAChD,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAClD,eAAO,MAAM,oBAAoB,6BAA6B,CAAA;AAC9D,eAAO,MAAM,wBAAwB,yBAAyB,CAAA;AAC9D,eAAO,MAAM,uBAAuB,wBAAwB,CAAA;AAC5D,eAAO,MAAM,iBAAiB,WAAW,CAAA;AACzC,eAAO,MAAM,uBAAuB,iBAAiB,CAAA;AAErD,MAAM,WAAW,aAAa;IAAG,OAAO,EAAE,MAAM,CAAA;CAAE;AAClD,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,OAAO,CAAA;CAAE;AAe7C,qFAAqF;AACrF,eAAO,MAAM,WAAW;;;;;;CAWd,CAAA;AAEV,eAAO,MAAM,oBAAoB,gEAAyB,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGhE,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAA;AAEvC,eAAO,MAAM,oBAAoB,WAAW,CAAA;AAC5C,eAAO,MAAM,oBAAoB,qBAAqB,CAAA;AACtD,eAAO,MAAM,2BAA2B,4BAA4B,CAAA;AACpE,gLAAgL;AAChL,eAAO,MAAM,4BAA4B,6BAA6B,CAAA;AACtE,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,uBAAuB,CAAA;AAChE,eAAO,MAAM,eAAe,oBAAoB,CAAA;AAChD,eAAO,MAAM,gBAAgB,qBAAqB,CAAA;AAClD,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AAExD,eAAO,MAAM,oBAAoB,6BAA6B,CAAA;AAC9D,eAAO,MAAM,wBAAwB,yBAAyB,CAAA;AAC9D,eAAO,MAAM,uBAAuB,wBAAwB,CAAA;AAC5D,eAAO,MAAM,mBAAmB,oBAAoB,CAAA;AACpD,eAAO,MAAM,iBAAiB,kBAAkB,CAAA;AAChD,eAAO,MAAM,yBAAyB,0BAA0B,CAAA;AAChE,eAAO,MAAM,uBAAuB,wBAAwB,CAAA;AAE5D,4EAA4E;AAC5E,eAAO,MAAM,kBAAkB,WAAW,CAAA;AAE1C;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,aAAa,CAAA;AAC1C,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,eAAe,CAAA;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAY1C,CAAA;AAEF,MAAM,WAAW,aAAa;IAAG,OAAO,EAAE,MAAM,CAAA;CAAE;AAClD,MAAM,WAAW,YAAY;IAAG,EAAE,EAAE,OAAO,CAAA;CAAE;AAC7C,MAAM,WAAW,yBAAyB;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAyB/E,qFAAqF;AACrF,eAAO,MAAM,WAAW;;IAEtB,yFAAyF;;;;IAKzF,mFAAmF;;IAMnF,+EAA+E;;CAMvE,CAAA"}
package/build/consts.js CHANGED
@@ -1,16 +1,66 @@
1
- import { contract, protocol, protocols, schema, typed } from '@owlmeans/entrypoint';
1
+ import { contract, protocol, schema, typed } from '@owlmeans/entrypoint';
2
2
  import { backend, route, RouteMethod } from '@owlmeans/route';
3
3
  import { GUARD_ED25519 } from '@owlmeans/server-app';
4
+ import { INTERNAL_PAYGATE, LIMIT_GATE } from '@owlmeans/payment';
5
+ export { INTERNAL_PAYGATE, LIMIT_GATE };
4
6
  export const STRIPE_PAYGATE_ALIAS = 'stripe';
5
7
  export const STRIPE_PLUGIN_CONFIG = '_external:stripe';
8
+ export const STRIPE_PORTAL_PLUGIN_CONFIG = '_external:stripe-portal';
9
+ /** Stripe-only pricing settings (FX Quotes API version, the unspecified-price migration switch) — never advertised to the browser, unlike the `PricingPolicy` record itself. */
10
+ export const STRIPE_PRICING_PLUGIN_CONFIG = '_external:stripe-pricing';
6
11
  export const STRIPE_SIGNATURE = 'Stripe-Signature';
12
+ /**
13
+ * The FX Quotes API is a Stripe PREVIEW endpoint as of this writing: it answers only a
14
+ * `Stripe-Version` header naming a preview version, never the SDK's pinned stable one. Verify this
15
+ * string against https://docs.stripe.com/api/fx_quotes/create before relying on it, and override it
16
+ * with `declarePaymentPricing({ stripe: { fxApiVersion } })` once Stripe moves the API or renames
17
+ * the preview.
18
+ */
19
+ export const STRIPE_FX_QUOTES_API_VERSION = '2025-07-30.preview';
7
20
  export const GATEWAY_SERVICE = 'payment-gateway';
8
21
  export const PAYMENT_OBSERVER = 'payment-observer';
22
+ export const ENTITLEMENT_SERVICE = 'payment-entitlement';
9
23
  export const RES_PAYGATE_CUSTOMER = 'payment-paygate-customer';
10
24
  export const RES_PAYMENT_SUBSCRIPTION = 'payment-subscription';
25
+ export const RES_PAYMENT_FULFILLMENT = 'payment-fulfillment';
26
+ export const RES_PAYMENT_WEBHOOK = 'payment-webhook';
27
+ export const RES_PAYMENT_USAGE = 'payment-usage';
28
+ export const RES_PAYMENT_USAGE_COUNTER = 'payment-usage-counter';
11
29
  export const RES_PAYMENT_FINGERPRINT = 'payment-fingerprint';
12
- export const COMPLETION_TOP_UP = 'top-up';
13
- export const COMPLETION_SUBSCRIPTION = 'subscription';
30
+ /** Fingerprint sku prefix of a portal configuration: `portal:<service>`. */
31
+ export const FINGERPRINT_PORTAL = 'portal';
32
+ /**
33
+ * The metadata every Stripe object this package creates carries (`{ owlmeans: 'payment', service }`).
34
+ * It labels the object for an operator; several deployments of one service share it, so it never
35
+ * decides on its own that an object belongs to this deployment.
36
+ */
37
+ export const STRIPE_OWNER_KEY = 'owlmeans';
38
+ export const STRIPE_OWNER_VALUE = 'payment';
39
+ /**
40
+ * The metadata key naming the ONE deployment a portal configuration belongs to, valued with that
41
+ * deployment's webhook URL (`webhookUrlOf`). Only an exact match lets a deployment adopt a
42
+ * configuration it holds no fingerprint row for.
43
+ */
44
+ export const STRIPE_DEPLOYMENT_KEY = 'deployment';
45
+ /**
46
+ * Every Stripe event the managed webhook endpoint subscribes to.
47
+ *
48
+ * `invoice.upcoming` is enabled although nothing handles it (it carries no invoice id and nothing
49
+ * is due), so an application can observe it without a Stripe dashboard change.
50
+ */
51
+ export const WEBHOOK_EVENTS = Object.freeze([
52
+ 'checkout.session.completed', 'checkout.session.async_payment_succeeded',
53
+ 'checkout.session.async_payment_failed', 'checkout.session.expired',
54
+ 'customer.created', 'customer.updated', 'customer.deleted',
55
+ 'customer.subscription.created', 'customer.subscription.updated', 'customer.subscription.deleted',
56
+ 'customer.subscription.paused', 'customer.subscription.resumed', 'customer.subscription.trial_will_end',
57
+ 'customer.subscription.pending_update_applied', 'customer.subscription.pending_update_expired',
58
+ 'invoice.paid', 'invoice.payment_failed', 'invoice.payment_action_required', 'invoice.upcoming',
59
+ 'invoice.marked_uncollectible', 'invoice.voided',
60
+ 'charge.refunded', 'refund.created', 'refund.updated', 'refund.failed',
61
+ 'charge.dispute.created', 'charge.dispute.closed', 'charge.dispute.funds_withdrawn',
62
+ 'charge.dispute.funds_reinstated',
63
+ ]);
14
64
  const PaygateParamsSchema = schema({
15
65
  type: 'object', properties: { paygate: { type: 'string' } }, required: ['paygate'],
16
66
  additionalProperties: false,
@@ -19,15 +69,27 @@ const ResyncResultSchema = schema({
19
69
  type: 'object', properties: { ok: { type: 'boolean' } }, required: ['ok'],
20
70
  additionalProperties: false,
21
71
  });
72
+ const ResyncSubscriptionsResultSchema = schema({
73
+ type: 'object',
74
+ properties: { scanned: { type: 'number' }, updated: { type: 'number' } },
75
+ required: ['scanned', 'updated'],
76
+ additionalProperties: false,
77
+ });
22
78
  const aliases = {
23
- base: 'payment-gate', webhook: 'payment-gate:webhook', resync: 'payment-gate:resync',
79
+ base: 'payment-gate',
80
+ webhook: 'payment-gate:webhook',
81
+ resync: 'payment-gate:resync',
82
+ resyncSubscriptions: 'payment-gate:resync-subscriptions',
24
83
  };
25
84
  const base = protocol(route(aliases.base, '/payment-gate', backend()), contract());
26
85
  /** Embedded gateway protocol tree; the alias strings are private adapter details. */
27
86
  export const paymentGate = {
28
87
  base,
88
+ /** Public: Stripe signs the raw body, so no application guard may sit in front of it. */
29
89
  webhook: protocol(route(aliases.webhook, '/webhook/:paygate', backend({ parent: base, method: RouteMethod.POST })), contract.request({ params: PaygateParamsSchema }, typed())),
90
+ /** Re-sync products, prices, the portal configuration and the webhook endpoint. */
30
91
  resync: protocol(route(aliases.resync, '/resync', backend({ parent: base, method: RouteMethod.POST })), contract(ResyncResultSchema), { guards: GUARD_ED25519 }),
92
+ /** Re-read every live paygate subscription and apply it as a webhook would. */
93
+ resyncSubscriptions: protocol(route(aliases.resyncSubscriptions, '/resync-subscriptions', backend({ parent: base, method: RouteMethod.POST })), contract(ResyncSubscriptionsResultSchema), { guards: GUARD_ED25519 }),
31
94
  };
32
- export const paymentGateProtocols = protocols(paymentGate);
33
95
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AACnF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAA;AAC5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,CAAA;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAClD,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAA;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAClD,MAAM,CAAC,MAAM,oBAAoB,GAAG,0BAA0B,CAAA;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,sBAAsB,CAAA;AAC9D,MAAM,CAAC,MAAM,uBAAuB,GAAG,qBAAqB,CAAA;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAA;AACzC,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAA;AAIrD,MAAM,mBAAmB,GAAG,MAAM,CAAgB;IAChD,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC;IAClF,oBAAoB,EAAE,KAAK;CACK,CAAC,CAAA;AACnC,MAAM,kBAAkB,GAAG,MAAM,CAAe;IAC9C,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,IAAI,CAAC;IACzE,oBAAoB,EAAE,KAAK;CACI,CAAC,CAAA;AAElC,MAAM,OAAO,GAAG;IACd,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,qBAAqB;CAC5E,CAAA;AACV,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;AAElF,qFAAqF;AACrF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI;IACJ,OAAO,EAAE,QAAQ,CACf,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAChG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,EAAE,KAAK,EAAa,CAAC,CACtE;IACD,MAAM,EAAE,QAAQ,CACd,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EACrF,QAAQ,CAAC,kBAAkB,CAAC,EAC5B,EAAE,MAAM,EAAE,aAAa,EAAE,CAC1B;CACO,CAAA;AAEV,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC,WAAW,CAAC,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { EntitlementPlanView, EntitlementView } from '@owlmeans/payment';
2
+ import type { Context as ApiContext } from '@owlmeans/server-api';
3
+ import type { EffectivePlan, EntitlementService } from './types.js';
4
+ /** The plan half of an entitlement view. `subscribedAt` is what a grandfathered promo is measured against. */
5
+ export declare const planViewOf: (effective: EffectivePlan) => EntitlementPlanView;
6
+ /** What an entity may do now: its effective plan, every capability and every limit with its usage. */
7
+ export declare const entitlementViewFor: (ctx: ApiContext, entityId: string) => Promise<EntitlementView>;
8
+ /** Plan resolution, the entitlement view and the usage ledger — Mongo only, never the paygate. */
9
+ export declare const makeEntitlementService: (alias?: string) => EntitlementService;
10
+ //# sourceMappingURL=entitlement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entitlement.d.ts","sourceRoot":"","sources":["../src/entitlement.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAc,MAAM,mBAAmB,CAAA;AACzF,OAAO,KAAK,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAOjE,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAKnE,8GAA8G;AAC9G,eAAO,MAAM,UAAU,cAAe,aAAa,KAAG,mBAsBrD,CAAA;AAED,sGAAsG;AACtG,eAAO,MAAM,kBAAkB,QAAe,UAAU,YAAY,MAAM,KAAG,OAAO,CAAC,eAAe,CAoBnG,CAAA;AAED,kGAAkG;AAClG,eAAO,MAAM,sBAAsB,WAAW,MAAM,KAAyB,kBAiB5E,CAAA"}