feat(billingplan): Add Paddle v2 checkout support and backend config endpoint; add CSP headers and bump typedserver
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
import * as plugins from '../../../plugins.js';
|
||||
import sharedStyles from '../sharedstyles.js';
|
||||
import * as state from '../../../states/accountstate.js';
|
||||
import { IdpState } from '../../../states/idp.state.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
@@ -61,28 +62,50 @@ export class PaddleSetupView extends DeesElement {
|
||||
public async openPaddle() {
|
||||
await this.domtoolsPromise;
|
||||
const paddleButton = this.shadowRoot.querySelector('dees-button');
|
||||
await this.domtools.setExternalScript('https://cdn.paddle.com/paddle/paddle.js');
|
||||
globalThis.Paddle.Setup({
|
||||
vendor: 30954,
|
||||
const idpState = await IdpState.getSingletonInstance();
|
||||
|
||||
// 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) => {
|
||||
// The data.event will specify the event type
|
||||
if (dataArg.event === 'Checkout.Complete') {
|
||||
const data: plugins.idpInterfaces.data.IPaddleCheckoutData = dataArg.eventData;
|
||||
// Paddle Billing v2 event handling
|
||||
if (dataArg.name === 'checkout.completed') {
|
||||
const paddleIframe = document.body.querySelector('iframe');
|
||||
if (paddleIframe) {
|
||||
document.body.removeChild(paddleIframe);
|
||||
}
|
||||
paddleButton.status = 'pending';
|
||||
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.text = 'Paddle connected!'
|
||||
}
|
||||
},
|
||||
});
|
||||
globalThis.Paddle.Checkout.open({
|
||||
product: 561076,
|
||||
email: 'phil@kunz.io',
|
||||
items: [{ priceId: paddlePriceId, quantity: 1 }],
|
||||
customer: { email: userEmail },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user