@owlmeans/server-payment 0.1.18-rc.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.
Files changed (94) hide show
  1. package/README.md +55 -0
  2. package/agent-meta/manifest.json +16 -0
  3. package/agent-meta/skills/server-payment/SKILL.md +80 -0
  4. package/build/actions/index.d.ts +3 -0
  5. package/build/actions/index.d.ts.map +1 -0
  6. package/build/actions/index.js +3 -0
  7. package/build/actions/index.js.map +1 -0
  8. package/build/actions/resync.d.ts +2 -0
  9. package/build/actions/resync.d.ts.map +1 -0
  10. package/build/actions/resync.js +11 -0
  11. package/build/actions/resync.js.map +1 -0
  12. package/build/actions/webhook.d.ts +4 -0
  13. package/build/actions/webhook.d.ts.map +1 -0
  14. package/build/actions/webhook.js +11 -0
  15. package/build/actions/webhook.js.map +1 -0
  16. package/build/config.d.ts +8 -0
  17. package/build/config.d.ts.map +1 -0
  18. package/build/config.js +46 -0
  19. package/build/config.js.map +1 -0
  20. package/build/consts.d.ts +26 -0
  21. package/build/consts.d.ts.map +1 -0
  22. package/build/consts.js +33 -0
  23. package/build/consts.js.map +1 -0
  24. package/build/entrypoints.d.ts +5 -0
  25. package/build/entrypoints.d.ts.map +1 -0
  26. package/build/entrypoints.js +10 -0
  27. package/build/entrypoints.js.map +1 -0
  28. package/build/gate.d.ts +10 -0
  29. package/build/gate.d.ts.map +1 -0
  30. package/build/gate.js +37 -0
  31. package/build/gate.js.map +1 -0
  32. package/build/index.d.ts +12 -0
  33. package/build/index.d.ts.map +1 -0
  34. package/build/index.js +11 -0
  35. package/build/index.js.map +1 -0
  36. package/build/model.d.ts +6 -0
  37. package/build/model.d.ts.map +1 -0
  38. package/build/model.js +33 -0
  39. package/build/model.js.map +1 -0
  40. package/build/observer.d.ts +4 -0
  41. package/build/observer.d.ts.map +1 -0
  42. package/build/observer.js +24 -0
  43. package/build/observer.js.map +1 -0
  44. package/build/plugins/events.d.ts +16 -0
  45. package/build/plugins/events.d.ts.map +1 -0
  46. package/build/plugins/events.js +195 -0
  47. package/build/plugins/events.js.map +1 -0
  48. package/build/plugins/stripe.d.ts +14 -0
  49. package/build/plugins/stripe.d.ts.map +1 -0
  50. package/build/plugins/stripe.js +166 -0
  51. package/build/plugins/stripe.js.map +1 -0
  52. package/build/resource.d.ts +6 -0
  53. package/build/resource.d.ts.map +1 -0
  54. package/build/resource.js +32 -0
  55. package/build/resource.js.map +1 -0
  56. package/build/service.d.ts +4 -0
  57. package/build/service.d.ts.map +1 -0
  58. package/build/service.js +35 -0
  59. package/build/service.js.map +1 -0
  60. package/build/sync.d.ts +5 -0
  61. package/build/sync.d.ts.map +1 -0
  62. package/build/sync.js +93 -0
  63. package/build/sync.js.map +1 -0
  64. package/build/types.d.ts +189 -0
  65. package/build/types.d.ts.map +1 -0
  66. package/build/types.js +2 -0
  67. package/build/types.js.map +1 -0
  68. package/build/utils.d.ts +14 -0
  69. package/build/utils.d.ts.map +1 -0
  70. package/build/utils.js +18 -0
  71. package/build/utils.js.map +1 -0
  72. package/package.json +54 -0
  73. package/src/actions/index.ts +2 -0
  74. package/src/actions/resync.ts +13 -0
  75. package/src/actions/webhook.ts +12 -0
  76. package/src/config.ts +53 -0
  77. package/src/consts.ts +47 -0
  78. package/src/entrypoints.ts +10 -0
  79. package/src/gate.ts +51 -0
  80. package/src/index.ts +13 -0
  81. package/src/model.ts +37 -0
  82. package/src/observer.ts +27 -0
  83. package/src/plugins/events.ts +181 -0
  84. package/src/plugins/stripe.ts +183 -0
  85. package/src/resource.ts +51 -0
  86. package/src/service.ts +35 -0
  87. package/src/sync.ts +97 -0
  88. package/src/types.ts +157 -0
  89. package/src/utils.ts +33 -0
  90. package/tests/checkout.spec.ts +135 -0
  91. package/tests/gate.spec.ts +97 -0
  92. package/tests/protocol.spec.ts +20 -0
  93. package/tests/tsconfig.json +5 -0
  94. package/tsconfig.json +11 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAGhE,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAuB,EAAE,IAAiB,EAAU,EAAE,CAClF,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAA;AAElF,MAAM,aAAa,GAAG,CAAC,OAAuB,EAAE,KAAoB,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;KAClG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;IACrB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK;IACzD,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;IAC1E,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;IACpF,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ;QAC3F,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;QACxE,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;QACpF,MAAM,EAAE,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC;KACrC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;CAC/C,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAEnB,MAAM,mBAAmB,GAAG,KAAK,EAAE,MAAc,EAAE,OAAuB,EAA2B,EAAE;IACrG,MAAM,MAAM,GAA+B;QACzC,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO;QAC7F,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;KAClG,CAAA;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,UAAU,IAAI,OAAO,CAAC,SAAS,IAAI,IAAI;QAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAA;IAC/G,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC3C,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC,CAAA;IACrE,CAAC;AACH,CAAC,CAAA;AAED,MAAM,YAAY,GAAG,KAAK,EAAE,MAAc,EAAE,OAAuB,EAA2B,EAAE,CAC9F,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AAErF,MAAM,qBAAqB,GAAG,KAAK,EAAE,MAAc,EAAE,OAAuB,EAAE,IAAiB,EAAiB,EAAE;IAChH,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC3C,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,EAAE,CAAC;QACrG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IACzD,CAAC;AACH,CAAC,CAAA;AAED,MAAM,iBAAiB,GAAG,KAAK,EAAE,MAAc,EAAE,OAAuB,EAAE,IAAiB,EAAiB,EAAE;IAC5G,IAAI,IAAI,CAAC,WAAW,KAAK,mBAAmB,CAAC,MAAM,EAAE,CAAC;QACpD,MAAM,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;QAClD,OAAM;IACR,CAAC;IACD,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAA;IAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAA;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI;QACtC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAwC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3F,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU;WAClG,KAAK,CAAC,QAAQ,KAAK,QAAQ;WAC3B,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7E,IAAI,KAAK,IAAI,IAAI;QAAE,OAAM;IACzB,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,EAAE,CAAC;QAC3E,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAA;IACzD,CAAC;IACD,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS;QAC9E,mBAAmB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG;QAC7C,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC;QACvE,QAAQ,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;KAC/F,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,GAAe,EAAiB,EAAE;IACjE,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAsB,CAAA;IAC7D,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAA;IAC/F,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IACjC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IAC/B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAkB,CAAA;QACvE,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QAC1C,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC7C,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;YAAE,SAAQ;QACpD,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAChE,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,MAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;QACxE,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAA;YACnF,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC1B,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAA;QACpG,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,6BAA6B,OAAO,CAAC,GAAG,gBAAgB,KAAK,CAAC,MAAM,WAAW,CAAC,CAAA;IAC/F,CAAC;AACH,CAAC,CAAA"}
@@ -0,0 +1,189 @@
1
+ import type { InitializedService, LazyService } from '@owlmeans/context';
2
+ import type { ResourceRecord } from '@owlmeans/resource';
3
+ import type { MongoResource } from '@owlmeans/mongo-resource';
4
+ import type { PluginConfig } from '@owlmeans/config';
5
+ import type { PermissionSet } from '@owlmeans/auth';
6
+ import type { Config as ApiConfig, Context as ApiContext } from '@owlmeans/server-api';
7
+ import type { AmountCheckoutPolicy, CheckoutPricingMode, LimitConfig, PlanDuration, Product, ProductPlan, ProductType, QuantityCheckoutPolicy, SubscriptionStatus } from '@owlmeans/payment';
8
+ export interface Config extends ApiConfig {
9
+ }
10
+ export interface Context<C extends Config = Config> extends ApiContext<C> {
11
+ }
12
+ export interface PaymentProduct extends Product {
13
+ taxCode?: string;
14
+ unitLabel?: string;
15
+ }
16
+ export interface PaymentPlan extends ProductPlan {
17
+ recurring?: {
18
+ interval: 'month' | 'year';
19
+ };
20
+ minQuantity?: number;
21
+ maxQuantity?: number;
22
+ defaultQuantity?: number;
23
+ pricingMode?: CheckoutPricingMode;
24
+ amountPolicy?: AmountCheckoutPolicy;
25
+ quantityPolicy?: QuantityCheckoutPolicy;
26
+ }
27
+ export interface PaymentProductDef {
28
+ sku: string;
29
+ type: ProductType;
30
+ services: string[];
31
+ gateways?: string[];
32
+ taxCode?: string;
33
+ name: string;
34
+ description?: string;
35
+ unitLabel?: string;
36
+ defaultLng?: string;
37
+ capabilities?: PermissionSet[];
38
+ }
39
+ export interface PaymentPlanDef {
40
+ productSku: string;
41
+ sku: string;
42
+ duration: PlanDuration;
43
+ /** Reference unit price in major units; amount checkout uses it only for fulfillment conversion. */
44
+ price: number;
45
+ currency?: string;
46
+ recurring?: {
47
+ interval: 'month' | 'year';
48
+ };
49
+ order?: number;
50
+ title?: string;
51
+ capabilities?: PermissionSet[];
52
+ limits?: {
53
+ [key: string]: LimitConfig;
54
+ };
55
+ pricingMode?: CheckoutPricingMode;
56
+ amountPolicy?: AmountCheckoutPolicy;
57
+ quantityPolicy?: QuantityCheckoutPolicy;
58
+ /** Legacy quantity declarations retained for source compatibility. */
59
+ minQuantity?: number;
60
+ maxQuantity?: number;
61
+ defaultQuantity?: number;
62
+ }
63
+ export interface StripePluginConfig extends PluginConfig {
64
+ api: string;
65
+ webhook: string;
66
+ }
67
+ export interface CreateLinkParams {
68
+ productSku: string;
69
+ /** Stable database key resolved by the application before this in-process call. */
70
+ entityId: string;
71
+ profileId?: string;
72
+ service: string;
73
+ planSku?: string;
74
+ amountMinor?: number;
75
+ successUrl?: string;
76
+ cancelUrl?: string;
77
+ }
78
+ export interface PaymentPlugin {
79
+ createLink: (ctx: ApiContext, params: CreateLinkParams) => Promise<string>;
80
+ handleWebhook: (request: unknown, ctx: ApiContext) => Promise<void>;
81
+ initialize?: (ctx: ApiContext) => Promise<void>;
82
+ manageSubscription: (ctx: ApiContext, entityId: string, returnUrl: string) => Promise<string>;
83
+ }
84
+ export interface GatewayService extends InitializedService {
85
+ createLink: PaymentPlugin['createLink'];
86
+ manageSubscription: PaymentPlugin['manageSubscription'];
87
+ }
88
+ export interface PaymentResourceOptions {
89
+ dbAlias?: string;
90
+ serviceAlias?: string;
91
+ }
92
+ interface TopUpBase {
93
+ entityId: string;
94
+ productSku: string;
95
+ planSku?: string;
96
+ service: string;
97
+ paygate: string;
98
+ externalId: string;
99
+ }
100
+ export interface QuantityTopUpCompletion extends TopUpBase {
101
+ mode: 'quantity';
102
+ units: number;
103
+ }
104
+ export interface AmountTopUpCompletion extends TopUpBase {
105
+ mode: 'amount';
106
+ amountMinor: number;
107
+ chargeAmountMinor: number;
108
+ currency: string;
109
+ }
110
+ export type TopUpCompletion = QuantityTopUpCompletion | AmountTopUpCompletion;
111
+ export interface SubscriptionCompletion {
112
+ entityId: string;
113
+ status: SubscriptionStatus;
114
+ productSku: string;
115
+ planSku: string;
116
+ service: string;
117
+ paygate: string;
118
+ externalId: string;
119
+ isNew: boolean;
120
+ capabilities?: PermissionSet[];
121
+ limits?: {
122
+ [key: string]: LimitConfig;
123
+ };
124
+ }
125
+ export interface TopUpCallback {
126
+ (completion: TopUpCompletion, ctx: ApiContext): Promise<void>;
127
+ }
128
+ export interface SubscriptionCallback {
129
+ (completion: SubscriptionCompletion, ctx: ApiContext): Promise<void>;
130
+ }
131
+ export interface CompletionObserver extends LazyService {
132
+ onTopUp: (cb: TopUpCallback) => void;
133
+ onSubscription: (cb: SubscriptionCallback) => void;
134
+ propagateTopUp: (completion: TopUpCompletion, ctx: ApiContext) => Promise<void>;
135
+ propagateSubscription: (completion: SubscriptionCompletion, ctx: ApiContext) => Promise<void>;
136
+ }
137
+ export interface PaygateCustomerRecord extends ResourceRecord {
138
+ paygate: string;
139
+ externalId: string;
140
+ entityId?: string;
141
+ profileId?: string;
142
+ email?: string;
143
+ name?: string;
144
+ taxId?: string;
145
+ }
146
+ export interface PaygateCustomerResource extends MongoResource<PaygateCustomerRecord> {
147
+ loadByPgId: (externalId: string, paygate: string) => Promise<PaygateCustomerRecord | null>;
148
+ byEntity: (entityId: string, paygate: string) => Promise<PaygateCustomerRecord | null>;
149
+ }
150
+ export interface PaymentSubscriptionRecord extends ResourceRecord {
151
+ sku: string;
152
+ productSku: string;
153
+ entityId: string;
154
+ service: string;
155
+ paygate: string;
156
+ externalId: string;
157
+ status: SubscriptionStatus;
158
+ kind: 'consumable' | 'subscription';
159
+ capabilities?: PermissionSet[];
160
+ limits?: {
161
+ [key: string]: LimitConfig;
162
+ };
163
+ pricingMode?: CheckoutPricingMode;
164
+ units?: number;
165
+ amountMinor?: number;
166
+ chargeAmountMinor?: number;
167
+ currency?: string;
168
+ createdAt: Date;
169
+ endsAt?: Date;
170
+ trialUntil?: Date;
171
+ canceledAt?: Date;
172
+ fulfilledAt?: Date;
173
+ initialPropagatedAt?: Date;
174
+ }
175
+ export interface PaymentSubscriptionResource extends MongoResource<PaymentSubscriptionRecord> {
176
+ byExternalId: (externalId: string, paygate: string) => Promise<PaymentSubscriptionRecord | null>;
177
+ }
178
+ export interface FingerprintRecord extends ResourceRecord {
179
+ sku: string;
180
+ hash: string;
181
+ productId?: string;
182
+ updatedAt: Date;
183
+ }
184
+ export interface FingerprintResource extends MongoResource<FingerprintRecord> {
185
+ bySku: (sku: string) => Promise<FingerprintRecord | null>;
186
+ clear: () => Promise<void>;
187
+ }
188
+ export {};
189
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import Stripe from 'stripe';
2
+ import type { PaymentService } from '@owlmeans/payment';
3
+ import type { Context as ApiContext } from '@owlmeans/server-api';
4
+ import type { CompletionObserver, FingerprintResource, GatewayService, PaygateCustomerResource, PaymentSubscriptionRecord, PaymentSubscriptionResource, StripePluginConfig } from './types.js';
5
+ export declare const payment: (ctx: ApiContext) => PaymentService;
6
+ export declare const gateway: (ctx: ApiContext) => GatewayService;
7
+ export declare const observer: (ctx: ApiContext) => CompletionObserver;
8
+ export declare const paygateCustomers: (ctx: ApiContext) => PaygateCustomerResource;
9
+ export declare const subscriptions: (ctx: ApiContext) => PaymentSubscriptionResource;
10
+ export declare const fingerprints: (ctx: ApiContext) => FingerprintResource;
11
+ export declare const stripeConfig: (ctx: ApiContext) => Promise<StripePluginConfig>;
12
+ export declare const stripeClient: (ctx: ApiContext) => Promise<Stripe>;
13
+ export declare const activeSubscription: (ctx: ApiContext, entityId: string, productSku: string) => Promise<PaymentSubscriptionRecord | null>;
14
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAG3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAKjE,OAAO,KAAK,EACV,kBAAkB,EAAE,mBAAmB,EAAE,cAAc,EAAE,uBAAuB,EAChF,yBAAyB,EAAE,2BAA2B,EAAE,kBAAkB,EAC3E,MAAM,YAAY,CAAA;AAEnB,eAAO,MAAM,OAAO,QAAS,UAAU,KAAG,cAA8D,CAAA;AACxG,eAAO,MAAM,OAAO,QAAS,UAAU,KAAG,cAA8D,CAAA;AACxG,eAAO,MAAM,QAAQ,QAAS,UAAU,KAAG,kBAAuE,CAAA;AAClH,eAAO,MAAM,gBAAgB,QAAS,UAAU,KAAG,uBACU,CAAA;AAC7D,eAAO,MAAM,aAAa,QAAS,UAAU,KAAG,2BACqB,CAAA;AACrE,eAAO,MAAM,YAAY,QAAS,UAAU,KAAG,mBACa,CAAA;AAC5D,eAAO,MAAM,YAAY,QAAe,UAAU,KAAG,OAAO,CAAC,kBAAkB,CAEA,CAAA;AAC/E,eAAO,MAAM,YAAY,QAAe,UAAU,KAAG,OAAO,CAAC,MAAM,CAA8C,CAAA;AACjH,eAAO,MAAM,kBAAkB,QACxB,UAAU,YAAY,MAAM,cAAc,MAAM,KACpD,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAGzC,CAAA"}
package/build/utils.js ADDED
@@ -0,0 +1,18 @@
1
+ import Stripe from 'stripe';
2
+ import { PLUGINS } from '@owlmeans/config';
3
+ import { DEFAULT_ALIAS as PAYMENT_SERVICE, SubscriptionStatus } from '@owlmeans/payment';
4
+ import { GATEWAY_SERVICE, PAYMENT_OBSERVER, RES_PAYGATE_CUSTOMER, RES_PAYMENT_FINGERPRINT, RES_PAYMENT_SUBSCRIPTION, STRIPE_PLUGIN_CONFIG, } from './consts.js';
5
+ export const payment = (ctx) => ctx.service(PAYMENT_SERVICE);
6
+ export const gateway = (ctx) => ctx.service(GATEWAY_SERVICE);
7
+ export const observer = (ctx) => ctx.service(PAYMENT_OBSERVER);
8
+ export const paygateCustomers = (ctx) => ctx.resource(RES_PAYGATE_CUSTOMER);
9
+ export const subscriptions = (ctx) => ctx.resource(RES_PAYMENT_SUBSCRIPTION);
10
+ export const fingerprints = (ctx) => ctx.resource(RES_PAYMENT_FINGERPRINT);
11
+ export const stripeConfig = async (ctx) => await ctx
12
+ .getConfigResource(PLUGINS).get(STRIPE_PLUGIN_CONFIG);
13
+ export const stripeClient = async (ctx) => new Stripe((await stripeConfig(ctx)).api);
14
+ export const activeSubscription = async (ctx, entityId, productSku) => await subscriptions(ctx).load({
15
+ entityId, productSku, kind: 'subscription',
16
+ status: [SubscriptionStatus.Active, SubscriptionStatus.Trial],
17
+ });
18
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAGxF,OAAO,EACL,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,uBAAuB,EAChF,wBAAwB,EAAE,oBAAoB,GAC/C,MAAM,aAAa,CAAA;AAMpB,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAe,EAAkB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAiB,eAAe,CAAC,CAAA;AACxG,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAe,EAAkB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAiB,eAAe,CAAC,CAAA;AACxG,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAe,EAAsB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAqB,gBAAgB,CAAC,CAAA;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAe,EAA2B,EAAE,CAC3E,GAAG,CAAC,QAAQ,CAA0B,oBAAoB,CAAC,CAAA;AAC7D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAe,EAA+B,EAAE,CAC5E,GAAG,CAAC,QAAQ,CAA8B,wBAAwB,CAAC,CAAA;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAe,EAAuB,EAAE,CACnE,GAAG,CAAC,QAAQ,CAAsB,uBAAuB,CAAC,CAAA;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,GAAe,EAA+B,EAAE,CACjF,MAAO,GAAoG;KACxG,iBAAiB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAuB,CAAA;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,GAAe,EAAmB,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AACjH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,GAAe,EAAE,QAAgB,EAAE,UAAkB,EACV,EAAE,CAAC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAC5E,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc;IAC1C,MAAM,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC;CAC9D,CAAC,CAAA"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@owlmeans/server-payment",
3
+ "version": "0.1.18-rc.0",
4
+ "license": "MIT",
5
+ "description": "Protocol-bound payment resources, entitlement gates, and Stripe checkout for OwlMeans servers.",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "tsc -b",
9
+ "dev": "sleep 12 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
10
+ "watch": "tsc -b -w --preserveWatchOutput --pretty",
11
+ "test": "bun test ./tests"
12
+ },
13
+ "main": "build/index.js",
14
+ "module": "build/index.js",
15
+ "types": "build/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "import": "./build/index.js",
19
+ "require": "./build/index.js",
20
+ "default": "./build/index.js",
21
+ "module": "./build/index.js",
22
+ "types": "./build/index.d.ts"
23
+ }
24
+ },
25
+ "peerDependencies": {
26
+ "ajv": "*"
27
+ },
28
+ "dependencies": {
29
+ "@owlmeans/auth": "^0.1.18-rc.13",
30
+ "@owlmeans/config": "^0.1.18-rc.16",
31
+ "@owlmeans/context": "^0.1.18-rc.12",
32
+ "@owlmeans/entrypoint": "^0.1.18-rc.15",
33
+ "@owlmeans/mongo-resource": "^0.1.18-rc.16",
34
+ "@owlmeans/payment": "^0.1.18-rc.17",
35
+ "@owlmeans/resource": "^0.1.18-rc.13",
36
+ "@owlmeans/route": "^0.1.18-rc.13",
37
+ "@owlmeans/server-api": "^0.1.18-rc.21",
38
+ "@owlmeans/server-app": "^0.1.18-rc.22",
39
+ "@owlmeans/server-context": "^0.1.18-rc.16",
40
+ "@owlmeans/server-entrypoint": "^0.1.18-rc.15",
41
+ "async-mutex": "^0.5.0",
42
+ "stripe": "^17.7.0"
43
+ },
44
+ "devDependencies": {
45
+ "@owlmeans/dep-config": "workspace:*",
46
+ "@types/bun": "^1.4.0",
47
+ "@types/node": "^26.1.0",
48
+ "nodemon": "^3.1.14",
49
+ "typescript": "^7.0.2"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ }
54
+ }
@@ -0,0 +1,2 @@
1
+ export * from './webhook.js'
2
+ export * from './resync.js'
@@ -0,0 +1,13 @@
1
+ import { handlers } from '@owlmeans/server-api'
2
+ import { paymentGate } from '../consts.js'
3
+ import { fingerprints } from '../utils.js'
4
+ import { initialize } from '../sync.js'
5
+ import type { Context } from '../types.js'
6
+
7
+ const bind = handlers<Context>()
8
+
9
+ export const resync = bind.request(paymentGate.resync, async (_request, context) => {
10
+ await fingerprints(context).clear()
11
+ await initialize(context)
12
+ return { ok: true }
13
+ })
@@ -0,0 +1,12 @@
1
+ import { UnknownPaygate } from '@owlmeans/payment'
2
+ import { handlers } from '@owlmeans/server-api'
3
+ import { paymentGate, STRIPE_PAYGATE_ALIAS } from '../consts.js'
4
+ import { stripePlugin } from '../plugins/stripe.js'
5
+ import type { Context } from '../types.js'
6
+
7
+ const bind = handlers<Context>()
8
+
9
+ export const webhook = bind.params(paymentGate.webhook, async ({ paygate }, context, request) => {
10
+ if (paygate !== STRIPE_PAYGATE_ALIAS) throw new UnknownPaygate(paygate)
11
+ await stripePlugin.handleWebhook(request, context)
12
+ })
package/src/config.ts ADDED
@@ -0,0 +1,53 @@
1
+ import { toConfigRecord } from '@owlmeans/server-app'
2
+ import { plugin } from '@owlmeans/config'
3
+ import {
4
+ assertAmountCheckoutPolicy, assertQuantityCheckoutPolicy, CheckoutPricingMode,
5
+ PLAN_RECORD_PREFIX, PLAN_RECORD_TYPE, PlanStatus, PRODUCT_RECORD_PREFIX, PRODUCT_RECORD_TYPE,
6
+ } from '@owlmeans/payment'
7
+ import { STRIPE_PAYGATE_ALIAS, STRIPE_PLUGIN_CONFIG } from './consts.js'
8
+ import type { Config, PaymentPlan, PaymentPlanDef, PaymentProduct, PaymentProductDef } from './types.js'
9
+
10
+ export const declarePaymentProduct = (cfg: Config, def: PaymentProductDef): void => {
11
+ cfg.records = cfg.records ?? []
12
+ const product: PaymentProduct = {
13
+ type: def.type, sku: def.sku, title: def.name, description: def.description,
14
+ defaultLng: def.defaultLng ?? 'en', services: def.services,
15
+ gateways: def.gateways ?? [STRIPE_PAYGATE_ALIAS], capabilities: def.capabilities,
16
+ taxCode: def.taxCode, unitLabel: def.unitLabel,
17
+ }
18
+ cfg.records.push({ ...toConfigRecord(product), recordType: PRODUCT_RECORD_TYPE, id: `${PRODUCT_RECORD_PREFIX}:${def.sku}` })
19
+ }
20
+
21
+ export const declarePaymentPlan = (cfg: Config, def: PaymentPlanDef): void => {
22
+ cfg.records = cfg.records ?? []
23
+ const pricingMode = def.pricingMode
24
+ if (pricingMode === CheckoutPricingMode.Amount) {
25
+ if (def.amountPolicy == null) throw new TypeError(`Amount checkout plan '${def.sku}' requires amountPolicy`)
26
+ assertAmountCheckoutPolicy(def.amountPolicy)
27
+ }
28
+ const quantityPolicy = def.quantityPolicy ?? (
29
+ def.minQuantity != null || def.maxQuantity != null || def.defaultQuantity != null
30
+ ? {
31
+ minimum: def.minQuantity ?? 1,
32
+ maximum: def.maxQuantity ?? Math.max(100_000, def.minQuantity ?? 1),
33
+ default: def.defaultQuantity ?? def.minQuantity ?? 1,
34
+ }
35
+ : undefined
36
+ )
37
+ if (quantityPolicy != null) assertQuantityCheckoutPolicy(quantityPolicy)
38
+
39
+ const plan: PaymentPlan = {
40
+ productSku: def.productSku, sku: def.sku, status: PlanStatus.Active,
41
+ duration: def.duration, price: def.price, currency: def.currency ?? def.amountPolicy?.currency ?? 'usd',
42
+ order: def.order ?? 0, title: def.title ?? def.sku, capabilities: def.capabilities,
43
+ limits: def.limits, recurring: def.recurring, pricingMode, amountPolicy: def.amountPolicy,
44
+ quantityPolicy,
45
+ minQuantity: quantityPolicy?.minimum, maxQuantity: quantityPolicy?.maximum,
46
+ defaultQuantity: quantityPolicy?.default,
47
+ }
48
+ cfg.records.push({ ...toConfigRecord(plan), recordType: PLAN_RECORD_TYPE, id: `${PLAN_RECORD_PREFIX}:${def.sku}` })
49
+ }
50
+
51
+ export const stripeSecrets = (cfg: Config, paths: { api: string; webhook: string }): void => {
52
+ plugin(cfg, { api: paths.api, webhook: paths.webhook }, STRIPE_PLUGIN_CONFIG)
53
+ }
package/src/consts.ts ADDED
@@ -0,0 +1,47 @@
1
+ import { contract, protocol, protocols, schema, typed } from '@owlmeans/entrypoint'
2
+ import { backend, route, RouteMethod } from '@owlmeans/route'
3
+ import { GUARD_ED25519 } from '@owlmeans/server-app'
4
+ import type { JSONSchemaType } from 'ajv'
5
+
6
+ export const STRIPE_PAYGATE_ALIAS = 'stripe'
7
+ export const STRIPE_PLUGIN_CONFIG = '_external:stripe'
8
+ export const STRIPE_SIGNATURE = 'Stripe-Signature'
9
+ export const GATEWAY_SERVICE = 'payment-gateway'
10
+ export const PAYMENT_OBSERVER = 'payment-observer'
11
+ export const RES_PAYGATE_CUSTOMER = 'payment-paygate-customer'
12
+ export const RES_PAYMENT_SUBSCRIPTION = 'payment-subscription'
13
+ export const RES_PAYMENT_FINGERPRINT = 'payment-fingerprint'
14
+ export const COMPLETION_TOP_UP = 'top-up'
15
+ export const COMPLETION_SUBSCRIPTION = 'subscription'
16
+
17
+ export interface PaygateParams { paygate: string }
18
+ export interface ResyncResult { ok: boolean }
19
+ const PaygateParamsSchema = schema<PaygateParams>({
20
+ type: 'object', properties: { paygate: { type: 'string' } }, required: ['paygate'],
21
+ additionalProperties: false,
22
+ } as JSONSchemaType<PaygateParams>)
23
+ const ResyncResultSchema = schema<ResyncResult>({
24
+ type: 'object', properties: { ok: { type: 'boolean' } }, required: ['ok'],
25
+ additionalProperties: false,
26
+ } as JSONSchemaType<ResyncResult>)
27
+
28
+ const aliases = {
29
+ base: 'payment-gate', webhook: 'payment-gate:webhook', resync: 'payment-gate:resync',
30
+ } as const
31
+ const base = protocol(route(aliases.base, '/payment-gate', backend()), contract())
32
+
33
+ /** Embedded gateway protocol tree; the alias strings are private adapter details. */
34
+ export const paymentGate = {
35
+ base,
36
+ webhook: protocol(
37
+ route(aliases.webhook, '/webhook/:paygate', backend({ parent: base, method: RouteMethod.POST })),
38
+ contract.request({ params: PaygateParamsSchema }, typed<undefined>()),
39
+ ),
40
+ resync: protocol(
41
+ route(aliases.resync, '/resync', backend({ parent: base, method: RouteMethod.POST })),
42
+ contract(ResyncResultSchema),
43
+ { guards: GUARD_ED25519 },
44
+ ),
45
+ } as const
46
+
47
+ export const paymentGateProtocols = protocols(paymentGate)
@@ -0,0 +1,10 @@
1
+ import { bind } from '@owlmeans/server-entrypoint'
2
+ import { paymentGate } from './consts.js'
3
+ import { resync, webhook } from './actions/index.js'
4
+
5
+ /** Runtime-local bindings for the shared immutable payment-gateway protocol tree. */
6
+ export const paymentGateEntrypoints = [
7
+ bind(paymentGate.base),
8
+ bind(paymentGate.webhook, webhook),
9
+ bind(paymentGate.resync, resync),
10
+ ]
package/src/gate.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { createLazyService } from '@owlmeans/context'
2
+ import type { AbstractRequest, GateService } from '@owlmeans/entrypoint'
3
+ import { AuthForbidden, entitySlugOf } from '@owlmeans/auth'
4
+ import type { Auth, PermissionSet } from '@owlmeans/auth'
5
+ import { ENTITLEMENT_GATE, hasEntitlement, SubscriptionStatus } from '@owlmeans/payment'
6
+ import type { Context as ApiContext } from '@owlmeans/server-api'
7
+ import { subscriptions } from './utils.js'
8
+ import type { Config, Context } from './types.js'
9
+
10
+ export interface EntitlementGateOptions {
11
+ productSkus?: string[]
12
+ resolveEntity?: (req: AbstractRequest) => string | null
13
+ }
14
+
15
+ export const entitlementsOf = async (
16
+ ctx: ApiContext, entityId: string, productSkus?: string[],
17
+ ): Promise<PermissionSet[]> => {
18
+ const { items } = await subscriptions(ctx).list({
19
+ entityId, status: [SubscriptionStatus.Active, SubscriptionStatus.Trial], productSku: productSkus,
20
+ }, { size: 0 })
21
+ return items.flatMap(record => record.capabilities ?? [])
22
+ }
23
+
24
+ const defaultEntity = (req: AbstractRequest): string | null =>
25
+ req.entity?.id ?? entitySlugOf(req.auth as Auth | undefined) ?? null
26
+
27
+ export const makeEntitlementGate = (
28
+ alias: string = ENTITLEMENT_GATE, opts?: EntitlementGateOptions,
29
+ ): GateService => {
30
+ const service = createLazyService<GateService>(alias, {
31
+ assert: async (req, _, params) => {
32
+ await service.ready()
33
+ const ctx = service.assertCtx<Config, Context>() as unknown as ApiContext
34
+ if (req.auth == null) throw new AuthForbidden('auth')
35
+ const entityId = (opts?.resolveEntity ?? defaultEntity)(req)
36
+ if (entityId == null || entityId === '') throw new AuthForbidden('entity')
37
+
38
+ let capabilities: PermissionSet[]
39
+ try {
40
+ capabilities = await entitlementsOf(ctx, entityId, opts?.productSkus)
41
+ } catch (error) {
42
+ console.error(`entitlement gate: cannot read subscriptions for "${entityId}"`, error)
43
+ throw new AuthForbidden('entitlement')
44
+ }
45
+ if (!params.some(param => hasEntitlement(capabilities, param))) {
46
+ throw new AuthForbidden('entitlement')
47
+ }
48
+ },
49
+ })
50
+ return service
51
+ }
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ export type * from './types.js'
2
+ export * from './consts.js'
3
+ export * from './config.js'
4
+ export * from './resource.js'
5
+ export * from './observer.js'
6
+ export * from './service.js'
7
+ export * from './gate.js'
8
+ export * from './entrypoints.js'
9
+ export { initialize as syncPaymentProducts, planLookupKey } from './sync.js'
10
+ export { amountCheckoutLineItem } from './plugins/stripe.js'
11
+ export {
12
+ payment, gateway, observer, paygateCustomers, subscriptions, fingerprints, activeSubscription,
13
+ } from './utils.js'
package/src/model.ts ADDED
@@ -0,0 +1,37 @@
1
+ import type { JSONSchemaType } from 'ajv'
2
+ import { PermissionSetSchema } from '@owlmeans/auth'
3
+ import { LimitConfigSchema } from '@owlmeans/payment'
4
+ import type { FingerprintRecord, PaygateCustomerRecord, PaymentSubscriptionRecord } from './types.js'
5
+
6
+ export const PaygateCustomerSchema = {
7
+ type: 'object',
8
+ properties: {
9
+ id: { type: 'string', nullable: true }, paygate: { type: 'string' }, externalId: { type: 'string' },
10
+ entityId: { type: 'string', nullable: true }, profileId: { type: 'string', nullable: true },
11
+ email: { type: 'string', nullable: true }, name: { type: 'string', nullable: true },
12
+ taxId: { type: 'string', nullable: true },
13
+ },
14
+ required: ['paygate', 'externalId'], additionalProperties: true,
15
+ } as unknown as JSONSchemaType<PaygateCustomerRecord>
16
+
17
+ export const PaymentSubscriptionSchema = {
18
+ type: 'object',
19
+ properties: {
20
+ id: { type: 'string', nullable: true }, sku: { type: 'string' }, productSku: { type: 'string' },
21
+ entityId: { type: 'string' }, service: { type: 'string' }, paygate: { type: 'string' },
22
+ externalId: { type: 'string' }, status: { type: 'string' }, kind: { type: 'string' },
23
+ capabilities: { type: 'array', items: PermissionSetSchema as never, nullable: true },
24
+ limits: { type: 'object', nullable: true, additionalProperties: LimitConfigSchema as never, required: [] },
25
+ },
26
+ required: ['sku', 'productSku', 'entityId', 'service', 'paygate', 'externalId', 'status', 'kind'],
27
+ additionalProperties: true,
28
+ } as unknown as JSONSchemaType<PaymentSubscriptionRecord>
29
+
30
+ export const FingerprintSchema = {
31
+ type: 'object',
32
+ properties: {
33
+ id: { type: 'string', nullable: true }, sku: { type: 'string' }, hash: { type: 'string' },
34
+ productId: { type: 'string', nullable: true },
35
+ },
36
+ required: ['sku', 'hash'], additionalProperties: true,
37
+ } as unknown as JSONSchemaType<FingerprintRecord>
@@ -0,0 +1,27 @@
1
+ import { createLazyService } from '@owlmeans/context'
2
+ import { PAYMENT_OBSERVER } from './consts.js'
3
+ import type { CompletionObserver, Config, Context, SubscriptionCallback, TopUpCallback } from './types.js'
4
+
5
+ export const makeCompletionObserverService = (
6
+ alias: string = PAYMENT_OBSERVER,
7
+ ): CompletionObserver => {
8
+ const topUpCallbacks: TopUpCallback[] = []
9
+ const subscriptionCallbacks: SubscriptionCallback[] = []
10
+ return createLazyService<CompletionObserver>(alias, {
11
+ onTopUp: cb => { topUpCallbacks.push(cb) },
12
+ onSubscription: cb => { subscriptionCallbacks.push(cb) },
13
+ propagateTopUp: async (completion, ctx) => {
14
+ for (const callback of topUpCallbacks) await callback(completion, ctx)
15
+ },
16
+ propagateSubscription: async (completion, ctx) => {
17
+ for (const callback of subscriptionCallbacks) await callback(completion, ctx)
18
+ },
19
+ }, service => async () => { service.initialized = true })
20
+ }
21
+
22
+ export const appendCompletionObserver = <C extends Config, T extends Context<C>>(
23
+ ctx: T, alias: string = PAYMENT_OBSERVER,
24
+ ): T => {
25
+ if (!ctx.hasService(alias)) ctx.registerService(makeCompletionObserverService(alias))
26
+ return ctx
27
+ }