feat(billingplan): Add Paddle v2 checkout support and backend config endpoint; add CSP headers and bump typedserver
This commit is contained in:
@@ -1,5 +1,15 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-12-07 - 1.10.0 - feat(billingplan)
|
||||||
|
Add Paddle v2 checkout support and backend config endpoint; add CSP headers and bump typedserver
|
||||||
|
|
||||||
|
- Add getPaddleConfig typedrequest handler in BillingPlanManager to expose PADDLE_TOKEN and PADDLE_PRICE_ID from environment.
|
||||||
|
- Introduce IReq_GetPaddleConfig typedrequest interface.
|
||||||
|
- Update frontend paddlesetup to use Paddle v2: load v2 script, call Paddle.Initialize with token, open Checkout using items.priceId and customer.email, and handle checkout.completed events (store transaction_id).
|
||||||
|
- Attempt to obtain user email from account state or via idpClient.whoIs before starting checkout; show error if email unavailable.
|
||||||
|
- Add Content Security Policy securityHeaders to website server configuration to allow Paddle, ProfitWell, Sentry and related assets/connections.
|
||||||
|
- Bump dependency @api.global/typedserver from ^7.8.17 to ^7.10.2.
|
||||||
|
|
||||||
## 2025-12-01 - 1.9.0 - feat(account)
|
## 2025-12-01 - 1.9.0 - feat(account)
|
||||||
Refactor account UI: migrate modals to promise-based show() API and improve navigation URL tracking
|
Refactor account UI: migrate modals to promise-based show() API and improve navigation URL tracking
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@api.global/typedrequest": "^3.2.5",
|
"@api.global/typedrequest": "^3.2.5",
|
||||||
"@api.global/typedrequest-interfaces": "^3.0.19",
|
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||||
"@api.global/typedserver": "^7.8.17",
|
"@api.global/typedserver": "^7.10.2",
|
||||||
"@api.global/typedsocket": "^4.1.0",
|
"@api.global/typedsocket": "^4.1.0",
|
||||||
"@consent.software/catalog": "^2.0.1",
|
"@consent.software/catalog": "^2.0.1",
|
||||||
"@design.estate/dees-catalog": "^2.0.3",
|
"@design.estate/dees-catalog": "^2.0.3",
|
||||||
|
|||||||
Generated
+27
-27
@@ -15,11 +15,11 @@ importers:
|
|||||||
specifier: ^3.0.19
|
specifier: ^3.0.19
|
||||||
version: 3.0.19
|
version: 3.0.19
|
||||||
'@api.global/typedserver':
|
'@api.global/typedserver':
|
||||||
specifier: ^7.8.17
|
specifier: ^7.10.2
|
||||||
version: 7.8.17(@tiptap/pm@2.27.1)
|
version: 7.10.2(@tiptap/pm@2.27.1)
|
||||||
'@api.global/typedsocket':
|
'@api.global/typedsocket':
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0(@push.rocks/smartserve@1.1.2)
|
version: 4.1.0(@push.rocks/smartserve@1.3.0)
|
||||||
'@consent.software/catalog':
|
'@consent.software/catalog':
|
||||||
specifier: ^2.0.1
|
specifier: ^2.0.1
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
@@ -94,7 +94,7 @@ importers:
|
|||||||
version: 2.0.20
|
version: 2.0.20
|
||||||
'@serve.zone/platformclient':
|
'@serve.zone/platformclient':
|
||||||
specifier: ^1.1.2
|
specifier: ^1.1.2
|
||||||
version: 1.1.2(@push.rocks/smartserve@1.1.2)
|
version: 1.1.2(@push.rocks/smartserve@1.3.0)
|
||||||
'@tsclass/tsclass':
|
'@tsclass/tsclass':
|
||||||
specifier: ^9.3.0
|
specifier: ^9.3.0
|
||||||
version: 9.3.0
|
version: 9.3.0
|
||||||
@@ -113,7 +113,7 @@ importers:
|
|||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
'@git.zone/tswatch':
|
'@git.zone/tswatch':
|
||||||
specifier: ^2.2.3
|
specifier: ^2.2.3
|
||||||
version: 2.2.3(@push.rocks/smartserve@1.1.2)
|
version: 2.2.3(@push.rocks/smartserve@1.3.0)
|
||||||
'@push.rocks/projectinfo':
|
'@push.rocks/projectinfo':
|
||||||
specifier: ^5.0.1
|
specifier: ^5.0.1
|
||||||
version: 5.0.2
|
version: 5.0.2
|
||||||
@@ -135,8 +135,8 @@ packages:
|
|||||||
'@api.global/typedserver@3.0.80':
|
'@api.global/typedserver@3.0.80':
|
||||||
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==}
|
||||||
|
|
||||||
'@api.global/typedserver@7.8.17':
|
'@api.global/typedserver@7.10.2':
|
||||||
resolution: {integrity: sha512-I4aA8l2f43HP70dZTEqOyWiDcolFsZm6/0d3B7lYq/DwzorV4IJZ0ZO18jHyGHZuaaJri4m5j3Wt7dn6yHDY3A==}
|
resolution: {integrity: sha512-b/LzAbcJB6aPTd044s23yptZEukD7Hvsi8mXfPfE68OI85I2vfalFO8/h0E9LizoeDFGaTguLXhZYnGl8HkVZQ==}
|
||||||
|
|
||||||
'@api.global/typedsocket@3.1.1':
|
'@api.global/typedsocket@3.1.1':
|
||||||
resolution: {integrity: sha512-Wkz3NlhmfdZMKqXXI2c2dMtGGmSmhdOegZiziL+9b2mqPYdc7Gd8AZRdEOKvbSoIvc9G22/5BEadIWHrfq66TA==}
|
resolution: {integrity: sha512-Wkz3NlhmfdZMKqXXI2c2dMtGGmSmhdOegZiziL+9b2mqPYdc7Gd8AZRdEOKvbSoIvc9G22/5BEadIWHrfq66TA==}
|
||||||
@@ -911,8 +911,8 @@ packages:
|
|||||||
'@push.rocks/smartrx@3.0.10':
|
'@push.rocks/smartrx@3.0.10':
|
||||||
resolution: {integrity: sha512-USjIYcsSfzn14cwOsxgq/bBmWDTTzy3ouWAnW5NdMyRRzEbmeNrvmy6TRqNeDlJ2PsYNTt1rr/zGUqvIy72ITg==}
|
resolution: {integrity: sha512-USjIYcsSfzn14cwOsxgq/bBmWDTTzy3ouWAnW5NdMyRRzEbmeNrvmy6TRqNeDlJ2PsYNTt1rr/zGUqvIy72ITg==}
|
||||||
|
|
||||||
'@push.rocks/smartserve@1.1.2':
|
'@push.rocks/smartserve@1.3.0':
|
||||||
resolution: {integrity: sha512-NkJNgdDt/rfsd9AMheCxtFd5X+ubzffvxOxjb0Aw1A5JR3xmiWeRifqEV1oN7mMTGL9jyQVvIME6Yrdxr244dA==}
|
resolution: {integrity: sha512-4ZR9uKVWXVAPzU5wtCQ1mA9jNmOlUl3oGr50EceLT6803UwbNcst7Ek/BhzSaZ0qb2pz0jO5T/V+icgvZ1/5ww==}
|
||||||
|
|
||||||
'@push.rocks/smartshell@3.3.0':
|
'@push.rocks/smartshell@3.3.0':
|
||||||
resolution: {integrity: sha512-m0w618H6YBs+vXGz1CgS4nPi5CUAnqRtckcS9/koGwfcIx1IpjqmiP47BoCTbdgcv0IPUxQVBG1IXTHPuZ8Z5g==}
|
resolution: {integrity: sha512-m0w618H6YBs+vXGz1CgS4nPi5CUAnqRtckcS9/koGwfcIx1IpjqmiP47BoCTbdgcv0IPUxQVBG1IXTHPuZ8Z5g==}
|
||||||
@@ -3678,11 +3678,11 @@ snapshots:
|
|||||||
'@push.rocks/webrequest': 3.0.37
|
'@push.rocks/webrequest': 3.0.37
|
||||||
'@push.rocks/webstream': 1.0.10
|
'@push.rocks/webstream': 1.0.10
|
||||||
|
|
||||||
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@1.1.2)':
|
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@1.3.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.1.2)
|
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.3.0)
|
||||||
'@cloudflare/workers-types': 4.20251202.0
|
'@cloudflare/workers-types': 4.20251202.0
|
||||||
'@design.estate/dees-comms': 1.0.27
|
'@design.estate/dees-comms': 1.0.27
|
||||||
'@push.rocks/lik': 6.2.2
|
'@push.rocks/lik': 6.2.2
|
||||||
@@ -3726,11 +3726,11 @@ snapshots:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@api.global/typedserver@7.8.17(@tiptap/pm@2.27.1)':
|
'@api.global/typedserver@7.10.2(@tiptap/pm@2.27.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@1.1.2)
|
'@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@1.3.0)
|
||||||
'@cloudflare/workers-types': 4.20251205.0
|
'@cloudflare/workers-types': 4.20251205.0
|
||||||
'@design.estate/dees-catalog': 2.0.3(@tiptap/pm@2.27.1)
|
'@design.estate/dees-catalog': 2.0.3(@tiptap/pm@2.27.1)
|
||||||
'@design.estate/dees-comms': 1.0.30
|
'@design.estate/dees-comms': 1.0.30
|
||||||
@@ -3753,7 +3753,7 @@ snapshots:
|
|||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrequest': 5.0.1
|
'@push.rocks/smartrequest': 5.0.1
|
||||||
'@push.rocks/smartrx': 3.0.10
|
'@push.rocks/smartrx': 3.0.10
|
||||||
'@push.rocks/smartserve': 1.1.2
|
'@push.rocks/smartserve': 1.3.0
|
||||||
'@push.rocks/smartsitemap': 2.0.4
|
'@push.rocks/smartsitemap': 2.0.4
|
||||||
'@push.rocks/smartstream': 3.2.5
|
'@push.rocks/smartstream': 3.2.5
|
||||||
'@push.rocks/smarttime': 4.1.1
|
'@push.rocks/smarttime': 4.1.1
|
||||||
@@ -3772,18 +3772,18 @@ snapshots:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@api.global/typedsocket@3.1.1(@push.rocks/smartserve@1.1.2)':
|
'@api.global/typedsocket@3.1.1(@push.rocks/smartserve@1.3.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@push.rocks/isohash': 2.0.1
|
'@push.rocks/isohash': 2.0.1
|
||||||
'@push.rocks/smartjson': 5.2.0
|
'@push.rocks/smartjson': 5.2.0
|
||||||
'@push.rocks/smartrx': 3.0.10
|
'@push.rocks/smartrx': 3.0.10
|
||||||
'@push.rocks/smartsocket': 2.1.0(@push.rocks/smartserve@1.1.2)
|
'@push.rocks/smartsocket': 2.1.0(@push.rocks/smartserve@1.3.0)
|
||||||
'@push.rocks/smartstring': 4.1.0
|
'@push.rocks/smartstring': 4.1.0
|
||||||
'@push.rocks/smarturl': 3.1.0
|
'@push.rocks/smarturl': 3.1.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@push.rocks/smartserve': 1.1.2
|
'@push.rocks/smartserve': 1.3.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@nuxt/kit'
|
- '@nuxt/kit'
|
||||||
- bufferutil
|
- bufferutil
|
||||||
@@ -3792,7 +3792,7 @@ snapshots:
|
|||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
'@api.global/typedsocket@4.1.0(@push.rocks/smartserve@1.1.2)':
|
'@api.global/typedsocket@4.1.0(@push.rocks/smartserve@1.3.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
@@ -3801,7 +3801,7 @@ snapshots:
|
|||||||
'@push.rocks/smartjson': 5.2.0
|
'@push.rocks/smartjson': 5.2.0
|
||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
'@push.rocks/smartrx': 3.0.10
|
'@push.rocks/smartrx': 3.0.10
|
||||||
'@push.rocks/smartserve': 1.1.2
|
'@push.rocks/smartserve': 1.3.0
|
||||||
'@push.rocks/smartstring': 4.1.0
|
'@push.rocks/smartstring': 4.1.0
|
||||||
'@push.rocks/smarturl': 3.1.0
|
'@push.rocks/smarturl': 3.1.0
|
||||||
|
|
||||||
@@ -4598,9 +4598,9 @@ snapshots:
|
|||||||
'@push.rocks/smartshell': 3.3.0
|
'@push.rocks/smartshell': 3.3.0
|
||||||
tsx: 4.21.0
|
tsx: 4.21.0
|
||||||
|
|
||||||
'@git.zone/tswatch@2.2.3(@push.rocks/smartserve@1.1.2)':
|
'@git.zone/tswatch@2.2.3(@push.rocks/smartserve@1.3.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.2)
|
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.3.0)
|
||||||
'@git.zone/tsbundle': 2.6.3
|
'@git.zone/tsbundle': 2.6.3
|
||||||
'@git.zone/tsrun': 2.0.0
|
'@git.zone/tsrun': 2.0.0
|
||||||
'@push.rocks/early': 4.0.4
|
'@push.rocks/early': 4.0.4
|
||||||
@@ -5380,7 +5380,7 @@ snapshots:
|
|||||||
'@push.rocks/smartpromise': 4.2.3
|
'@push.rocks/smartpromise': 4.2.3
|
||||||
rxjs: 7.8.2
|
rxjs: 7.8.2
|
||||||
|
|
||||||
'@push.rocks/smartserve@1.1.2':
|
'@push.rocks/smartserve@1.3.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
'@push.rocks/lik': 6.2.2
|
'@push.rocks/lik': 6.2.2
|
||||||
@@ -5410,10 +5410,10 @@ snapshots:
|
|||||||
'@push.rocks/webrequest': 4.0.1
|
'@push.rocks/webrequest': 4.0.1
|
||||||
'@tsclass/tsclass': 9.3.0
|
'@tsclass/tsclass': 9.3.0
|
||||||
|
|
||||||
'@push.rocks/smartsocket@2.1.0(@push.rocks/smartserve@1.1.2)':
|
'@push.rocks/smartsocket@2.1.0(@push.rocks/smartserve@1.3.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest-interfaces': 3.0.19
|
'@api.global/typedrequest-interfaces': 3.0.19
|
||||||
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.2)
|
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.3.0)
|
||||||
'@push.rocks/isohash': 2.0.1
|
'@push.rocks/isohash': 2.0.1
|
||||||
'@push.rocks/isounique': 1.0.5
|
'@push.rocks/isounique': 1.0.5
|
||||||
'@push.rocks/lik': 6.2.2
|
'@push.rocks/lik': 6.2.2
|
||||||
@@ -5727,11 +5727,11 @@ snapshots:
|
|||||||
'@push.rocks/smartlog-interfaces': 3.0.2
|
'@push.rocks/smartlog-interfaces': 3.0.2
|
||||||
'@tsclass/tsclass': 4.4.4
|
'@tsclass/tsclass': 4.4.4
|
||||||
|
|
||||||
'@serve.zone/platformclient@1.1.2(@push.rocks/smartserve@1.1.2)':
|
'@serve.zone/platformclient@1.1.2(@push.rocks/smartserve@1.3.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@api.global/typedrequest': 3.2.5
|
'@api.global/typedrequest': 3.2.5
|
||||||
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.2)
|
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.3.0)
|
||||||
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.1.2)
|
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.3.0)
|
||||||
'@push.rocks/qenv': 6.1.3
|
'@push.rocks/qenv': 6.1.3
|
||||||
'@push.rocks/smartlog': 3.1.10
|
'@push.rocks/smartlog': 3.1.10
|
||||||
'@push.rocks/smartntml': 2.0.8
|
'@push.rocks/smartntml': 2.0.8
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@idp.global/idp.global',
|
name: '@idp.global/idp.global',
|
||||||
version: '1.9.0',
|
version: '1.10.0',
|
||||||
description: 'An identity provider software managing user authentications, registrations, and sessions.'
|
description: 'An identity provider software managing user authentications, registrations, and sessions.'
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -8,6 +8,17 @@ export const runCli = async () => {
|
|||||||
feedMetadata: null,
|
feedMetadata: null,
|
||||||
domain: 'idp.global',
|
domain: 'idp.global',
|
||||||
serveDir: paths.distWebDir,
|
serveDir: paths.distWebDir,
|
||||||
|
securityHeaders: {
|
||||||
|
csp: {
|
||||||
|
defaultSrc: "'self'",
|
||||||
|
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://cdn.paddle.com", "https://public.profitwell.com"],
|
||||||
|
styleSrc: ["'self'", "'unsafe-inline'", "https://cdn.paddle.com", "https://assetbroker.lossless.one"],
|
||||||
|
imgSrc: ["'self'", "data:", "https:"],
|
||||||
|
fontSrc: ["'self'", "data:"],
|
||||||
|
connectSrc: ["'self'", "https://*.paddle.com", "https://buy.paddle.com", "https://checkout.paddle.com", "https://checkout-service.paddle.com", "https://cdn.paddle.com", "https://*.sentry.io", "https://public.profitwell.com", "wss:"],
|
||||||
|
frameSrc: ["https://buy.paddle.com", "https://checkout.paddle.com", "https://*.paddle.com"],
|
||||||
|
},
|
||||||
|
},
|
||||||
addCustomRoutes: async (typedserver) => {
|
addCustomRoutes: async (typedserver) => {
|
||||||
// Enable SPA fallback - serves index.html for non-file routes (e.g., /login, /dashboard)
|
// Enable SPA fallback - serves index.html for non-file routes (e.g., /login, /dashboard)
|
||||||
typedserver.options.spaFallback = true;
|
typedserver.options.spaFallback = true;
|
||||||
|
|||||||
@@ -59,6 +59,17 @@ export class BillingPlanManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}));
|
||||||
|
|
||||||
|
// Paddle configuration endpoint
|
||||||
|
this.typedrouter.addTypedHandler(
|
||||||
|
new plugins.typedrequest.TypedHandler<plugins.idpInterfaces.request.IReq_GetPaddleConfig>(
|
||||||
|
'getPaddleConfig',
|
||||||
|
async () => ({
|
||||||
|
paddleToken: await this.receptionRef.serviceQenv.getEnvVarOnDemand('PADDLE_TOKEN'),
|
||||||
|
paddlePriceId: await this.receptionRef.serviceQenv.getEnvVarOnDemand('PADDLE_PRICE_ID'),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,3 +37,19 @@ export interface IReq_GetBillingPlan
|
|||||||
billingPlan: data.IBillingPlan;
|
billingPlan: data.IBillingPlan;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Paddle configuration from environment variables
|
||||||
|
*/
|
||||||
|
export interface IReq_GetPaddleConfig
|
||||||
|
extends plugins.typedRequestInterfaces.implementsTR<
|
||||||
|
plugins.typedRequestInterfaces.ITypedRequest,
|
||||||
|
IReq_GetPaddleConfig
|
||||||
|
> {
|
||||||
|
method: 'getPaddleConfig';
|
||||||
|
request: {};
|
||||||
|
response: {
|
||||||
|
paddleToken: string;
|
||||||
|
paddlePriceId: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@idp.global/idp.global',
|
name: '@idp.global/idp.global',
|
||||||
version: '1.9.0',
|
version: '1.10.0',
|
||||||
description: 'An identity provider software managing user authentications, registrations, and sessions.'
|
description: 'An identity provider software managing user authentications, registrations, and sessions.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
import * as plugins from '../../../plugins.js';
|
import * as plugins from '../../../plugins.js';
|
||||||
import sharedStyles from '../sharedstyles.js';
|
import sharedStyles from '../sharedstyles.js';
|
||||||
import * as state from '../../../states/accountstate.js';
|
import * as state from '../../../states/accountstate.js';
|
||||||
|
import { IdpState } from '../../../states/idp.state.js';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
@@ -61,28 +62,50 @@ export class PaddleSetupView extends DeesElement {
|
|||||||
public async openPaddle() {
|
public async openPaddle() {
|
||||||
await this.domtoolsPromise;
|
await this.domtoolsPromise;
|
||||||
const paddleButton = this.shadowRoot.querySelector('dees-button');
|
const paddleButton = this.shadowRoot.querySelector('dees-button');
|
||||||
await this.domtools.setExternalScript('https://cdn.paddle.com/paddle/paddle.js');
|
const idpState = await IdpState.getSingletonInstance();
|
||||||
globalThis.Paddle.Setup({
|
|
||||||
vendor: 30954,
|
// Get user email - first try from state, then fetch directly
|
||||||
|
let userEmail = state.accountState.getState().user?.data?.email;
|
||||||
|
|
||||||
|
if (!userEmail) {
|
||||||
|
// State not loaded, fetch user directly
|
||||||
|
const whoIsResponse = await idpState.idpClient.whoIs().catch(() => null);
|
||||||
|
userEmail = whoIsResponse?.user?.data?.email;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userEmail) {
|
||||||
|
console.error('Unable to get user email for Paddle checkout');
|
||||||
|
paddleButton.status = 'error';
|
||||||
|
paddleButton.text = 'Error: Not logged in';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch Paddle config from backend
|
||||||
|
const configRequest = idpState.idpClient.typedsocket
|
||||||
|
.createTypedRequest<plugins.idpInterfaces.request.IReq_GetPaddleConfig>('getPaddleConfig');
|
||||||
|
const { paddleToken, paddlePriceId } = await configRequest.fire({});
|
||||||
|
|
||||||
|
await this.domtools.setExternalScript('https://cdn.paddle.com/paddle/v2/paddle.js');
|
||||||
|
globalThis.Paddle.Initialize({
|
||||||
|
token: paddleToken,
|
||||||
eventCallback: async (dataArg: any) => {
|
eventCallback: async (dataArg: any) => {
|
||||||
// The data.event will specify the event type
|
// Paddle Billing v2 event handling
|
||||||
if (dataArg.event === 'Checkout.Complete') {
|
if (dataArg.name === 'checkout.completed') {
|
||||||
const data: plugins.idpInterfaces.data.IPaddleCheckoutData = dataArg.eventData;
|
|
||||||
const paddleIframe = document.body.querySelector('iframe');
|
const paddleIframe = document.body.querySelector('iframe');
|
||||||
if (paddleIframe) {
|
if (paddleIframe) {
|
||||||
document.body.removeChild(paddleIframe);
|
document.body.removeChild(paddleIframe);
|
||||||
}
|
}
|
||||||
paddleButton.status = 'pending';
|
paddleButton.status = 'pending';
|
||||||
paddleButton.text = 'Processing...';
|
paddleButton.text = 'Processing...';
|
||||||
await state.accountState.dispatchAction(state.updatePaddleCheckoutId, data.checkout.id);
|
await state.accountState.dispatchAction(state.updatePaddleCheckoutId, dataArg.data.transaction_id);
|
||||||
paddleButton.status = 'success';
|
paddleButton.status = 'success';
|
||||||
paddleButton.text = 'Paddle connected!'
|
paddleButton.text = 'Paddle connected!'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
globalThis.Paddle.Checkout.open({
|
globalThis.Paddle.Checkout.open({
|
||||||
product: 561076,
|
items: [{ priceId: paddlePriceId, quantity: 1 }],
|
||||||
email: 'phil@kunz.io',
|
customer: { email: userEmail },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user