@owlmeans/server-payment 0.1.18-rc.30 → 0.1.18-rc.32
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 +35 -24
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-payment/SKILL.md +39 -39
- package/build/access/types.d.ts +46 -0
- package/build/access/types.d.ts.map +1 -0
- package/build/access/types.js +2 -0
- package/build/access/types.js.map +1 -0
- package/build/access.d.ts +6 -0
- package/build/access.d.ts.map +1 -0
- package/build/access.js +45 -0
- package/build/access.js.map +1 -0
- package/build/actions/resync-subscriptions.d.ts.map +1 -1
- package/build/actions/resync-subscriptions.js +3 -2
- package/build/actions/resync-subscriptions.js.map +1 -1
- package/build/actions/resync.d.ts.map +1 -1
- package/build/actions/resync.js +7 -5
- package/build/actions/resync.js.map +1 -1
- package/build/actions/webhook.d.ts.map +1 -1
- package/build/actions/webhook.js +5 -4
- package/build/actions/webhook.js.map +1 -1
- package/build/bootstrap/types.d.ts +16 -0
- package/build/bootstrap/types.d.ts.map +1 -0
- package/build/bootstrap/types.js +2 -0
- package/build/bootstrap/types.js.map +1 -0
- package/build/bootstrap.d.ts +6 -0
- package/build/bootstrap.d.ts.map +1 -0
- package/build/bootstrap.js +26 -0
- package/build/bootstrap.js.map +1 -0
- package/build/catalogue/types.d.ts +38 -0
- package/build/catalogue/types.d.ts.map +1 -0
- package/build/catalogue/types.js +2 -0
- package/build/catalogue/types.js.map +1 -0
- package/build/catalogue.d.ts +6 -0
- package/build/catalogue.d.ts.map +1 -0
- package/build/catalogue.js +110 -0
- package/build/catalogue.js.map +1 -0
- package/build/commit/types.d.ts +22 -0
- package/build/commit/types.d.ts.map +1 -0
- package/build/commit/types.js +2 -0
- package/build/commit/types.js.map +1 -0
- package/build/commit.d.ts +6 -0
- package/build/commit.d.ts.map +1 -0
- package/build/commit.js +125 -0
- package/build/commit.js.map +1 -0
- package/build/config.d.ts +1 -17
- package/build/config.d.ts.map +1 -1
- package/build/config.js +9 -46
- package/build/config.js.map +1 -1
- package/build/consumer/cancellation/types.d.ts +11 -0
- package/build/consumer/cancellation/types.d.ts.map +1 -0
- package/build/consumer/cancellation/types.js +2 -0
- package/build/consumer/cancellation/types.js.map +1 -0
- package/build/consumer/cancellation.d.ts +6 -0
- package/build/consumer/cancellation.d.ts.map +1 -0
- package/build/consumer/cancellation.js +33 -0
- package/build/consumer/cancellation.js.map +1 -0
- package/build/consumer/capture/types.d.ts +50 -0
- package/build/consumer/capture/types.d.ts.map +1 -0
- package/build/consumer/capture/types.js +2 -0
- package/build/consumer/capture/types.js.map +1 -0
- package/build/consumer/capture.d.ts +4 -59
- package/build/consumer/capture.d.ts.map +1 -1
- package/build/consumer/capture.js +277 -293
- package/build/consumer/capture.js.map +1 -1
- package/build/consumer/format/types.d.ts +30 -0
- package/build/consumer/format/types.d.ts.map +1 -0
- package/build/consumer/format/types.js +2 -0
- package/build/consumer/format/types.js.map +1 -0
- package/build/consumer/format.d.ts +3 -26
- package/build/consumer/format.d.ts.map +1 -1
- package/build/consumer/format.js +69 -77
- package/build/consumer/format.js.map +1 -1
- package/build/consumer/handlers.d.ts.map +1 -1
- package/build/consumer/handlers.js +8 -7
- package/build/consumer/handlers.js.map +1 -1
- package/build/consumer/index.d.ts +7 -4
- package/build/consumer/index.d.ts.map +1 -1
- package/build/consumer/index.js +3 -3
- package/build/consumer/index.js.map +1 -1
- package/build/consumer/mail/types.d.ts +29 -0
- package/build/consumer/mail/types.d.ts.map +1 -0
- package/build/consumer/mail/types.js +2 -0
- package/build/consumer/mail/types.js.map +1 -0
- package/build/consumer/mail.d.ts +4 -25
- package/build/consumer/mail.d.ts.map +1 -1
- package/build/consumer/mail.js +211 -212
- package/build/consumer/mail.js.map +1 -1
- package/build/consumer/observers/types.d.ts +15 -0
- package/build/consumer/observers/types.d.ts.map +1 -0
- package/build/consumer/observers/types.js +2 -0
- package/build/consumer/observers/types.js.map +1 -0
- package/build/consumer/observers.d.ts +6 -0
- package/build/consumer/observers.d.ts.map +1 -0
- package/build/consumer/observers.js +74 -0
- package/build/consumer/observers.js.map +1 -0
- package/build/consumer/origin/types.d.ts +17 -0
- package/build/consumer/origin/types.d.ts.map +1 -0
- package/build/consumer/origin/types.js +2 -0
- package/build/consumer/origin/types.js.map +1 -0
- package/build/consumer/origin.d.ts +4 -10
- package/build/consumer/origin.d.ts.map +1 -1
- package/build/consumer/origin.js +39 -42
- package/build/consumer/origin.js.map +1 -1
- package/build/consumer/reconcile/types.d.ts +13 -0
- package/build/consumer/reconcile/types.d.ts.map +1 -0
- package/build/consumer/reconcile/types.js +2 -0
- package/build/consumer/reconcile/types.js.map +1 -0
- package/build/consumer/reconcile.d.ts +2 -9
- package/build/consumer/reconcile.d.ts.map +1 -1
- package/build/consumer/reconcile.js +283 -279
- package/build/consumer/reconcile.js.map +1 -1
- package/build/consumer/records/types.d.ts +66 -0
- package/build/consumer/records/types.d.ts.map +1 -0
- package/build/consumer/records/types.js +2 -0
- package/build/consumer/records/types.js.map +1 -0
- package/build/consumer/records.d.ts +4 -106
- package/build/consumer/records.d.ts.map +1 -1
- package/build/consumer/records.js +225 -281
- package/build/consumer/records.js.map +1 -1
- package/build/consumer/service.d.ts +2 -18
- package/build/consumer/service.d.ts.map +1 -1
- package/build/consumer/service.js +203 -268
- package/build/consumer/service.js.map +1 -1
- package/build/consumer/types.d.ts +5 -8
- package/build/consumer/types.d.ts.map +1 -1
- package/build/consumer/types.local.d.ts +4 -3
- package/build/consumer/types.local.d.ts.map +1 -1
- package/build/consumer/withdrawal/types.d.ts +36 -0
- package/build/consumer/withdrawal/types.d.ts.map +1 -0
- package/build/consumer/withdrawal/types.js +2 -0
- package/build/consumer/withdrawal/types.js.map +1 -0
- package/build/consumer/withdrawal.d.ts +4 -32
- package/build/consumer/withdrawal.d.ts.map +1 -1
- package/build/consumer/withdrawal.js +204 -214
- package/build/consumer/withdrawal.js.map +1 -1
- package/build/entitlement.d.ts +1 -7
- package/build/entitlement.d.ts.map +1 -1
- package/build/entitlement.js +41 -38
- package/build/entitlement.js.map +1 -1
- package/build/entrypoints.js +1 -1
- package/build/entrypoints.js.map +1 -1
- package/build/gate/request.d.ts +4 -0
- package/build/gate/request.d.ts.map +1 -0
- package/build/gate/request.js +17 -0
- package/build/gate/request.js.map +1 -0
- package/build/gate/types.d.ts +15 -0
- package/build/gate/types.d.ts.map +1 -0
- package/build/gate/types.js +2 -0
- package/build/gate/types.js.map +1 -0
- package/build/gate.d.ts +4 -14
- package/build/gate.d.ts.map +1 -1
- package/build/gate.js +7 -32
- package/build/gate.js.map +1 -1
- package/build/index.d.ts +47 -17
- package/build/index.d.ts.map +1 -1
- package/build/index.js +26 -14
- package/build/index.js.map +1 -1
- package/build/limit.d.ts.map +1 -1
- package/build/limit.js +6 -6
- package/build/limit.js.map +1 -1
- package/build/model.d.ts +15 -0
- package/build/model.d.ts.map +1 -0
- package/build/model.js +247 -0
- package/build/model.js.map +1 -0
- package/build/models/declarations/types.d.ts +22 -0
- package/build/models/declarations/types.d.ts.map +1 -0
- package/build/models/declarations/types.js +2 -0
- package/build/models/declarations/types.js.map +1 -0
- package/build/models/declarations.d.ts +4 -0
- package/build/models/declarations.d.ts.map +1 -0
- package/build/models/declarations.js +26 -0
- package/build/models/declarations.js.map +1 -0
- package/build/models/purchase/types.d.ts +13 -0
- package/build/models/purchase/types.d.ts.map +1 -0
- package/build/models/purchase/types.js +2 -0
- package/build/models/purchase/types.js.map +1 -0
- package/build/models/purchase.d.ts +4 -0
- package/build/models/purchase.d.ts.map +1 -0
- package/build/models/purchase.js +37 -0
- package/build/models/purchase.js.map +1 -0
- package/build/plan/types.d.ts +21 -0
- package/build/plan/types.d.ts.map +1 -0
- package/build/plan/types.js +2 -0
- package/build/plan/types.js.map +1 -0
- package/build/plan.d.ts +5 -31
- package/build/plan.d.ts.map +1 -1
- package/build/plan.js +26 -98
- package/build/plan.js.map +1 -1
- package/build/plugins/checkout-plugins/types.d.ts +25 -0
- package/build/plugins/checkout-plugins/types.d.ts.map +1 -0
- package/build/plugins/checkout-plugins/types.js +2 -0
- package/build/plugins/checkout-plugins/types.js.map +1 -0
- package/build/plugins/checkout-plugins.d.ts +7 -36
- package/build/plugins/checkout-plugins.d.ts.map +1 -1
- package/build/plugins/checkout-plugins.js +62 -115
- package/build/plugins/checkout-plugins.js.map +1 -1
- package/build/plugins/checkout-policy/types.d.ts +18 -0
- package/build/plugins/checkout-policy/types.d.ts.map +1 -0
- package/build/plugins/checkout-policy/types.js +2 -0
- package/build/plugins/checkout-policy/types.js.map +1 -0
- package/build/plugins/checkout-policy.d.ts +4 -0
- package/build/plugins/checkout-policy.d.ts.map +1 -0
- package/build/plugins/checkout-policy.js +26 -0
- package/build/plugins/checkout-policy.js.map +1 -0
- package/build/plugins/checkout-registry/types.d.ts +7 -0
- package/build/plugins/checkout-registry/types.d.ts.map +1 -0
- package/build/plugins/checkout-registry/types.js +2 -0
- package/build/plugins/checkout-registry/types.js.map +1 -0
- package/build/plugins/checkout-registry.d.ts +8 -0
- package/build/plugins/checkout-registry.d.ts.map +1 -0
- package/build/plugins/checkout-registry.js +21 -0
- package/build/plugins/checkout-registry.js.map +1 -0
- package/build/plugins/customer-lock/types.d.ts +6 -0
- package/build/plugins/customer-lock/types.d.ts.map +1 -0
- package/build/plugins/customer-lock/types.js +2 -0
- package/build/plugins/customer-lock/types.js.map +1 -0
- package/build/plugins/customer-lock.d.ts +5 -0
- package/build/plugins/customer-lock.d.ts.map +1 -0
- package/build/plugins/customer-lock.js +22 -0
- package/build/plugins/customer-lock.js.map +1 -0
- package/build/plugins/estimate/cache.d.ts +4 -0
- package/build/plugins/estimate/cache.d.ts.map +1 -0
- package/build/plugins/estimate/cache.js +7 -0
- package/build/plugins/estimate/cache.js.map +1 -0
- package/build/plugins/estimate/types.d.ts +27 -0
- package/build/plugins/estimate/types.d.ts.map +1 -0
- package/build/plugins/estimate/types.js +2 -0
- package/build/plugins/estimate/types.js.map +1 -0
- package/build/plugins/estimate.d.ts +4 -16
- package/build/plugins/estimate.d.ts.map +1 -1
- package/build/plugins/estimate.js +168 -182
- package/build/plugins/estimate.js.map +1 -1
- package/build/plugins/events/types.d.ts +12 -0
- package/build/plugins/events/types.d.ts.map +1 -0
- package/build/plugins/events/types.js +2 -0
- package/build/plugins/events/types.js.map +1 -0
- package/build/plugins/events.d.ts +2 -30
- package/build/plugins/events.d.ts.map +1 -1
- package/build/plugins/events.js +92 -284
- package/build/plugins/events.js.map +1 -1
- package/build/plugins/fx/types.d.ts +31 -0
- package/build/plugins/fx/types.d.ts.map +1 -0
- package/build/plugins/fx/types.js +2 -0
- package/build/plugins/fx/types.js.map +1 -0
- package/build/plugins/fx.d.ts +4 -26
- package/build/plugins/fx.d.ts.map +1 -1
- package/build/plugins/fx.js +65 -66
- package/build/plugins/fx.js.map +1 -1
- package/build/plugins/portal/types.d.ts +44 -0
- package/build/plugins/portal/types.d.ts.map +1 -0
- package/build/plugins/portal/types.js +2 -0
- package/build/plugins/portal/types.js.map +1 -0
- package/build/plugins/portal.d.ts +4 -38
- package/build/plugins/portal.d.ts.map +1 -1
- package/build/plugins/portal.js +218 -241
- package/build/plugins/portal.js.map +1 -1
- package/build/plugins/refunds/types.d.ts +35 -0
- package/build/plugins/refunds/types.d.ts.map +1 -0
- package/build/plugins/refunds/types.js +2 -0
- package/build/plugins/refunds/types.js.map +1 -0
- package/build/plugins/refunds.d.ts +4 -11
- package/build/plugins/refunds.d.ts.map +1 -1
- package/build/plugins/refunds.js +71 -70
- package/build/plugins/refunds.js.map +1 -1
- package/build/plugins/session/types.d.ts +32 -0
- package/build/plugins/session/types.d.ts.map +1 -0
- package/build/plugins/session/types.js +2 -0
- package/build/plugins/session/types.js.map +1 -0
- package/build/plugins/session.d.ts +4 -0
- package/build/plugins/session.d.ts.map +1 -0
- package/build/plugins/session.js +58 -0
- package/build/plugins/session.js.map +1 -0
- package/build/plugins/status.d.ts +8 -0
- package/build/plugins/status.d.ts.map +1 -0
- package/build/plugins/status.js +21 -0
- package/build/plugins/status.js.map +1 -0
- package/build/plugins/stripe/types.d.ts +20 -0
- package/build/plugins/stripe/types.d.ts.map +1 -0
- package/build/plugins/stripe/types.js +2 -0
- package/build/plugins/stripe/types.js.map +1 -0
- package/build/plugins/stripe.d.ts +4 -52
- package/build/plugins/stripe.d.ts.map +1 -1
- package/build/plugins/stripe.js +385 -495
- package/build/plugins/stripe.js.map +1 -1
- package/build/plugins/subscriptions/types.d.ts +41 -0
- package/build/plugins/subscriptions/types.d.ts.map +1 -0
- package/build/plugins/subscriptions/types.js +2 -0
- package/build/plugins/subscriptions/types.js.map +1 -0
- package/build/plugins/subscriptions.d.ts +6 -0
- package/build/plugins/subscriptions.d.ts.map +1 -0
- package/build/plugins/subscriptions.js +169 -0
- package/build/plugins/subscriptions.js.map +1 -0
- package/build/plugins/types.d.ts +1 -76
- package/build/plugins/types.d.ts.map +1 -1
- package/build/plugins/types.local.d.ts +0 -1
- package/build/plugins/types.local.d.ts.map +1 -1
- package/build/plugins/webhook-manager/types.d.ts +62 -0
- package/build/plugins/webhook-manager/types.d.ts.map +1 -0
- package/build/plugins/webhook-manager/types.js +2 -0
- package/build/plugins/webhook-manager/types.js.map +1 -0
- package/build/plugins/webhook-manager.d.ts +5 -51
- package/build/plugins/webhook-manager.d.ts.map +1 -1
- package/build/plugins/webhook-manager.js +203 -200
- package/build/plugins/webhook-manager.js.map +1 -1
- package/build/protocol.d.ts +13 -0
- package/build/protocol.d.ts.map +1 -0
- package/build/protocol.js +17 -0
- package/build/protocol.js.map +1 -0
- package/build/reconcile/types.d.ts +17 -0
- package/build/reconcile/types.d.ts.map +1 -0
- package/build/reconcile/types.js +2 -0
- package/build/reconcile/types.js.map +1 -0
- package/build/reconcile.d.ts +6 -9
- package/build/reconcile.d.ts.map +1 -1
- package/build/reconcile.js +78 -76
- package/build/reconcile.js.map +1 -1
- package/build/resource.d.ts.map +1 -1
- package/build/resource.js +2 -3
- package/build/resource.js.map +1 -1
- package/build/schemas.d.ts +5 -1
- package/build/schemas.d.ts.map +1 -1
- package/build/schemas.js +16 -0
- package/build/schemas.js.map +1 -1
- package/build/service.d.ts +3 -17
- package/build/service.d.ts.map +1 -1
- package/build/service.js +32 -85
- package/build/service.js.map +1 -1
- package/build/subscription/types.d.ts +21 -0
- package/build/subscription/types.d.ts.map +1 -0
- package/build/subscription/types.js +2 -0
- package/build/subscription/types.js.map +1 -0
- package/build/subscription.d.ts +3 -26
- package/build/subscription.d.ts.map +1 -1
- package/build/subscription.js +75 -170
- package/build/subscription.js.map +1 -1
- package/build/sync/types.d.ts +25 -0
- package/build/sync/types.d.ts.map +1 -0
- package/build/sync/types.js +2 -0
- package/build/sync/types.js.map +1 -0
- package/build/sync.d.ts +4 -30
- package/build/sync.d.ts.map +1 -1
- package/build/sync.js +170 -194
- package/build/sync.js.map +1 -1
- package/build/types.d.ts +15 -15
- package/build/types.d.ts.map +1 -1
- package/build/types.local.d.ts +4 -9
- package/build/types.local.d.ts.map +1 -1
- package/build/usage/types.d.ts +56 -0
- package/build/usage/types.d.ts.map +1 -0
- package/build/usage/types.js +2 -0
- package/build/usage/types.js.map +1 -0
- package/build/usage.d.ts +4 -50
- package/build/usage.d.ts.map +1 -1
- package/build/usage.js +291 -307
- package/build/usage.js.map +1 -1
- package/build/utils/types.d.ts +31 -0
- package/build/utils/types.d.ts.map +1 -0
- package/build/utils/types.js +2 -0
- package/build/utils/types.js.map +1 -0
- package/build/utils.d.ts +15 -69
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +54 -113
- package/build/utils.js.map +1 -1
- package/package.json +18 -18
- package/src/access/types.ts +52 -0
- package/src/access.ts +86 -0
- package/src/actions/resync-subscriptions.ts +3 -2
- package/src/actions/resync.ts +7 -5
- package/src/actions/webhook.ts +5 -4
- package/src/bootstrap/types.ts +16 -0
- package/src/bootstrap.ts +31 -0
- package/src/catalogue/types.ts +32 -0
- package/src/catalogue.ts +135 -0
- package/src/commit/types.ts +27 -0
- package/src/commit.ts +152 -0
- package/src/config.ts +10 -49
- package/src/consumer/cancellation/types.ts +13 -0
- package/src/consumer/cancellation.ts +43 -0
- package/src/consumer/capture/types.ts +53 -0
- package/src/consumer/capture.ts +289 -303
- package/src/consumer/format/types.ts +29 -0
- package/src/consumer/format.ts +64 -69
- package/src/consumer/handlers.ts +11 -7
- package/src/consumer/index.ts +7 -4
- package/src/consumer/mail/types.ts +31 -0
- package/src/consumer/mail.ts +233 -234
- package/src/consumer/observers/types.ts +22 -0
- package/src/consumer/observers.ts +97 -0
- package/src/consumer/origin/types.ts +17 -0
- package/src/consumer/origin.ts +48 -48
- package/src/consumer/reconcile/types.ts +13 -0
- package/src/consumer/reconcile.ts +274 -270
- package/src/consumer/records/types.ts +64 -0
- package/src/consumer/records.ts +248 -317
- package/src/consumer/service.ts +219 -306
- package/src/consumer/types.local.ts +2 -2
- package/src/consumer/types.ts +8 -10
- package/src/consumer/withdrawal/types.ts +37 -0
- package/src/consumer/withdrawal.ts +221 -226
- package/src/entitlement.ts +43 -42
- package/src/entrypoints.ts +1 -1
- package/src/gate/request.ts +24 -0
- package/src/gate/types.ts +13 -0
- package/src/gate.ts +12 -41
- package/src/index.ts +52 -24
- package/src/limit.ts +6 -6
- package/src/models/declarations/types.ts +22 -0
- package/src/models/declarations.ts +30 -0
- package/src/models/purchase/types.ts +13 -0
- package/src/models/purchase.ts +43 -0
- package/src/plan/types.ts +21 -0
- package/src/plan.ts +36 -114
- package/src/plugins/checkout-plugins/types.ts +25 -0
- package/src/plugins/checkout-plugins.ts +73 -128
- package/src/plugins/checkout-policy/types.ts +18 -0
- package/src/plugins/checkout-policy.ts +34 -0
- package/src/plugins/checkout-registry/types.ts +7 -0
- package/src/plugins/checkout-registry.ts +23 -0
- package/src/plugins/customer-lock/types.ts +5 -0
- package/src/plugins/customer-lock.ts +25 -0
- package/src/plugins/estimate/cache.ts +12 -0
- package/src/plugins/estimate/types.ts +28 -0
- package/src/plugins/estimate.ts +179 -200
- package/src/plugins/events/types.ts +11 -0
- package/src/plugins/events.ts +107 -326
- package/src/plugins/fx/types.ts +38 -0
- package/src/plugins/fx.ts +75 -76
- package/src/plugins/portal/types.ts +45 -0
- package/src/plugins/portal.ts +227 -256
- package/src/plugins/refunds/types.ts +31 -0
- package/src/plugins/refunds.ts +74 -72
- package/src/plugins/session/types.ts +28 -0
- package/src/plugins/session.ts +73 -0
- package/src/plugins/status.ts +22 -0
- package/src/plugins/stripe/types.ts +20 -0
- package/src/plugins/stripe.ts +402 -529
- package/src/plugins/subscriptions/types.ts +39 -0
- package/src/plugins/subscriptions.ts +195 -0
- package/src/plugins/types.local.ts +0 -1
- package/src/plugins/types.ts +1 -81
- package/src/plugins/webhook-manager/types.ts +63 -0
- package/src/plugins/webhook-manager.ts +215 -205
- package/src/protocol.ts +29 -0
- package/src/reconcile/types.ts +17 -0
- package/src/reconcile.ts +86 -78
- package/src/resource.ts +28 -19
- package/src/schemas.ts +25 -1
- package/src/service.ts +39 -94
- package/src/subscription/types.ts +23 -0
- package/src/subscription.ts +88 -192
- package/src/sync/types.ts +25 -0
- package/src/sync.ts +177 -204
- package/src/types.local.ts +2 -4
- package/src/types.ts +10 -12
- package/src/usage/types.ts +51 -0
- package/src/usage.ts +323 -342
- package/src/utils/types.ts +30 -0
- package/src/utils.ts +85 -181
- package/tests/checkout-consumer.spec.ts +27 -28
- package/tests/checkout-locks.spec.ts +18 -17
- package/tests/checkout-plugins.spec.ts +27 -27
- package/tests/checkout.spec.ts +15 -12
- package/tests/consumer-events.spec.ts +22 -24
- package/tests/consumer-fixtures.ts +6 -4
- package/tests/consumer-ops.spec.ts +38 -39
- package/tests/consumer-rights.integration.spec.ts +41 -43
- package/tests/consumer-rights.spec.ts +31 -36
- package/tests/context.ts +2 -2
- package/tests/entitlement.spec.ts +21 -21
- package/tests/estimate.spec.ts +27 -26
- package/tests/events.spec.ts +31 -30
- package/tests/fake-stripe.ts +19 -13
- package/tests/gate-handlers.spec.ts +2 -2
- package/tests/gate.spec.ts +5 -4
- package/tests/gateway-options.spec.ts +27 -28
- package/tests/limit-gate.spec.ts +13 -15
- package/tests/portal.spec.ts +31 -29
- package/tests/sync.spec.ts +12 -12
- package/tests/usage.integration.spec.ts +23 -25
- package/tests/usage.spec.ts +20 -22
- package/tests/webhook-manager.spec.ts +23 -26
package/README.md
CHANGED
|
@@ -40,17 +40,16 @@ declarePaymentPlan(cfg, {
|
|
|
40
40
|
})
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
`declarePaymentPlan` validates each declaration before recording it;
|
|
44
|
-
the catalogue as a whole (one free plan per
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
`declarePaymentPlan` validates each declaration before recording it;
|
|
44
|
+
`makePlanDeclarationsModel(cfg).assertPlans()` checks the catalogue as a whole (one free plan per
|
|
45
|
+
rank, no two paid plans of a product at one rank) and runs when the gateway initializes. A limit key
|
|
46
|
+
may use a different kind on different plans — each kind keeps its own counter window, so a lifetime
|
|
47
|
+
count still sticks to the entity when it moves to a monthly plan.
|
|
47
48
|
|
|
48
49
|
## Wire the services
|
|
49
50
|
|
|
50
51
|
```typescript
|
|
51
|
-
import {
|
|
52
|
-
appendPaymentGatewayService, entitlements, gateway, observer, paymentGateEntrypoints,
|
|
53
|
-
} from '@owlmeans/server-payment'
|
|
52
|
+
import { appendPaymentGatewayService, paymentAccessOf, paymentGateEntrypoints } from '@owlmeans/server-payment'
|
|
54
53
|
|
|
55
54
|
appendPaymentGatewayService(context) // the process that owns Stripe
|
|
56
55
|
appendPaymentGatewayService(context, { manage: false }) // a process that only reads entitlements
|
|
@@ -59,11 +58,12 @@ appendPaymentGatewayService(context, { owner: 'app-api', webhookService: 'app-ho
|
|
|
59
58
|
appendPaymentGatewayService(context, { owner: 'app-api', webhookService: 'app-hooks', bootstrap: false }) // checkout and portal
|
|
60
59
|
export const serverBindings = [...paymentGateEntrypoints]
|
|
61
60
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
const paid = paymentAccessOf(context).observer()
|
|
62
|
+
paid.onTopUp(async completion => { /* credit, idempotent by completion.externalId */ })
|
|
63
|
+
paid.onSubscription(async event => { /* idempotent by event.eventKey */ })
|
|
64
|
+
paid.onRefund(async event => { /* claw back, idempotent by event.eventKey */ })
|
|
65
|
+
paid.onDispute(async event => { /* … */ })
|
|
66
|
+
paid.onPaymentFailed(async event => { /* notify */ })
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
A managed gateway brings Stripe to the declared state at boot — products and prices, one
|
|
@@ -77,7 +77,7 @@ Three gateway options place that state when a deployment runs several processes:
|
|
|
77
77
|
|---|---|---|
|
|
78
78
|
| `webhookService` | `cfg.service` | the `cfg.services` alias whose host and base form the webhook URL — also the portal's deployment key |
|
|
79
79
|
| `owner` | `cfg.service` | the key of the `payment-webhook` rows, the signing-secret lookup, the `portal:<owner>` fingerprint and the Stripe labels |
|
|
80
|
-
| `bootstrap` | `manage` | whether this process runs the bootstrap at boot; a forced one (`resync`, `bootstrapStripe(
|
|
80
|
+
| `bootstrap` | `manage` | whether this process runs the bootstrap at boot; a forced one (`resync`, `stripeBootstrapOf(ctx).bootstrapStripe(stripe, { force: true })`) runs in any managed process |
|
|
81
81
|
|
|
82
82
|
Give every process of the database the same `owner` and `webhookService` (the process that receives
|
|
83
83
|
the webhook), and keep `bootstrap` on that receiver only. Changing `webhookService` moves the
|
|
@@ -103,29 +103,40 @@ even an undeliverable local one.
|
|
|
103
103
|
## Use it
|
|
104
104
|
|
|
105
105
|
```typescript
|
|
106
|
+
const payments = paymentAccessOf(ctx) // the services, resources and settings of one context
|
|
107
|
+
|
|
106
108
|
// Checkout and the portal (in-process; resolve the stable entityId at your authenticated boundary)
|
|
107
|
-
const url = await gateway(
|
|
108
|
-
const portal = await gateway(
|
|
109
|
-
await gateway(
|
|
109
|
+
const url = await payments.gateway().createLink(ctx, { productSku: 'app-plans', planSku: 'pro-monthly', entityId, service: 'app', successUrl })
|
|
110
|
+
const portal = await payments.gateway().portalLink(ctx, entityId, { flow: PortalFlow.Change, planSku: 'pro-monthly', returnUrl })
|
|
111
|
+
await payments.gateway().grantInternalPlan(ctx, entityId, 'free') // when the organization is created
|
|
110
112
|
|
|
111
113
|
// What the entity may do
|
|
112
|
-
const view = await entitlements(
|
|
113
|
-
await entitlements(
|
|
114
|
+
const view = await payments.entitlements().entitlements(entityId) // the EntitlementView a UI renders
|
|
115
|
+
await payments.entitlements().hasCapability(entityId, 'feature:whitelabel')
|
|
114
116
|
|
|
115
117
|
// Spend a counted allowance — key it by the record it pays for
|
|
116
|
-
await entitlements(
|
|
117
|
-
await entitlements(
|
|
118
|
+
await payments.entitlements().consume({ entityId, limitKey: 'exports', eventKey: `export:${reportId}`, ref: reportId })
|
|
119
|
+
await payments.entitlements().release({ entityId, limitKey: 'exports', eventKey: `export:${reportId}` })
|
|
118
120
|
|
|
119
121
|
// Periodic repair
|
|
120
|
-
await reconcileAll(
|
|
121
|
-
await entitlements(
|
|
122
|
+
await reconcileOf(ctx).reconcileAll({ freePlanSku: 'free' })
|
|
123
|
+
await payments.entitlements().reconcileOccupancy(entityId, 'seats', liveSeatCount)
|
|
122
124
|
```
|
|
123
125
|
|
|
126
|
+
The package's functionality comes as objects: pure helpers with a ready instance (`planHelper`,
|
|
127
|
+
`subscriptionHelper`, `checkoutPolicyHelper`, `stripeSessionHelper`, `consumerFormatHelper`,
|
|
128
|
+
`originHelper`) and helpers bound to one context, reached through their accessor — `paymentAccessOf(ctx)`,
|
|
129
|
+
`catalogueOf(ctx)`, `usageOf(ctx)`, `subscriptionCommitOf(ctx)`, `productSyncOf(ctx)`,
|
|
130
|
+
`stripeBootstrapOf(ctx)`, `reconcileOf(ctx)`, `checkoutPluginsOf(ctx)`, `stripeCheckoutOf(ctx)`,
|
|
131
|
+
`stripeSubscriptionsOf(ctx)`, `portalOf(ctx)`, `webhookOf(ctx)`, `estimateOf(ctx)`, `consumerMailOf(ctx)`.
|
|
132
|
+
The former free functions (`gateway`, `reconcileAll`, `webhookUrlOf`, …) remain as
|
|
133
|
+
deprecated delegates.
|
|
134
|
+
|
|
124
135
|
Routes declare what they need; the gates refuse before the handler:
|
|
125
136
|
|
|
126
137
|
```typescript
|
|
127
138
|
protocol(route(...), contract(...), { gate: { alias: ENTITLEMENT_GATE, params: ['feature:whitelabel'] } })
|
|
128
|
-
protocol(route(...), contract(...), { gate: { alias: LIMIT_GATE, params: [formatLimitParam('seats')] } })
|
|
139
|
+
protocol(route(...), contract(...), { gate: { alias: LIMIT_GATE, params: [planLimitHelper.formatLimitParam('seats')] } })
|
|
129
140
|
```
|
|
130
141
|
|
|
131
142
|
`CapabilityRequired` and `LimitExhausted` extend `AuthForbidden`, so an HTTP boundary answers 403.
|
|
@@ -167,7 +178,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
167
178
|
your project's skill store (`.agents/skills/`):
|
|
168
179
|
|
|
169
180
|
```sh
|
|
170
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
181
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.51
|
|
171
182
|
```
|
|
172
183
|
|
|
173
184
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/server-payment",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-10-
|
|
4
|
+
"version": "0.1.18-rc.32",
|
|
5
|
+
"generatedAt": "2026-10-06T11:45:57.672Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -7,7 +7,7 @@ user-invocable: false
|
|
|
7
7
|
|
|
8
8
|
# @owlmeans/server-payment
|
|
9
9
|
|
|
10
|
-
**Install:** `bun add @owlmeans/server-payment@^0.1.18-rc.
|
|
10
|
+
**Install:** `bun add @owlmeans/server-payment@^0.1.18-rc.32`
|
|
11
11
|
|
|
12
12
|
Public MIT package. It embeds Stripe into an application backend and owns everything between
|
|
13
13
|
Stripe and an entity's entitlements: the subscription store, one-time fulfillments, the usage
|
|
@@ -53,8 +53,8 @@ appendPaymentGatewayService(context, { manage: false }) // a worker that only r
|
|
|
53
53
|
appendPaymentGatewayService(context, { owner: 'app-api', webhookService: 'app-hooks' }) // receives the webhook, bootstraps at boot
|
|
54
54
|
appendPaymentGatewayService(context, { owner: 'app-api', webhookService: 'app-hooks', bootstrap: false }) // checkout and portal only
|
|
55
55
|
appendConsumerRights(context, { manage, usage: myUsageMeter }) // before or after the gateway; idempotent
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
paymentAccessOf(context).consumerRights().useMailRenderer(myRenderer) // lazy service: works while wiring
|
|
57
|
+
paymentAccessOf(context).gateway().use(myCheckoutPlugin) // a tier / cap / hold plugin — once the context is initialized
|
|
58
58
|
export const serverBindings = [
|
|
59
59
|
...paymentGateEntrypoints, // the library's own, unpinned `paymentGate`
|
|
60
60
|
...consumerRightsEntrypoints(consumerProtocols, { guardMoney, throttle, subjectOf, planNameOf }),
|
|
@@ -67,7 +67,7 @@ export const hookBindings = [
|
|
|
67
67
|
bind(own.resync, paymentGateHandlers.resync),
|
|
68
68
|
bind(own.resyncSubscriptions, paymentGateHandlers.resyncSubscriptions),
|
|
69
69
|
]
|
|
70
|
-
|
|
70
|
+
paymentAccessOf(context).observer().onSubscription(async event => { /* keyed by event.eventKey */ })
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
- `appendPaymentGatewayService` registers twelve resources, the catalogue service
|
|
@@ -79,9 +79,9 @@ observer(context).onSubscription(async event => { /* keyed by event.eventKey */
|
|
|
79
79
|
`usage` and `stripe` are installed on the one service, and `manage` resolves as the application's
|
|
80
80
|
explicit value, else the gateway's, else managed. The consumer-rights resources keep the aliases
|
|
81
81
|
of the first registration.
|
|
82
|
-
- **The consumer-rights service is lazy** (like the completion observer): `
|
|
82
|
+
- **The consumer-rights service is lazy** (like the completion observer): `paymentAccessOf(ctx).consumerRights()`,
|
|
83
83
|
`useMeter` and `useMailRenderer` work while the application is wired; the gateway's initialization
|
|
84
|
-
initializes it, so its boot checks still run at boot. The gateway is NOT lazy: `
|
|
84
|
+
initializes it, so its boot checks still run at boot. The gateway is NOT lazy: `paymentAccessOf(ctx).gateway()` (and
|
|
85
85
|
`.use(plugin)`) needs the initialized context.
|
|
86
86
|
- **`manage: false`** registers the same surface with no Stripe client: no bootstrap at init, and
|
|
87
87
|
`createLink`, `portalLink`, `resyncSubscription`, `resyncAll`, the webhook route, `withdraw` and
|
|
@@ -89,24 +89,24 @@ observer(context).onSubscription(async event => { /* keyed by event.eventKey */
|
|
|
89
89
|
`amountPolicy`, `planPrices` and the consumer-rights reads, `recordConsent`,
|
|
90
90
|
`recordStartRequest` and `assertConsent` work, because they are Mongo only.
|
|
91
91
|
- **Three keys of a deployment's Stripe state**, each a `PaymentGatewayOptions` field, each read
|
|
92
|
-
back on the gateway (`
|
|
92
|
+
back on the gateway (`paymentAccessOf(ctx).gateway().webhookService / owner / bootstrap`):
|
|
93
93
|
- `webhookService` (default `cfg.service`) — the `cfg.services` alias whose host and base form
|
|
94
|
-
`webhookUrlOf`, the portal's deployment key too. Name the process that RECEIVES the webhook
|
|
94
|
+
`webhookOf(ctx).webhookUrlOf`, the portal's deployment key too. Name the process that RECEIVES the webhook
|
|
95
95
|
(the one serving `paymentGate`) in every process, so every bootstrap computes one URL.
|
|
96
96
|
- `owner` (default `cfg.service`) — the `payment-webhook` rows' `service`, the signing-secret
|
|
97
97
|
lookup, the endpoint's `owlmeans:<owner>` description and `service` metadata, the
|
|
98
98
|
`portal:<owner>` fingerprint and the portal's `service` metadata. One value in every process of
|
|
99
99
|
the database, so each finds and replaces the others' rows.
|
|
100
|
-
- `bootstrap` (default: `manage`) — run `bootstrapStripe` at boot. Exactly one kind of process
|
|
100
|
+
- `bootstrap` (default: `manage`) — run `stripeBootstrapOf(ctx).bootstrapStripe` at boot. Exactly one kind of process
|
|
101
101
|
keeps it (the receiver). A managed process with `bootstrap: false` still serves checkout, the
|
|
102
102
|
portal, estimates, the resyncs and the webhook route, and a FORCED bootstrap (`resync`, an
|
|
103
|
-
application's maintenance `bootstrapStripe(
|
|
103
|
+
application's maintenance `stripeBootstrapOf(ctx).bootstrapStripe(stripe, { force: true })`) still runs there —
|
|
104
104
|
same URL, same rows, fingerprinted, so idempotent from any process.
|
|
105
105
|
- Refused at construction: `bootstrap: true` with `manage: false`, an empty `owner` or
|
|
106
106
|
`webhookService` (`PaygateError`). A managed, bootstrapping gateway fails its initialization when
|
|
107
107
|
`webhookService` is not declared in `cfg.services` (`WebhookSetupError('service:<alias>')`).
|
|
108
|
-
- `stripe` (a `StripeFactory`, default `stripeClient`) is the gateway's own Stripe client —
|
|
109
|
-
`
|
|
108
|
+
- `stripe` (a `StripeFactory`, default `paymentAccessOf(ctx).stripeClient`) is the gateway's own Stripe client —
|
|
109
|
+
`paymentAccessOf(ctx).gateway().stripe(ctx)`, used by its methods, its boot bootstrap and the `paymentGate` handlers.
|
|
110
110
|
The consumer-rights service takes its own (`appendConsumerRights({ stripe })`).
|
|
111
111
|
- Every process that registers the gateway runs the collection validators (`collMod`) of all
|
|
112
112
|
twelve records at init: a process of an older version narrows the validators again, so roll
|
|
@@ -130,12 +130,12 @@ observer(context).onSubscription(async event => { /* keyed by event.eventKey */
|
|
|
130
130
|
(CJEU C-641/19): `{ key, basis: 'time' | 'units', shareMinor }`, the shares summing to
|
|
131
131
|
`round(price × 100)`. Absent: the whole price is one `time` component. They also pick the start
|
|
132
132
|
statement: a `units` part → the `_units` variant, otherwise the base (time-only) texts
|
|
133
|
-
(`startContextOf`, `@owlmeans/payment`).
|
|
133
|
+
(`consumerCopyHelper.startContextOf`, `@owlmeans/payment`).
|
|
134
134
|
- `declarePaymentPlan` refuses before recording: a bad rank or a priced/gatewayed free plan
|
|
135
135
|
(`PlanRankConflict`), a capability set under the reserved `limit` scope, a malformed limit
|
|
136
136
|
(`LimitMisdeclared('<key>:<reason>')`), a malformed or amount-mode `currencyPrices` or components
|
|
137
137
|
that do not add up (`ProductError('currency-prices:…' | 'withdrawal:<sku>:…')`).
|
|
138
|
-
- `
|
|
138
|
+
- `makePlanDeclarationsModel(cfg).assertPlans()` runs when the gateway initializes and fails the boot on two free plans
|
|
139
139
|
at one rank, or two paid non-consumable plans of one product at one rank.
|
|
140
140
|
- A limit key may use a different kind on different plans; each kind counts separately and a
|
|
141
141
|
lifetime count stays with the entity through upgrades, downgrades and cancellations.
|
|
@@ -167,7 +167,7 @@ None declares an ObjectId reference: `entityId` is an organization key and every
|
|
|
167
167
|
- A compound sparse index still indexes a row that lacks only some of its keys — a unique index
|
|
168
168
|
that must skip absent values is single-field (`{sessionId}`).
|
|
169
169
|
- Conditional writes (`consentedAt`, `withdrawnAt`) are raw `$set`s guarded by the old value
|
|
170
|
-
(`conditionalSet`), so a concurrent declaration of the same purchase loses; declarations,
|
|
170
|
+
(`paymentUtils.conditionalSet`), so a concurrent declaration of the same purchase loses; declarations,
|
|
171
171
|
consents and events are only ever created.
|
|
172
172
|
|
|
173
173
|
## Checkout
|
|
@@ -198,7 +198,7 @@ None declares an ObjectId reference: `entityId` is an organization key and every
|
|
|
198
198
|
(an operator relocks). An organization that already paid before its country was locked is
|
|
199
199
|
locked lazily from its Stripe customer's address (`source: 'customer'`). Before any lock, the
|
|
200
200
|
declared country is prefilled on a customer without an address.
|
|
201
|
-
- **The currency.** Charge currency = the profile's currency, else `chargeCurrencyOf(region)`
|
|
201
|
+
- **The currency.** Charge currency = the profile's currency, else `consumerRegionHelper.chargeCurrencyOf(region)`
|
|
202
202
|
(`policy.currencies`). An amount checkout whose policy currency IS the charge currency is
|
|
203
203
|
charged exactly — no FX call; any other goes through the FX reference rate (rounded up). A
|
|
204
204
|
subscription or quantity session is forced to the charge currency (`currency`) only when its
|
|
@@ -209,7 +209,7 @@ None declares an ObjectId reference: `entityId` is an organization key and every
|
|
|
209
209
|
- **The lock at Stripe.** A locked profile whose customer carries the address:
|
|
210
210
|
`customer_update.address: 'never'` and `billing_address_collection: 'auto'` (tax follows the
|
|
211
211
|
saved address, Checkout cannot move it); `name: 'auto'` stays. A locked customer without a
|
|
212
|
-
tax-locatable address (`isTaxLocatable`) keeps `'auto'`/`'required'`, or Stripe refuses the
|
|
212
|
+
tax-locatable address (`stripeSessionHelper.isTaxLocatable`) keeps `'auto'`/`'required'`, or Stripe refuses the
|
|
213
213
|
session ("Automatic tax calculation in Checkout requires a valid address on the Customer").
|
|
214
214
|
- **Terms.** `mechanisms.checkoutTerms` puts `consent_collection.terms_of_service: 'required'` and
|
|
215
215
|
`custom_text.terms_of_service_acceptance` (the `checkout.terms-acceptance.in-scope | other` copy
|
|
@@ -217,7 +217,7 @@ None declares an ObjectId reference: `entityId` is an organization key and every
|
|
|
217
217
|
- **A missing Dashboard terms URL never breaks a payment.** Stripe refuses the checkbox then
|
|
218
218
|
(`invalid_request_error`, param `consent_collection[terms_of_service]`, "You cannot collect consent
|
|
219
219
|
to your terms of service unless a URL is set in the Stripe Dashboard", matched by
|
|
220
|
-
`isMissingTermsUrl`): the session is created ONCE more without `consent_collection` and without the
|
|
220
|
+
`stripeSessionHelper.isMissingTermsUrl`): the session is created ONCE more without `consent_collection` and without the
|
|
221
221
|
terms text, under the same plugin admissions, metadata `termsCollected: 'false'`; a
|
|
222
222
|
`checkout-terms-fallback` event (`recordKind: 'checkout'`, `recordId` = the entity, `externalId`
|
|
223
223
|
= the session, `ok: false`, the Stripe message in `detail`) is appended per fallback and one
|
|
@@ -259,7 +259,7 @@ or without a consumer-rights policy.
|
|
|
259
259
|
region" picker (a payment-method detail no parameter hides), which then moves neither tax nor the
|
|
260
260
|
saved address. Metadata `countryPinned: 'true'` makes the first completed purchase lock THAT
|
|
261
261
|
country (`lockFromSession`: `metadata.country` before `customer_details.address.country`).
|
|
262
|
-
- **Tax-locatable** (`isTaxLocatable`, from Stripe's customer-locations table): a country alone
|
|
262
|
+
- **Tax-locatable** (`stripeSessionHelper.isTaxLocatable`, from Stripe's customer-locations table): a country alone
|
|
263
263
|
everywhere except US (needs `postal_code`) and CA / IN (`postal_code` or `state`). A pinned US,
|
|
264
264
|
CA or IN customer without one is not kept: Checkout collects the address — country editable —
|
|
265
265
|
and the purchase locks what was typed, as without the option.
|
|
@@ -268,7 +268,7 @@ or without a consumer-rights policy.
|
|
|
268
268
|
|
|
269
269
|
## Checkout plugins
|
|
270
270
|
|
|
271
|
-
`
|
|
271
|
+
`paymentAccessOf(ctx).gateway().use(plugin)` seats a `CheckoutPlugin` per gateway instance (the `ExecutionService.use`
|
|
272
272
|
registry: a plugin whose `alias` is registered already replaces it). All hooks are optional:
|
|
273
273
|
|
|
274
274
|
| Hook | Called | Contract |
|
|
@@ -280,7 +280,7 @@ registry: a plugin whose `alias` is registered already replaces it). All hooks a
|
|
|
280
280
|
| `sessionTtlSeconds` | — | the smallest declared, clamped to 30 min – 24 h, becomes `expires_at`; none declared: Stripe's default |
|
|
281
281
|
|
|
282
282
|
- **One narrowing path.** `createLink` and `gateway.amountPolicy(ctx, entityId, productSku,
|
|
283
|
-
planSku?)` both call `narrowAmountFor` → `narrowAmountPolicy` (`@owlmeans/payment`); an amount
|
|
283
|
+
planSku?)` both call `checkoutPluginsOf(ctx).narrowAmountFor` → `amountNarrowingHelper.narrowAmountPolicy` (`@owlmeans/payment`); an amount
|
|
284
284
|
above the narrowed maximum, or any amount while `blocked`, is `CheckoutLimitExceeded` (409). A
|
|
285
285
|
control and a refusal cannot disagree. An amount above the plan's own maximum stays the base
|
|
286
286
|
policy's error.
|
|
@@ -291,7 +291,7 @@ registry: a plugin whose `alias` is registered already replaces it). All hooks a
|
|
|
291
291
|
|
|
292
292
|
## Price sync and the tax estimate
|
|
293
293
|
|
|
294
|
-
- `syncStripeProducts` gives a matching, still-`unspecified` price the declared `tax.behavior` IN
|
|
294
|
+
- `productSyncOf(ctx).syncStripeProducts` gives a matching, still-`unspecified` price the declared `tax.behavior` IN
|
|
295
295
|
PLACE and a fresh one on creation; a price carrying the OPPOSITE behavior is replaced. Before an
|
|
296
296
|
in-place update it checks the account's tax-settings default and skips — logging why — when that
|
|
297
297
|
would change existing renewals, unless `stripe.migrateUnspecifiedPrices` opts in.
|
|
@@ -324,7 +324,7 @@ registry: a plugin whose `alias` is registered already replaces it). All hooks a
|
|
|
324
324
|
- **The effective plan** is the highest-ranked row in `ENTITLING_STATUSES` (catalogue rank; the
|
|
325
325
|
newest on a tie), else the declared free plan, else `PlanRequired`.
|
|
326
326
|
- **A subscription row may override its plan.** `PaymentSubscriptionRecord.overrides`
|
|
327
|
-
(`SubscriptionOverrides`: `limits: { <key>: { limit } }`) is applied by `overriddenPlan(plan, row)`
|
|
327
|
+
(`SubscriptionOverrides`: `limits: { <key>: { limit } }`) is applied by `planHelper.overriddenPlan(plan, row)`
|
|
328
328
|
inside `resolveEffectivePlan` and `snapshotOf`, so ceilings, the entitlement view, both gates and
|
|
329
329
|
observers read one answer and nothing else needs to know. An override sets the ceiling of a key
|
|
330
330
|
the plan declares and drops that key's promo; kind and window stay the plan's (counters are keyed
|
|
@@ -332,7 +332,7 @@ registry: a plugin whose `alias` is registered already replaces it). All hooks a
|
|
|
332
332
|
writes it, no paygate does: every sync and re-grant spreads the previous row, so it survives. It
|
|
333
333
|
belongs to the row — it follows the subscription through a plan change, ends with it, and the
|
|
334
334
|
free-plan fallback (no row) has none. A new overridable parameter is a new optional key of
|
|
335
|
-
`SubscriptionOverrides`, declared in `PaymentSubscriptionSchema` and merged in `overriddenPlan`.
|
|
335
|
+
`SubscriptionOverrides`, declared in `PaymentSubscriptionSchema` and merged in `planHelper.overriddenPlan`.
|
|
336
336
|
- `mapStatus`: `active`→Active, `trialing`→Trial, `past_due`→PastDue, `unpaid`/`paused`→Suspended,
|
|
337
337
|
`incomplete`→Created, `incomplete_expired`→Ended, `canceled`→Canceled; paused collection is
|
|
338
338
|
Suspended with `pausedAt`.
|
|
@@ -354,12 +354,12 @@ registry: a plugin whose `alias` is registered already replaces it). All hooks a
|
|
|
354
354
|
admission reads. `consume` increments the counter FIRST by one conditional upsert (`used <= limit
|
|
355
355
|
- amount`), then appends the event — **the counter may over-count, never over-admit**. An event
|
|
356
356
|
key is idempotent; `release` appends `release:<eventKey>` first. `reconcileCounters`,
|
|
357
|
-
`reconcileOccupancy`, `reconcileEntity` and
|
|
357
|
+
`reconcileOccupancy`, `reconcileOf(ctx).reconcileEntity` and `.reconcileAll` repair it (details: the `entitlements`
|
|
358
358
|
skill).
|
|
359
359
|
|
|
360
360
|
## Entitlements and gates
|
|
361
361
|
|
|
362
|
-
- `
|
|
362
|
+
- `paymentAccessOf(ctx).entitlements()` → `effectivePlan`, `entitlements` (the `EntitlementView`), `hasCapability`,
|
|
363
363
|
`limitState`, the ledger operations. Never calls Stripe.
|
|
364
364
|
- **Capability gate** (`ENTITLEMENT_GATE`) passes when the view grants ANY parameter; **limit gate**
|
|
365
365
|
(`LIMIT_GATE`) when any `limit:<key>[>=n]` has room — it never consumes. Both refuse with
|
|
@@ -370,7 +370,7 @@ skill).
|
|
|
370
370
|
|
|
371
371
|
The EU right of withdrawal (with the Art. 11a withdrawal function), spend consent for prepaid
|
|
372
372
|
credits, subscription start requests, the cancellation function and a billing country fixed at the
|
|
373
|
-
first purchase. The service is `
|
|
373
|
+
first purchase. The service is `paymentAccessOf(ctx).consumerRights()` (`.consumerRightsOf()` is null-safe); its
|
|
374
374
|
full contract is in `reference.md`.
|
|
375
375
|
|
|
376
376
|
- **A purchase** is a paid one-time checkout, or a subscription's FIRST invoice — renewals,
|
|
@@ -379,7 +379,7 @@ full contract is in `reference.md`.
|
|
|
379
379
|
collision) is written **before anything is granted**: in `checkout.session.completed` before
|
|
380
380
|
`onTopUp`, in the first subscription commit before the `created` observers. A completed
|
|
381
381
|
subscription checkout then refines it with the buyer's own country, e-mail, totals and terms
|
|
382
|
-
acceptance. Window = in scope, before `deadline` (`withdrawalDeadlineOf`, policy margin),
|
|
382
|
+
acceptance. Window = in scope, before `deadline` (`withdrawalDeadlineHelper.withdrawalDeadlineOf`, policy margin),
|
|
383
383
|
neither withdrawn nor refunded; a full refund closes it (`refundedAt`).
|
|
384
384
|
- **In scope** when the buyer's own country or the organization's locked country is in the policy's
|
|
385
385
|
territories; an unknown country is protected by default. A business tax id does not exempt.
|
|
@@ -399,16 +399,16 @@ full contract is in `reference.md`.
|
|
|
399
399
|
required while an open in-scope top-up window has none. `assertConsent` is one indexed query and
|
|
400
400
|
throws `PerformanceConsentRequired` (428, `pending`, latest `deadline`); an application calls it
|
|
401
401
|
only where credits will actually be spent. `consentView` carries the policy's `consentContext`
|
|
402
|
-
as `context`. `recordConsent` renders the statement itself (`consentStatementOf` with the
|
|
402
|
+
as `context`. `recordConsent` renders the statement itself (`consumerCopyHelper.consentStatementOf` with the
|
|
403
403
|
trader's `name` and the policy's `consentContext`, so the stored verbatim text and the consent
|
|
404
404
|
mail are the `_<context>` variant the dialog showed; without a context the base statement),
|
|
405
405
|
stores that `context` on the record, refuses a stale `textVersion` with a fresh 428, covers only
|
|
406
406
|
the open windows the body lists, stamps `consentedAt` conditionally, mails the confirmation, then
|
|
407
407
|
tells `onConsent`.
|
|
408
408
|
- **Start requests follow the plan's withdrawal arithmetic.** `startView(entityId, planSku)` names
|
|
409
|
-
`context = startContextOf(plan)` (`'units'` for a plan with a `units` component, absent for a
|
|
409
|
+
`context = consumerCopyHelper.startContextOf(plan)` (`'units'` for a plan with a `units` component, absent for a
|
|
410
410
|
time-only one); `recordStartRequest(subject, body, origin, { plan })` renders the statement with
|
|
411
|
-
the SAME `startContextOf(plan)` and the plan's short name the application passes (default: its
|
|
411
|
+
the SAME `consumerCopyHelper.startContextOf(plan)` and the plan's short name the application passes (default: its
|
|
412
412
|
localized title), stores it verbatim with its `context`, and the start mail repeats it with
|
|
413
413
|
`email.start.rule` of that variant (the record's `context`). Usable `startRequestTtlSeconds`
|
|
414
414
|
(3600); the purchase takes it as `servicesStartedAt`/`consentedAt`.
|
|
@@ -444,7 +444,7 @@ address and the model form), consent confirmation, start confirmation, withdrawa
|
|
|
444
444
|
cancellation receipt. User values are HTML-escaped; a deadline is shown as its last included day.
|
|
445
445
|
The mails and the withdrawal information name the trader's `legalName, address, email`; the
|
|
446
446
|
statements its `name`. Every send, skip or failure is a `mail` event (step = kind); addresses on
|
|
447
|
-
`.test`/`.example`/`.invalid`/`.localhost` and every subdomain of them (`isReservedAddress`; case, a
|
|
447
|
+
`.test`/`.example`/`.invalid`/`.localhost` and every subdomain of them (`consumerFormatHelper.isReservedAddress`; case, a
|
|
448
448
|
display-name form and a trailing dot read through) are never sent (recorded as skipped); each `bcc`
|
|
449
449
|
address gets its own copy. **The purchase confirmation goes out once per purchase**: a delivery
|
|
450
450
|
sends it only after winning the conditional `confirmationMailAt` claim on the purchase row (a mail
|
|
@@ -457,7 +457,7 @@ mailer is registered.
|
|
|
457
457
|
|
|
458
458
|
## Reconcile
|
|
459
459
|
|
|
460
|
-
`
|
|
460
|
+
`paymentAccessOf(ctx).consumerRights().reconcile({ since?, limit? })` — the application's nightly job: retries the
|
|
461
461
|
paygate steps of withdrawals (refund, credit note, subscription cancel) and scheduled
|
|
462
462
|
cancellations, failed mails and failed observers; backfills purchases (records only, no mail) from
|
|
463
463
|
completed sessions of the last 16 days without a row; locks organizations that paid before the
|
|
@@ -477,7 +477,7 @@ made (found by `metadata.withdrawalId`). Five failures of a step leave it to an
|
|
|
477
477
|
`@owlmeans/server-entrypoint` / `@owlmeans/server-app`, and never registers `paymentGate` or
|
|
478
478
|
`paymentGateEntrypoints`. A handler reads its context from the entrypoint it is bound to, so the
|
|
479
479
|
application's declaration is the one mounted and run. Its declarations keep the library's paths
|
|
480
|
-
(`webhookUrlOf` forms the Stripe URL from `paymentGate`'s), contracts (`PaygateParams`,
|
|
480
|
+
(`webhookOf(ctx).webhookUrlOf` forms the Stripe URL from `paymentGate`'s), contracts (`PaygateParams`,
|
|
481
481
|
`ResyncResult`, `ResyncSubscriptionsResult` — `bind` refuses another shape at compile time) and
|
|
482
482
|
guards. Two ways to get it wrong: `bindAll(declarations, [paymentGateHandlers.webhook])` pairs by
|
|
483
483
|
object identity and leaves the application's declaration without a handler, and
|
|
@@ -496,16 +496,16 @@ made (found by `metadata.withdrawalId`). Five failures of a step leave it to an
|
|
|
496
496
|
least `publicMinMs` (1000 ms) so a match is not visible in the timing either.
|
|
497
497
|
- `checkoutReadEntrypoints(protocols, { resolveEntity?, gatewayAlias? })` binds
|
|
498
498
|
`makeCheckoutReadProtocols`: `amountPolicy` and `planPrices`; its `resolveEntity(req, ctx)` too.
|
|
499
|
-
- **`requestOriginOf(req)`** is the evidence of every consumer act (the default `metaOf`): `ip` =
|
|
499
|
+
- **`originHelper.requestOriginOf(req)`** is the evidence of every consumer act (the default `metaOf`): `ip` =
|
|
500
500
|
`cf-connecting-ip` → the LAST `x-forwarded-for` entry → `x-real-ip` → the socket; the raw
|
|
501
501
|
`x-forwarded-for`, `user-agent` (≤ 512), `cf-ipcountry`, `accept-language`.
|
|
502
502
|
|
|
503
503
|
## Stripe self-management
|
|
504
504
|
|
|
505
505
|
Runs in `initialize()` of a managed gateway with `bootstrap` (default), after the context is
|
|
506
|
-
ready, and on a forced `bootstrapStripe` from any managed process; each step independent: products
|
|
506
|
+
ready, and on a forced `stripeBootstrapOf(ctx).bootstrapStripe` from any managed process; each step independent: products
|
|
507
507
|
and prices (above), the portal configuration, the webhook endpoint. A deployment's identity is its
|
|
508
|
-
webhook URL (`webhookUrlOf`: the `webhookService` alias's host and base); its rows carry the
|
|
508
|
+
webhook URL (`webhookOf(ctx).webhookUrlOf()`: the `webhookService` alias's host and base); its rows carry the
|
|
509
509
|
`owner`.
|
|
510
510
|
|
|
511
511
|
- **The portal configuration**: customer update (tax id; email unless `stripe.lockCustomerEmail`;
|
|
@@ -513,11 +513,11 @@ webhook URL (`webhookUrlOf`: the `webhookService` alias's host and base); its ro
|
|
|
513
513
|
payment method update, cancellation at period end without proration, price switching between the
|
|
514
514
|
active recurring prices. Its fingerprint covers the catalogue (incl. `currencyPrices`), the lock
|
|
515
515
|
flags, the region currencies, the branding and the deployment key. Each deployment owns its own configuration, tagged `{ owlmeans: 'payment',
|
|
516
|
-
service: <owner>, deployment:
|
|
516
|
+
service: <owner>, deployment: webhookOf(ctx).webhookUrlOf() }`; one tagged for another deployment (a former
|
|
517
517
|
webhook URL included) is never touched — a moved URL creates a new configuration.
|
|
518
518
|
- `portalLink(ctx, entityId, { flow, planSku?, returnUrl })`: a customer is required
|
|
519
519
|
(`PortalUnavailable`, 409); `Cancel`/`Update`/`Change` need an entitling Stripe subscription.
|
|
520
|
-
- **The webhook endpoint** at `
|
|
520
|
+
- **The webhook endpoint** at `webhookOf(ctx).webhookUrlOf()`, subscribed to `WEBHOOK_EVENTS`, on the API version
|
|
521
521
|
read back from the client; only an https public host. A deployment deletes only the endpoints its
|
|
522
522
|
own rows name. A new URL (a moved host, a new `webhookService`) creates the endpoint there, then
|
|
523
523
|
deletes the endpoints of the owner's rows at other URLs and those rows — no migration step. The
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type Stripe from 'stripe';
|
|
2
|
+
import type { PaymentService } from '@owlmeans/payment';
|
|
3
|
+
import type { BillingProfileResource, CompletionObserver, ConsumerConsentResource, ConsumerDeclarationResource, ConsumerEventResource, ConsumerMailPluginConfig, ConsumerRightsService, EntitlementService, FingerprintResource, GatewayService, PaygateCustomerResource, PaymentFulfillmentResource, PaymentSubscriptionRecord, PaymentSubscriptionResource, PaymentUsageCounterResource, PaymentUsageResource, PaymentWebhookResource, PortalBrandingConfig, PurchaseResource, StripePluginConfig, StripePricingPluginConfig } from '../types.js';
|
|
4
|
+
/** What one context holds for payments: its services, its resources, its plugin configs and its Stripe client. */
|
|
5
|
+
export interface PaymentAccess {
|
|
6
|
+
payment: () => PaymentService;
|
|
7
|
+
gateway: () => GatewayService;
|
|
8
|
+
/** The gateway, or `null` in a context that registered none. */
|
|
9
|
+
gatewayOf: () => GatewayService | null;
|
|
10
|
+
observer: () => CompletionObserver;
|
|
11
|
+
entitlements: () => EntitlementService;
|
|
12
|
+
paygateCustomers: () => PaygateCustomerResource;
|
|
13
|
+
subscriptions: () => PaymentSubscriptionResource;
|
|
14
|
+
fulfillments: () => PaymentFulfillmentResource;
|
|
15
|
+
paymentWebhooks: () => PaymentWebhookResource;
|
|
16
|
+
usageEvents: () => PaymentUsageResource;
|
|
17
|
+
usageCounters: () => PaymentUsageCounterResource;
|
|
18
|
+
fingerprints: () => FingerprintResource;
|
|
19
|
+
billingProfiles: () => BillingProfileResource;
|
|
20
|
+
purchases: () => PurchaseResource;
|
|
21
|
+
consumerConsents: () => ConsumerConsentResource;
|
|
22
|
+
consumerDeclarations: () => ConsumerDeclarationResource;
|
|
23
|
+
consumerEvents: () => ConsumerEventResource;
|
|
24
|
+
/** The consumer-rights service. @throws when it is not registered */
|
|
25
|
+
consumerRights: (alias?: string) => ConsumerRightsService;
|
|
26
|
+
/** The consumer-rights service, or `null` in a process that registered none. */
|
|
27
|
+
consumerRightsOf: (alias?: string) => ConsumerRightsService | null;
|
|
28
|
+
stripeConfig: () => Promise<StripePluginConfig>;
|
|
29
|
+
/** The portal branding declared with `portalBranding`, or `null`. */
|
|
30
|
+
portalBrandingConfig: () => Promise<PortalBrandingConfig | null>;
|
|
31
|
+
/** The consumer-rights mail options declared with `declareConsumerRights`, or `null`. */
|
|
32
|
+
consumerMailConfig: () => Promise<ConsumerMailPluginConfig | null>;
|
|
33
|
+
/** The Stripe-only pricing settings declared with `declarePaymentPricing`, or `null`. */
|
|
34
|
+
stripePricingConfig: () => Promise<StripePricingPluginConfig | null>;
|
|
35
|
+
/**
|
|
36
|
+
* A Stripe client pinned to {@link STRIPE_PINNED_API_VERSION}: the API version this package's payload
|
|
37
|
+
* readers, the stored webhook endpoints and the test doubles are written for. The installed SDK is typed
|
|
38
|
+
* for a newer one, so a read of a field the newer version moved (a subscription's period, an invoice's
|
|
39
|
+
* subscription) is cast at the seam until the readers are migrated — the pin is what keeps the shapes
|
|
40
|
+
* the code parses and the shapes Stripe sends the same.
|
|
41
|
+
*/
|
|
42
|
+
stripeClient: () => Promise<Stripe>;
|
|
43
|
+
/** The entity's highest-ranked entitling subscription of one product. */
|
|
44
|
+
activeSubscription: (entityId: string, productSku: string) => Promise<PaymentSubscriptionRecord | null>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EACV,sBAAsB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,2BAA2B,EAChG,qBAAqB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,mBAAmB,EAC/G,cAAc,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,yBAAyB,EAC9F,2BAA2B,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,sBAAsB,EACtG,oBAAoB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,yBAAyB,EACtF,MAAM,aAAa,CAAA;AAEpB,kHAAkH;AAClH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,cAAc,CAAA;IAC7B,OAAO,EAAE,MAAM,cAAc,CAAA;IAC7B,gEAAgE;IAChE,SAAS,EAAE,MAAM,cAAc,GAAG,IAAI,CAAA;IACtC,QAAQ,EAAE,MAAM,kBAAkB,CAAA;IAClC,YAAY,EAAE,MAAM,kBAAkB,CAAA;IACtC,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;IAC/C,aAAa,EAAE,MAAM,2BAA2B,CAAA;IAChD,YAAY,EAAE,MAAM,0BAA0B,CAAA;IAC9C,eAAe,EAAE,MAAM,sBAAsB,CAAA;IAC7C,WAAW,EAAE,MAAM,oBAAoB,CAAA;IACvC,aAAa,EAAE,MAAM,2BAA2B,CAAA;IAChD,YAAY,EAAE,MAAM,mBAAmB,CAAA;IACvC,eAAe,EAAE,MAAM,sBAAsB,CAAA;IAC7C,SAAS,EAAE,MAAM,gBAAgB,CAAA;IACjC,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;IAC/C,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;IACvD,cAAc,EAAE,MAAM,qBAAqB,CAAA;IAC3C,qEAAqE;IACrE,cAAc,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,qBAAqB,CAAA;IACzD,gFAAgF;IAChF,gBAAgB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,qBAAqB,GAAG,IAAI,CAAA;IAClE,YAAY,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC/C,qEAAqE;IACrE,oBAAoB,EAAE,MAAM,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAA;IAChE,yFAAyF;IACzF,kBAAkB,EAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAA;IAClE,yFAAyF;IACzF,mBAAmB,EAAE,MAAM,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAA;IACpE;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IACnC,yEAAyE;IACzE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAAA;CACxG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Context as ApiContext } from '@owlmeans/server-api';
|
|
2
|
+
import type { PaymentAccess } from './access/types.js';
|
|
3
|
+
export declare const makePaymentAccess: (ctx: ApiContext) => PaymentAccess;
|
|
4
|
+
/** The payment access of a context — one per context. */
|
|
5
|
+
export declare const paymentAccessOf: (target: ApiContext<import("@owlmeans/server-api").Config>) => PaymentAccess;
|
|
6
|
+
//# sourceMappingURL=access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAgBjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,eAAO,MAAM,iBAAiB,QAAS,UAAU,KAAG,aA4DnD,CAAA;AAED,yDAAyD;AACzD,eAAO,MAAM,eAAe,8EAAwC,CAAA"}
|
package/build/access.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Stripe from 'stripe';
|
|
2
|
+
import { PLUGINS } from '@owlmeans/config';
|
|
3
|
+
import { memoHelper } from '@owlmeans/context';
|
|
4
|
+
import { DEFAULT_ALIAS as PAYMENT_SERVICE, ENTITLING_STATUSES } from '@owlmeans/payment';
|
|
5
|
+
import { CONSUMER_RIGHTS_MAIL_PLUGIN_CONFIG, CONSUMER_RIGHTS_SERVICE, ENTITLEMENT_SERVICE, GATEWAY_SERVICE, PAYMENT_OBSERVER, RES_BILLING_PROFILE, RES_CONSUMER_CONSENT, RES_CONSUMER_DECLARATION, RES_CONSUMER_EVENT, RES_PAYGATE_CUSTOMER, RES_PAYMENT_FINGERPRINT, RES_PAYMENT_FULFILLMENT, RES_PAYMENT_PURCHASE, RES_PAYMENT_SUBSCRIPTION, RES_PAYMENT_USAGE, RES_PAYMENT_USAGE_COUNTER, RES_PAYMENT_WEBHOOK, STRIPE_PINNED_API_VERSION, STRIPE_PLUGIN_CONFIG, STRIPE_PORTAL_PLUGIN_CONFIG, STRIPE_PRICING_PLUGIN_CONFIG, } from './consts.js';
|
|
6
|
+
export const makePaymentAccess = (ctx) => {
|
|
7
|
+
const hasService = (alias) => ctx.hasService?.(alias) === true;
|
|
8
|
+
const plugins = () => ctx.getConfigResource(PLUGINS);
|
|
9
|
+
const payment = () => ctx.service(PAYMENT_SERVICE);
|
|
10
|
+
const gateway = () => ctx.service(GATEWAY_SERVICE);
|
|
11
|
+
const gatewayOf = () => hasService(GATEWAY_SERVICE) ? gateway() : null;
|
|
12
|
+
const observer = () => ctx.service(PAYMENT_OBSERVER);
|
|
13
|
+
const entitlements = () => ctx.service(ENTITLEMENT_SERVICE);
|
|
14
|
+
const paygateCustomers = () => ctx.resource(RES_PAYGATE_CUSTOMER);
|
|
15
|
+
const subscriptions = () => ctx.resource(RES_PAYMENT_SUBSCRIPTION);
|
|
16
|
+
const fulfillments = () => ctx.resource(RES_PAYMENT_FULFILLMENT);
|
|
17
|
+
const paymentWebhooks = () => ctx.resource(RES_PAYMENT_WEBHOOK);
|
|
18
|
+
const usageEvents = () => ctx.resource(RES_PAYMENT_USAGE);
|
|
19
|
+
const usageCounters = () => ctx.resource(RES_PAYMENT_USAGE_COUNTER);
|
|
20
|
+
const fingerprints = () => ctx.resource(RES_PAYMENT_FINGERPRINT);
|
|
21
|
+
const billingProfiles = () => ctx.resource(RES_BILLING_PROFILE);
|
|
22
|
+
const purchases = () => ctx.resource(RES_PAYMENT_PURCHASE);
|
|
23
|
+
const consumerConsents = () => ctx.resource(RES_CONSUMER_CONSENT);
|
|
24
|
+
const consumerDeclarations = () => ctx.resource(RES_CONSUMER_DECLARATION);
|
|
25
|
+
const consumerEvents = () => ctx.resource(RES_CONSUMER_EVENT);
|
|
26
|
+
const consumerRights = (alias = CONSUMER_RIGHTS_SERVICE) => ctx.service(alias);
|
|
27
|
+
const consumerRightsOf = (alias = CONSUMER_RIGHTS_SERVICE) => hasService(alias) ? ctx.service(alias) : null;
|
|
28
|
+
const stripeConfig = async () => await plugins().get(STRIPE_PLUGIN_CONFIG);
|
|
29
|
+
const portalBrandingConfig = async () => await plugins().load(STRIPE_PORTAL_PLUGIN_CONFIG);
|
|
30
|
+
const consumerMailConfig = async () => await plugins().load(CONSUMER_RIGHTS_MAIL_PLUGIN_CONFIG);
|
|
31
|
+
const stripePricingConfig = async () => await plugins().load(STRIPE_PRICING_PLUGIN_CONFIG);
|
|
32
|
+
const stripeClient = async () => new Stripe((await stripeConfig()).api, { apiVersion: STRIPE_PINNED_API_VERSION });
|
|
33
|
+
const activeSubscription = async (entityId, productSku) => await subscriptions().load({
|
|
34
|
+
entityId, productSku, status: [...ENTITLING_STATUSES],
|
|
35
|
+
}, { sort: [{ field: 'rank', order: 'desc' }, { field: 'createdAt', order: 'desc' }] });
|
|
36
|
+
return {
|
|
37
|
+
payment, gateway, gatewayOf, observer, entitlements, paygateCustomers, subscriptions, fulfillments,
|
|
38
|
+
paymentWebhooks, usageEvents, usageCounters, fingerprints, billingProfiles, purchases, consumerConsents,
|
|
39
|
+
consumerDeclarations, consumerEvents, consumerRights, consumerRightsOf, stripeConfig, portalBrandingConfig,
|
|
40
|
+
consumerMailConfig, stripePricingConfig, stripeClient, activeSubscription,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/** The payment access of a context — one per context. */
|
|
44
|
+
export const paymentAccessOf = memoHelper.oncePer(makePaymentAccess);
|
|
45
|
+
//# sourceMappingURL=access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resync-subscriptions.d.ts","sourceRoot":"","sources":["../../src/actions/resync-subscriptions.ts"],"names":[],"mappings":"
|
|
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,sKAC8B,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { handlers } from '@owlmeans/server-api';
|
|
2
|
-
import {
|
|
2
|
+
import { paymentAccessOf } from '../access.js';
|
|
3
|
+
import { paymentGate } from '../protocol.js';
|
|
3
4
|
const bind = handlers();
|
|
4
5
|
/** Re-read every live paygate subscription — the manually or periodically triggered repair. */
|
|
5
|
-
export const resyncSubscriptions = bind.request(paymentGate.resyncSubscriptions, async (_request, context) => await
|
|
6
|
+
export const resyncSubscriptions = bind.request(paymentGate.resyncSubscriptions, async (_request, context) => await paymentAccessOf(context).gateway().resyncAll(context));
|
|
6
7
|
//# sourceMappingURL=resync-subscriptions.js.map
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"resync-subscriptions.js","sourceRoot":"","sources":["../../src/actions/resync-subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE5C,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,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resync.d.ts","sourceRoot":"","sources":["../../src/actions/resync.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resync.d.ts","sourceRoot":"","sources":["../../src/actions/resync.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,eAAO,MAAM,MAAM,yJAOjB,CAAA"}
|
package/build/actions/resync.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { PaygateError } from '@owlmeans/payment';
|
|
2
2
|
import { handlers } from '@owlmeans/server-api';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { paymentAccessOf } from '../access.js';
|
|
4
|
+
import { paymentGate } from '../protocol.js';
|
|
5
|
+
import { stripeBootstrapOf } from '../bootstrap.js';
|
|
5
6
|
const bind = handlers();
|
|
6
7
|
/**
|
|
7
8
|
* Forget every sync fingerprint and bring Stripe back to the declared catalogue, portal and webhook —
|
|
@@ -9,11 +10,12 @@ const bind = handlers();
|
|
|
9
10
|
* gateway's `webhookService` and `owner`, so every process of the owner converges on one state.
|
|
10
11
|
*/
|
|
11
12
|
export const resync = bind.request(paymentGate.resync, async (_request, context) => {
|
|
12
|
-
const
|
|
13
|
+
const paymentAccess = paymentAccessOf(context);
|
|
14
|
+
const service = paymentAccess.gateway();
|
|
13
15
|
if (!service.managed)
|
|
14
16
|
throw new PaygateError('unmanaged');
|
|
15
|
-
await fingerprints(
|
|
16
|
-
await bootstrapStripe(
|
|
17
|
+
await paymentAccess.fingerprints().clear();
|
|
18
|
+
await stripeBootstrapOf(context).bootstrapStripe(await service.stripe(context), { force: true });
|
|
17
19
|
return { ok: true };
|
|
18
20
|
});
|
|
19
21
|
//# sourceMappingURL=resync.js.map
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAE/C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEnD,MAAM,IAAI,GAAG,QAAQ,EAAW,CAAA;AAEhC;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;IACjF,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IAC9C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,CAAA;IACvC,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,MAAM,IAAI,YAAY,CAAC,WAAW,CAAC,CAAA;IACzD,MAAM,aAAa,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,CAAA;IAC1C,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAChG,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":"
|
|
1
|
+
{"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/actions/webhook.ts"],"names":[],"mappings":"AAUA,uGAAuG;AACvG,eAAO,MAAM,OAAO;;cAKlB,CAAA"}
|