priceos 1.0.21 → 1.0.23
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 +28 -1
- package/dist/{chunk-SMK7KTGQ.js → chunk-L253ULJU.js} +105 -37
- package/dist/chunk-L253ULJU.js.map +1 -0
- package/dist/client.d.ts +7 -5
- package/dist/embed/pricing-table.global.js +7 -7
- package/dist/gen/openapi.d.ts +1325 -935
- package/dist/index.cjs +104 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/next.cjs +267 -50
- package/dist/next.cjs.map +1 -1
- package/dist/next.js +164 -15
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +104 -73
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.ts +29 -6
- package/dist/react.js +102 -73
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +25 -12
- package/package.json +3 -2
- package/dist/chunk-SMK7KTGQ.js.map +0 -1
package/dist/next.cjs
CHANGED
|
@@ -58,19 +58,16 @@ var getRetryDelayMs = (retryCount) => {
|
|
|
58
58
|
return Math.min(RETRY_DELAY_CAP_MS, backoff + jitter);
|
|
59
59
|
};
|
|
60
60
|
var resolveIdempotencyKey = (input) => {
|
|
61
|
-
const providedEventKey = typeof input.eventKey === "string" ? input.eventKey.trim() : "";
|
|
62
61
|
const providedIdempotencyKey = typeof input.idempotencyKey === "string" ? String(input.idempotencyKey).trim() : "";
|
|
63
|
-
return providedIdempotencyKey
|
|
62
|
+
return providedIdempotencyKey;
|
|
64
63
|
};
|
|
65
64
|
var withIdempotencyKey = (input) => {
|
|
66
65
|
const idempotencyKey = resolveIdempotencyKey(input);
|
|
67
66
|
if (!idempotencyKey) return input;
|
|
68
|
-
|
|
67
|
+
return {
|
|
69
68
|
...input,
|
|
70
69
|
idempotencyKey
|
|
71
70
|
};
|
|
72
|
-
delete next.eventKey;
|
|
73
|
-
return next;
|
|
74
71
|
};
|
|
75
72
|
var createLogger = (logLevel) => {
|
|
76
73
|
const shouldLog = (level) => logLevel !== "none" && LOG_LEVELS[level] <= LOG_LEVELS[logLevel];
|
|
@@ -145,6 +142,22 @@ var throwRequestError = (log, error, response, context) => {
|
|
|
145
142
|
log.error("Request failed", { context, status: response?.status, error });
|
|
146
143
|
throw new PriceOSError(getErrorMessage(error), { status: response?.status, details: error });
|
|
147
144
|
};
|
|
145
|
+
var resolveUrlResponse = (data, response) => {
|
|
146
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
147
|
+
const value = data.url;
|
|
148
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
149
|
+
return { url: value };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const location = response?.headers.get("location");
|
|
153
|
+
if (location && location.trim().length > 0) {
|
|
154
|
+
return { url: location };
|
|
155
|
+
}
|
|
156
|
+
if (response?.redirected && typeof response.url === "string" && response.url.trim().length > 0) {
|
|
157
|
+
return { url: response.url };
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
};
|
|
148
161
|
var createRetryingFetch = (baseFetch, log) => {
|
|
149
162
|
return async (input, init) => {
|
|
150
163
|
const { method, url } = getRequestDetails(input, init);
|
|
@@ -259,9 +272,14 @@ var PriceOS = class {
|
|
|
259
272
|
}
|
|
260
273
|
});
|
|
261
274
|
this.customers = {
|
|
262
|
-
get: async (customerId) => {
|
|
275
|
+
get: async (customerId, options) => {
|
|
276
|
+
const query = options?.expand?.length ? { expand: options.expand } : void 0;
|
|
263
277
|
const { data, error, response } = await this.client.GET("/v1/customers/{customerId}", {
|
|
264
|
-
params: {
|
|
278
|
+
params: {
|
|
279
|
+
path: { customerId },
|
|
280
|
+
...query ? { query } : {},
|
|
281
|
+
header: this.header
|
|
282
|
+
}
|
|
265
283
|
});
|
|
266
284
|
if (error) throwRequestError(this.log, error, response, "GET /v1/customers/{customerId}");
|
|
267
285
|
return data ?? null;
|
|
@@ -291,6 +309,34 @@ var PriceOS = class {
|
|
|
291
309
|
if (error) throwRequestError(this.log, error, response, "PUT /v1/customers/{customerId}");
|
|
292
310
|
return data;
|
|
293
311
|
},
|
|
312
|
+
addCustomProduct: async (input) => {
|
|
313
|
+
const { customerId, ...body } = input;
|
|
314
|
+
const { data, error, response } = await this.client.POST(
|
|
315
|
+
"/v1/customers/{customerId}/custom-product/add",
|
|
316
|
+
{
|
|
317
|
+
params: { path: { customerId }, header: this.header },
|
|
318
|
+
body
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
if (error) {
|
|
322
|
+
throwRequestError(this.log, error, response, "POST /v1/customers/{customerId}/custom-product/add");
|
|
323
|
+
}
|
|
324
|
+
return data;
|
|
325
|
+
},
|
|
326
|
+
removeCustomProduct: async (input) => {
|
|
327
|
+
const { customerId, ...body } = input;
|
|
328
|
+
const { data, error, response } = await this.client.POST(
|
|
329
|
+
"/v1/customers/{customerId}/custom-product/remove",
|
|
330
|
+
{
|
|
331
|
+
params: { path: { customerId }, header: this.header },
|
|
332
|
+
body
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
if (error) {
|
|
336
|
+
throwRequestError(this.log, error, response, "POST /v1/customers/{customerId}/custom-product/remove");
|
|
337
|
+
}
|
|
338
|
+
return data;
|
|
339
|
+
},
|
|
294
340
|
delete: async (customerId) => {
|
|
295
341
|
const { data, error, response } = await this.client.DELETE("/v1/customers/{customerId}", {
|
|
296
342
|
params: { path: { customerId }, header: this.header }
|
|
@@ -308,7 +354,43 @@ var PriceOS = class {
|
|
|
308
354
|
if (error) {
|
|
309
355
|
throwRequestError(this.log, error, response, "POST /v1/customers/{customerId}/customer_portal");
|
|
310
356
|
}
|
|
311
|
-
|
|
357
|
+
if (response && !response.ok) {
|
|
358
|
+
throw new PriceOSError(response.statusText || "Request failed", { status: response.status });
|
|
359
|
+
}
|
|
360
|
+
const result = resolveUrlResponse(data, response);
|
|
361
|
+
if (result) {
|
|
362
|
+
return result;
|
|
363
|
+
}
|
|
364
|
+
throw new PriceOSError("Invalid customer portal response", {
|
|
365
|
+
status: response?.status,
|
|
366
|
+
details: {
|
|
367
|
+
redirected: response?.redirected ?? false,
|
|
368
|
+
responseUrl: response?.url ?? null
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
createCheckout: async (customerId, input) => {
|
|
373
|
+
const { data, error, response } = await this.client.POST("/v1/customers/{customerId}/checkout", {
|
|
374
|
+
params: { path: { customerId }, header: this.header },
|
|
375
|
+
body: input
|
|
376
|
+
});
|
|
377
|
+
if (error) {
|
|
378
|
+
throwRequestError(this.log, error, response, "POST /v1/customers/{customerId}/checkout");
|
|
379
|
+
}
|
|
380
|
+
if (response && !response.ok) {
|
|
381
|
+
throw new PriceOSError(response.statusText || "Request failed", { status: response.status });
|
|
382
|
+
}
|
|
383
|
+
const result = resolveUrlResponse(data, response);
|
|
384
|
+
if (result) {
|
|
385
|
+
return result;
|
|
386
|
+
}
|
|
387
|
+
throw new PriceOSError("Invalid checkout response", {
|
|
388
|
+
status: response?.status,
|
|
389
|
+
details: {
|
|
390
|
+
redirected: response?.redirected ?? false,
|
|
391
|
+
responseUrl: response?.url ?? null
|
|
392
|
+
}
|
|
393
|
+
});
|
|
312
394
|
}
|
|
313
395
|
};
|
|
314
396
|
const getFeatureAccessForCustomer = async (customerId) => {
|
|
@@ -346,7 +428,20 @@ var PriceOS = class {
|
|
|
346
428
|
body: input
|
|
347
429
|
});
|
|
348
430
|
if (error) throwRequestError(this.log, error, response, "POST /v1/checkout");
|
|
349
|
-
|
|
431
|
+
if (response && !response.ok) {
|
|
432
|
+
throw new PriceOSError(response.statusText || "Request failed", { status: response.status });
|
|
433
|
+
}
|
|
434
|
+
const result = resolveUrlResponse(data, response);
|
|
435
|
+
if (result) {
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
throw new PriceOSError("Invalid checkout response", {
|
|
439
|
+
status: response?.status,
|
|
440
|
+
details: {
|
|
441
|
+
redirected: response?.redirected ?? false,
|
|
442
|
+
responseUrl: response?.url ?? null
|
|
443
|
+
}
|
|
444
|
+
});
|
|
350
445
|
}
|
|
351
446
|
};
|
|
352
447
|
this.bonuses = {
|
|
@@ -408,24 +503,6 @@ var PriceOS = class {
|
|
|
408
503
|
if (error) throwRequestError(this.log, error, response, "GET /v1/usage/{id}");
|
|
409
504
|
return data;
|
|
410
505
|
},
|
|
411
|
-
getEventByIdempotencyKey: async (idempotencyKey) => {
|
|
412
|
-
const { data, error, response } = await this.client.GET("/v1/usage/idempotency-key/{idempotencyKey}", {
|
|
413
|
-
params: { header: this.header, path: { idempotencyKey } }
|
|
414
|
-
});
|
|
415
|
-
if (error) {
|
|
416
|
-
throwRequestError(this.log, error, response, "GET /v1/usage/idempotency-key/{idempotencyKey}");
|
|
417
|
-
}
|
|
418
|
-
return data;
|
|
419
|
-
},
|
|
420
|
-
getEventByKey: async (eventKey) => {
|
|
421
|
-
const { data, error, response } = await this.client.GET("/v1/usage/idempotency-key/{idempotencyKey}", {
|
|
422
|
-
params: { header: this.header, path: { idempotencyKey: eventKey } }
|
|
423
|
-
});
|
|
424
|
-
if (error) {
|
|
425
|
-
throwRequestError(this.log, error, response, "GET /v1/usage/idempotency-key/{idempotencyKey}");
|
|
426
|
-
}
|
|
427
|
-
return data;
|
|
428
|
-
},
|
|
429
506
|
updateEvent: async (input) => {
|
|
430
507
|
const { id, ...body } = input;
|
|
431
508
|
const { data, error, response } = await this.client.PUT("/v1/usage/{id}", {
|
|
@@ -435,15 +512,6 @@ var PriceOS = class {
|
|
|
435
512
|
if (error) throwRequestError(this.log, error, response, "PUT /v1/usage/{id}");
|
|
436
513
|
return data;
|
|
437
514
|
},
|
|
438
|
-
voidEvent: async (input) => {
|
|
439
|
-
const { id, ...body } = input;
|
|
440
|
-
const { data, error, response } = await this.client.POST("/v1/usage/{id}/void", {
|
|
441
|
-
params: { header: this.header, path: { id } },
|
|
442
|
-
body
|
|
443
|
-
});
|
|
444
|
-
if (error) throwRequestError(this.log, error, response, "POST /v1/usage/{id}/void");
|
|
445
|
-
return data;
|
|
446
|
-
},
|
|
447
515
|
deleteEvent: async (eventId) => {
|
|
448
516
|
const { data, error, response } = await this.client.DELETE("/v1/usage/{id}", {
|
|
449
517
|
params: { header: this.header, path: { id: eventId } }
|
|
@@ -490,6 +558,7 @@ var FEATURE_ACCESS_PATH = "v1/feature-access";
|
|
|
490
558
|
var TRACK_USAGE_PATH = "v1/usage";
|
|
491
559
|
var PRICING_TABLE_PATH = "v1/pricing-table";
|
|
492
560
|
var CHECKOUT_PATH = "v1/checkout";
|
|
561
|
+
var CUSTOMER_PORTAL_PATH = "v1/customer-portal";
|
|
493
562
|
var normalizePath = (value) => value.replace(/^\/+/, "");
|
|
494
563
|
var logTrackUsageError = (message, details) => {
|
|
495
564
|
if (details === void 0) {
|
|
@@ -507,6 +576,18 @@ var normalizeCustomerId = (value) => {
|
|
|
507
576
|
const normalized = value.trim();
|
|
508
577
|
return normalized.length ? normalized : null;
|
|
509
578
|
};
|
|
579
|
+
var parseCustomerExpand = (url) => {
|
|
580
|
+
const expandValues = [...url.searchParams.getAll("expand"), ...url.searchParams.getAll("expand[]")].flatMap((value) => value.split(",")).map((value) => value.trim()).filter((value) => value.length > 0);
|
|
581
|
+
if (!expandValues.length) {
|
|
582
|
+
return { data: {} };
|
|
583
|
+
}
|
|
584
|
+
const normalizedValues = Array.from(new Set(expandValues));
|
|
585
|
+
const invalidValue = normalizedValues.find((value) => value !== "subscriptions");
|
|
586
|
+
if (invalidValue) {
|
|
587
|
+
return { error: `Invalid expand value: ${invalidValue}` };
|
|
588
|
+
}
|
|
589
|
+
return { data: { expand: normalizedValues } };
|
|
590
|
+
};
|
|
510
591
|
var parseTrackUsageBody = async (request) => {
|
|
511
592
|
let rawBody;
|
|
512
593
|
try {
|
|
@@ -530,7 +611,7 @@ var parseTrackUsageBody = async (request) => {
|
|
|
530
611
|
if (!Number.isFinite(amount) || amount <= 0) {
|
|
531
612
|
return { error: "amount must be a positive number" };
|
|
532
613
|
}
|
|
533
|
-
const idempotencyKeyRaw = body.idempotencyKey
|
|
614
|
+
const idempotencyKeyRaw = body.idempotencyKey;
|
|
534
615
|
const idempotencyKey = idempotencyKeyRaw === void 0 ? void 0 : typeof idempotencyKeyRaw === "string" && idempotencyKeyRaw.trim().length > 0 ? idempotencyKeyRaw.trim() : null;
|
|
535
616
|
if (idempotencyKey === null) {
|
|
536
617
|
return { error: "idempotencyKey must be a non-empty string" };
|
|
@@ -595,13 +676,20 @@ var parseCheckoutBody = async (request) => {
|
|
|
595
676
|
return { error: "Invalid JSON body" };
|
|
596
677
|
}
|
|
597
678
|
const body = rawBody;
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
679
|
+
const stripeProductKey = typeof body.stripeProductKey === "string" && body.stripeProductKey.trim().length > 0 ? body.stripeProductKey.trim() : void 0;
|
|
680
|
+
const stripePriceId = typeof body.stripePriceId === "string" && body.stripePriceId.trim().length > 0 ? body.stripePriceId.trim() : void 0;
|
|
681
|
+
if (!stripeProductKey && !stripePriceId) {
|
|
682
|
+
return { error: "stripeProductKey or stripePriceId is required" };
|
|
601
683
|
}
|
|
602
|
-
const
|
|
603
|
-
if (
|
|
604
|
-
return { error: "successUrl
|
|
684
|
+
const successUrlRaw = body.successUrl;
|
|
685
|
+
if (successUrlRaw !== void 0 && typeof successUrlRaw !== "string") {
|
|
686
|
+
return { error: "successUrl must be a non-empty string" };
|
|
687
|
+
}
|
|
688
|
+
const successUrl = normalizeCustomerId(
|
|
689
|
+
typeof successUrlRaw === "string" ? successUrlRaw : void 0
|
|
690
|
+
);
|
|
691
|
+
if (successUrlRaw !== void 0 && !successUrl) {
|
|
692
|
+
return { error: "successUrl must be a non-empty string" };
|
|
605
693
|
}
|
|
606
694
|
const cancelUrl = typeof body.cancelUrl === "string" && body.cancelUrl.trim().length > 0 ? body.cancelUrl.trim() : void 0;
|
|
607
695
|
const customerId = typeof body.customerId === "string" && body.customerId.trim().length > 0 ? body.customerId.trim() : void 0;
|
|
@@ -616,16 +704,71 @@ var parseCheckoutBody = async (request) => {
|
|
|
616
704
|
}
|
|
617
705
|
}
|
|
618
706
|
}
|
|
707
|
+
const checkoutParamsRaw = body.checkoutParams;
|
|
708
|
+
if (checkoutParamsRaw !== void 0 && (!checkoutParamsRaw || typeof checkoutParamsRaw !== "object" || Array.isArray(checkoutParamsRaw))) {
|
|
709
|
+
return { error: "checkoutParams must be an object" };
|
|
710
|
+
}
|
|
711
|
+
const customerInfoRaw = body.customerInfo;
|
|
712
|
+
if (customerInfoRaw !== void 0 && (!customerInfoRaw || typeof customerInfoRaw !== "object" || Array.isArray(customerInfoRaw))) {
|
|
713
|
+
return { error: "customerInfo must be an object" };
|
|
714
|
+
}
|
|
715
|
+
const customerInfoRecord = customerInfoRaw;
|
|
716
|
+
const customerName = normalizeCustomerId(
|
|
717
|
+
typeof customerInfoRecord?.name === "string" ? customerInfoRecord.name : void 0
|
|
718
|
+
);
|
|
719
|
+
const customerEmail = normalizeCustomerId(
|
|
720
|
+
typeof customerInfoRecord?.email === "string" ? customerInfoRecord.email : void 0
|
|
721
|
+
);
|
|
619
722
|
return {
|
|
620
723
|
data: {
|
|
621
|
-
|
|
622
|
-
|
|
724
|
+
...stripeProductKey ? { stripeProductKey } : {},
|
|
725
|
+
...stripePriceId ? { stripePriceId } : {},
|
|
726
|
+
...successUrl ? { successUrl } : {},
|
|
623
727
|
...cancelUrl ? { cancelUrl } : {},
|
|
624
728
|
...customerId ? { customerId } : {},
|
|
625
|
-
...metadataRaw ? { metadata: metadataRaw } : {}
|
|
729
|
+
...metadataRaw ? { metadata: metadataRaw } : {},
|
|
730
|
+
...checkoutParamsRaw ? { checkoutParams: checkoutParamsRaw } : {},
|
|
731
|
+
...customerInfoRaw ? {
|
|
732
|
+
customerInfo: {
|
|
733
|
+
...customerName ? { name: customerName } : {},
|
|
734
|
+
...customerEmail ? { email: customerEmail } : {}
|
|
735
|
+
}
|
|
736
|
+
} : {}
|
|
626
737
|
}
|
|
627
738
|
};
|
|
628
739
|
};
|
|
740
|
+
var parseCustomerPortalBody = async (request) => {
|
|
741
|
+
let rawText = "";
|
|
742
|
+
try {
|
|
743
|
+
rawText = await request.text();
|
|
744
|
+
} catch {
|
|
745
|
+
return { error: "Invalid JSON body" };
|
|
746
|
+
}
|
|
747
|
+
if (!rawText.trim()) return { data: {} };
|
|
748
|
+
let rawBody;
|
|
749
|
+
try {
|
|
750
|
+
rawBody = JSON.parse(rawText);
|
|
751
|
+
} catch {
|
|
752
|
+
return { error: "Invalid JSON body" };
|
|
753
|
+
}
|
|
754
|
+
if (!rawBody || typeof rawBody !== "object" || Array.isArray(rawBody)) {
|
|
755
|
+
return { error: "Invalid JSON body" };
|
|
756
|
+
}
|
|
757
|
+
const body = rawBody;
|
|
758
|
+
const customerIdRaw = body.customerId;
|
|
759
|
+
if (customerIdRaw !== void 0 && typeof customerIdRaw !== "string") {
|
|
760
|
+
return { error: "customerId must be a non-empty string" };
|
|
761
|
+
}
|
|
762
|
+
const customerId = normalizeCustomerId(
|
|
763
|
+
typeof customerIdRaw === "string" ? customerIdRaw : void 0
|
|
764
|
+
);
|
|
765
|
+
if (customerIdRaw !== void 0 && !customerId) {
|
|
766
|
+
return { error: "customerId must be a non-empty string" };
|
|
767
|
+
}
|
|
768
|
+
return {
|
|
769
|
+
data: customerId ? { customerId } : {}
|
|
770
|
+
};
|
|
771
|
+
};
|
|
629
772
|
var handleGetCustomer = async (request, url, client, getCustomerId) => {
|
|
630
773
|
if (request.method.toUpperCase() !== "GET") {
|
|
631
774
|
return new Response("Method not allowed.", { status: 405 });
|
|
@@ -637,8 +780,12 @@ var handleGetCustomer = async (request, url, client, getCustomerId) => {
|
|
|
637
780
|
if (errorResponse || !customerId) {
|
|
638
781
|
return errorResponse ?? jsonResponse(401, { error: "Customer not identified" });
|
|
639
782
|
}
|
|
783
|
+
const expandResult = parseCustomerExpand(url);
|
|
784
|
+
if (!expandResult.data) {
|
|
785
|
+
return jsonResponse(400, { error: expandResult.error ?? "Invalid request" });
|
|
786
|
+
}
|
|
640
787
|
try {
|
|
641
|
-
const data = await client.customers.get(customerId);
|
|
788
|
+
const data = await client.customers.get(customerId, expandResult.data);
|
|
642
789
|
return jsonResponse(200, data);
|
|
643
790
|
} catch (error) {
|
|
644
791
|
if (error instanceof PriceOSError) {
|
|
@@ -769,12 +916,79 @@ var handleCreateCheckout = async (request, client, getCustomerId) => {
|
|
|
769
916
|
request
|
|
770
917
|
);
|
|
771
918
|
if (errorResponse) return errorResponse;
|
|
919
|
+
if (parsed.data.customerId && resolvedCustomerId && parsed.data.customerId !== resolvedCustomerId) {
|
|
920
|
+
return jsonResponse(403, { error: "customerId must match authenticated customer" });
|
|
921
|
+
}
|
|
922
|
+
const customerId = parsed.data.customerId ?? resolvedCustomerId;
|
|
923
|
+
if (!customerId) {
|
|
924
|
+
return jsonResponse(401, { error: "Customer not identified" });
|
|
925
|
+
}
|
|
926
|
+
if (parsed.data.stripePriceId) {
|
|
927
|
+
const requestOrigin = new URL(request.url).origin;
|
|
928
|
+
const successUrl = parsed.data.successUrl ?? `${requestOrigin}/settings/billing?checkout=success`;
|
|
929
|
+
const cancelUrl = parsed.data.cancelUrl ?? successUrl;
|
|
930
|
+
try {
|
|
931
|
+
const data = await client.checkout.create({
|
|
932
|
+
stripePriceId: parsed.data.stripePriceId,
|
|
933
|
+
successUrl,
|
|
934
|
+
cancelUrl,
|
|
935
|
+
...parsed.data.metadata ? { metadata: parsed.data.metadata } : {},
|
|
936
|
+
customerId
|
|
937
|
+
});
|
|
938
|
+
return jsonResponse(200, data);
|
|
939
|
+
} catch (error) {
|
|
940
|
+
if (error instanceof PriceOSError) {
|
|
941
|
+
return jsonResponse(error.status ?? 500, { error: error.message });
|
|
942
|
+
}
|
|
943
|
+
return jsonResponse(500, { error: "Request failed" });
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
if (!parsed.data.stripeProductKey) {
|
|
947
|
+
return jsonResponse(400, { error: "stripeProductKey is required" });
|
|
948
|
+
}
|
|
949
|
+
const checkoutParams = {
|
|
950
|
+
...parsed.data.checkoutParams ?? {},
|
|
951
|
+
...parsed.data.cancelUrl ? { cancel_url: parsed.data.cancelUrl } : {},
|
|
952
|
+
...parsed.data.metadata ? { metadata: parsed.data.metadata } : {}
|
|
953
|
+
};
|
|
772
954
|
const body = {
|
|
773
|
-
|
|
774
|
-
...parsed.data.
|
|
955
|
+
stripeProductKey: parsed.data.stripeProductKey,
|
|
956
|
+
...parsed.data.successUrl ? { successUrl: parsed.data.successUrl } : {},
|
|
957
|
+
...parsed.data.customerInfo ? { customerInfo: parsed.data.customerInfo } : {},
|
|
958
|
+
...Object.keys(checkoutParams).length ? { checkoutParams } : {}
|
|
775
959
|
};
|
|
776
960
|
try {
|
|
777
|
-
const data = await client.
|
|
961
|
+
const data = await client.customers.createCheckout(customerId, body);
|
|
962
|
+
return jsonResponse(200, data);
|
|
963
|
+
} catch (error) {
|
|
964
|
+
if (error instanceof PriceOSError) {
|
|
965
|
+
return jsonResponse(error.status ?? 500, { error: error.message });
|
|
966
|
+
}
|
|
967
|
+
return jsonResponse(500, { error: "Request failed" });
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
var handleCreateCustomerPortal = async (request, client, getCustomerId) => {
|
|
971
|
+
if (request.method.toUpperCase() !== "POST") {
|
|
972
|
+
return new Response("Method not allowed.", { status: 405 });
|
|
973
|
+
}
|
|
974
|
+
const parsed = await parseCustomerPortalBody(request);
|
|
975
|
+
if (!parsed.data) {
|
|
976
|
+
return jsonResponse(400, { error: parsed.error ?? "Invalid request body" });
|
|
977
|
+
}
|
|
978
|
+
const { customerId: resolvedCustomerId, errorResponse } = await resolveOptionalCustomerId(
|
|
979
|
+
getCustomerId,
|
|
980
|
+
request
|
|
981
|
+
);
|
|
982
|
+
if (errorResponse) return errorResponse;
|
|
983
|
+
if (parsed.data.customerId && resolvedCustomerId && parsed.data.customerId !== resolvedCustomerId) {
|
|
984
|
+
return jsonResponse(403, { error: "customerId must match authenticated customer" });
|
|
985
|
+
}
|
|
986
|
+
const customerId = parsed.data.customerId ?? resolvedCustomerId;
|
|
987
|
+
if (!customerId) {
|
|
988
|
+
return jsonResponse(401, { error: "Customer not identified" });
|
|
989
|
+
}
|
|
990
|
+
try {
|
|
991
|
+
const data = await client.customers.createPortal(customerId);
|
|
778
992
|
return jsonResponse(200, data);
|
|
779
993
|
} catch (error) {
|
|
780
994
|
if (error instanceof PriceOSError) {
|
|
@@ -823,6 +1037,9 @@ function priceosHandler(options = {}) {
|
|
|
823
1037
|
if (path === CHECKOUT_PATH) {
|
|
824
1038
|
return handleCreateCheckout(request, client, getCustomerId);
|
|
825
1039
|
}
|
|
1040
|
+
if (path === CUSTOMER_PORTAL_PATH) {
|
|
1041
|
+
return handleCreateCustomerPortal(request, client, getCustomerId);
|
|
1042
|
+
}
|
|
826
1043
|
return new Response("Not found.", { status: 404 });
|
|
827
1044
|
};
|
|
828
1045
|
return Object.assign(handler, {
|