@spaire/hono 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # @spaire/hono
2
+
3
+ Payments and Checkouts made dead simple with Hono.
4
+
5
+ `pnpm install @spaire/hono zod`
6
+
7
+ ## Checkout
8
+
9
+ Create a Checkout handler which takes care of redirections.
10
+
11
+ ```typescript
12
+ import { Hono } from "hono";
13
+ import { Checkout } from "@spaire/hono";
14
+
15
+ const app = new Hono();
16
+
17
+ app.get(
18
+ "/checkout",
19
+ Checkout({
20
+ accessToken: "xxx", // Or set an environment variable to SPAIRE_ACCESS_TOKEN
21
+ successUrl: process.env.SUCCESS_URL,
22
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Checkout
23
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
24
+ theme: "dark" // Enforces the theme - System-preferred theme will be set if left omitted
25
+ }),
26
+ );
27
+ ```
28
+
29
+ ### Query Params
30
+
31
+ Pass query params to this route.
32
+
33
+ - products `?products=123`
34
+ - customerId (optional) `?products=123&customerId=xxx`
35
+ - customerExternalId (optional) `?products=123&customerExternalId=xxx`
36
+ - customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
37
+ - customerName (optional) `?products=123&customerName=Jane`
38
+ - metadata (optional) `URL-Encoded JSON string`
39
+
40
+ ## Customer Portal
41
+
42
+ Create a customer portal where your customer can view orders and subscriptions.
43
+
44
+ ```typescript
45
+ import { Hono } from "hono";
46
+ import { CustomerPortal } from "@spaire/hono";
47
+
48
+ const app = new Hono();
49
+
50
+ app.get(
51
+ "/portal",
52
+ CustomerPortal({
53
+ accessToken: "xxx", // Or set an environment variable to SPAIRE_ACCESS_TOKEN
54
+ getCustomerId: (event) => "", // Fuction to resolve a Spaire Customer ID
55
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Customer Portal
56
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
57
+ }),
58
+ );
59
+ ```
60
+
61
+ ## Webhooks
62
+
63
+ A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
64
+
65
+ ```typescript
66
+ import { Hono } from 'hono'
67
+ import { Webhooks } from "@spaire/hono";
68
+
69
+ const app = new Hono()
70
+
71
+ app.post('/spaire/webhooks', Webhooks({
72
+ webhookSecret: process.env.SPAIRE_WEBHOOK_SECRET!,
73
+ onPayload: async (payload) => /** Handle payload */,
74
+ }))
75
+ ```
76
+
77
+ #### Payload Handlers
78
+
79
+ The Webhook handler also supports granular handlers for easy integration.
80
+
81
+ - onCheckoutCreated: (payload) =>
82
+ - onCheckoutUpdated: (payload) =>
83
+ - onOrderCreated: (payload) =>
84
+ - onOrderUpdated: (payload) =>
85
+ - onOrderPaid: (payload) =>
86
+ - onSubscriptionCreated: (payload) =>
87
+ - onSubscriptionUpdated: (payload) =>
88
+ - onSubscriptionActive: (payload) =>
89
+ - onSubscriptionCanceled: (payload) =>
90
+ - onSubscriptionRevoked: (payload) =>
91
+ - onProductCreated: (payload) =>
92
+ - onProductUpdated: (payload) =>
93
+ - onOrganizationUpdated: (payload) =>
94
+ - onBenefitCreated: (payload) =>
95
+ - onBenefitUpdated: (payload) =>
96
+ - onBenefitGrantCreated: (payload) =>
97
+ - onBenefitGrantUpdated: (payload) =>
98
+ - onBenefitGrantRevoked: (payload) =>
99
+ - onCustomerCreated: (payload) =>
100
+ - onCustomerUpdated: (payload) =>
101
+ - onCustomerDeleted: (payload) =>
102
+ - onCustomerStateChanged: (payload) =>
package/dist/index.cjs ADDED
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Checkout: () => Checkout,
24
+ CustomerPortal: () => CustomerPortal,
25
+ EntitlementStrategy: () => import_adapter_utils2.EntitlementStrategy,
26
+ Entitlements: () => import_adapter_utils2.Entitlements,
27
+ Webhooks: () => Webhooks
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+ var import_adapter_utils = require("@spaire/adapter-utils");
31
+ var import_sdk = require("@spaire/sdk");
32
+ var import_webhooks = require("@spaire/sdk/webhooks");
33
+ var import_adapter_utils2 = require("@spaire/adapter-utils");
34
+ var Checkout = ({
35
+ accessToken,
36
+ successUrl,
37
+ returnUrl,
38
+ server,
39
+ theme,
40
+ includeCheckoutId = true
41
+ }) => {
42
+ const spaire = new import_sdk.Spaire({
43
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
44
+ server
45
+ });
46
+ return async (c) => {
47
+ const url = new URL(c.req.url);
48
+ const products = url.searchParams.getAll("products");
49
+ if (products.length === 0) {
50
+ return c.json(
51
+ { error: "Missing products in query params" },
52
+ { status: 400 }
53
+ );
54
+ }
55
+ const success = successUrl ? new URL(successUrl) : void 0;
56
+ if (success && includeCheckoutId) {
57
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
58
+ }
59
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
60
+ try {
61
+ const result = await spaire.checkouts.create({
62
+ products,
63
+ successUrl: success ? decodeURI(success.toString()) : void 0,
64
+ customerId: url.searchParams.get("customerId") ?? void 0,
65
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
66
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
67
+ customerName: url.searchParams.get("customerName") ?? void 0,
68
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
69
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
70
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
71
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
72
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
73
+ discountId: url.searchParams.get("discountId") ?? void 0,
74
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
75
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
76
+ });
77
+ const redirectUrl = new URL(result.url);
78
+ if (theme) {
79
+ redirectUrl.searchParams.set("theme", theme);
80
+ }
81
+ return c.redirect(redirectUrl.toString());
82
+ } catch (error) {
83
+ console.error(error);
84
+ return c.json({ error: "Internal server error" }, { status: 500 });
85
+ }
86
+ };
87
+ };
88
+ var CustomerPortal = ({
89
+ accessToken,
90
+ server,
91
+ getCustomerId,
92
+ returnUrl
93
+ }) => {
94
+ const spaire = new import_sdk.Spaire({
95
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
96
+ server
97
+ });
98
+ return async (c) => {
99
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
100
+ const customerId = await getCustomerId(c);
101
+ if (!customerId) {
102
+ return c.json({ error: "customerId not defined" }, { status: 400 });
103
+ }
104
+ try {
105
+ const result = await spaire.customerSessions.create({
106
+ customerId,
107
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
108
+ });
109
+ return c.redirect(result.customerPortalUrl);
110
+ } catch (error) {
111
+ console.error(error);
112
+ return c.json({ error: "Internal server error" }, { status: 500 });
113
+ }
114
+ };
115
+ };
116
+ var Webhooks = ({
117
+ webhookSecret,
118
+ onPayload,
119
+ entitlements,
120
+ ...eventHandlers
121
+ }) => {
122
+ return async (c) => {
123
+ const requestBody = await c.req.text();
124
+ const webhookHeaders = {
125
+ "webhook-id": c.req.header("webhook-id") ?? "",
126
+ "webhook-timestamp": c.req.header("webhook-timestamp") ?? "",
127
+ "webhook-signature": c.req.header("webhook-signature") ?? ""
128
+ };
129
+ let webhookPayload;
130
+ try {
131
+ webhookPayload = (0, import_webhooks.validateEvent)(
132
+ requestBody,
133
+ webhookHeaders,
134
+ webhookSecret
135
+ );
136
+ } catch (error) {
137
+ if (error instanceof import_webhooks.WebhookVerificationError) {
138
+ return c.json({ received: false }, { status: 403 });
139
+ }
140
+ throw error;
141
+ }
142
+ await (0, import_adapter_utils.handleWebhookPayload)(webhookPayload, {
143
+ webhookSecret,
144
+ entitlements,
145
+ onPayload,
146
+ ...eventHandlers
147
+ });
148
+ return c.json({ received: true });
149
+ };
150
+ };
151
+ // Annotate the CommonJS export names for ESM import in node:
152
+ 0 && (module.exports = {
153
+ Checkout,
154
+ CustomerPortal,
155
+ EntitlementStrategy,
156
+ Entitlements,
157
+ Webhooks
158
+ });
159
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n\ttype WebhooksConfig,\n\thandleWebhookPayload,\n} from \"@spaire/adapter-utils\";\nimport { Spaire } from \"@spaire/sdk\";\nimport { WebhookVerificationError, validateEvent } from \"@spaire/sdk/webhooks\";\nimport type { Context } from \"hono\";\n\nexport {\n\ttype EntitlementContext,\n\ttype EntitlementHandler,\n\ttype EntitlementProperties,\n\tEntitlementStrategy,\n\tEntitlements,\n} from \"@spaire/adapter-utils\";\nexport interface CheckoutConfig {\n\taccessToken?: string;\n\tsuccessUrl?: string;\n\treturnUrl?: string;\n\tincludeCheckoutId?: boolean;\n\tserver?: \"sandbox\" | \"production\";\n\ttheme?: \"light\" | \"dark\";\n}\n\nexport const Checkout = ({\n\taccessToken,\n\tsuccessUrl,\n\treturnUrl,\n\tserver,\n\ttheme,\n\tincludeCheckoutId = true,\n}: CheckoutConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (c: Context) => {\n\t\tconst url = new URL(c.req.url);\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn c.json(\n\t\t\t\t{ error: \"Missing products in query params\" },\n\t\t\t\t{ status: 400 },\n\t\t\t);\n\t\t}\n\n\t\tconst success = successUrl ? new URL(successUrl) : undefined;\n\n\t\tif (success && includeCheckoutId) {\n\t\t\tsuccess.searchParams.set(\"checkoutId\", \"{CHECKOUT_ID}\");\n\t\t}\n\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\ttry {\n\t\t\tconst result = await spaire.checkouts.create({\n\t\t\t\tproducts,\n\t\t\t\tsuccessUrl: success ? decodeURI(success.toString()) : undefined,\n\t\t\t\tcustomerId: url.searchParams.get(\"customerId\") ?? undefined,\n\t\t\t\texternalCustomerId:\n\t\t\t\t\turl.searchParams.get(\"customerExternalId\") ?? undefined,\n\t\t\t\tcustomerEmail: url.searchParams.get(\"customerEmail\") ?? undefined,\n\t\t\t\tcustomerName: url.searchParams.get(\"customerName\") ?? undefined,\n\t\t\t\tcustomerBillingAddress: url.searchParams.has(\"customerBillingAddress\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerBillingAddress\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tcustomerTaxId: url.searchParams.get(\"customerTaxId\") ?? undefined,\n\t\t\t\tcustomerIpAddress:\n\t\t\t\t\turl.searchParams.get(\"customerIpAddress\") ?? undefined,\n\t\t\t\tcustomerMetadata: url.searchParams.has(\"customerMetadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerMetadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tallowDiscountCodes: url.searchParams.has(\"allowDiscountCodes\")\n\t\t\t\t\t? url.searchParams.get(\"allowDiscountCodes\") === \"true\"\n\t\t\t\t\t: undefined,\n\t\t\t\tdiscountId: url.searchParams.get(\"discountId\") ?? undefined,\n\t\t\t\tmetadata: url.searchParams.has(\"metadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"metadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\tconst redirectUrl = new URL(result.url);\n\n\t\t\tif (theme) {\n\t\t\t\tredirectUrl.searchParams.set(\"theme\", theme);\n\t\t\t}\n\n\t\t\treturn c.redirect(redirectUrl.toString());\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn c.json({ error: \"Internal server error\" }, { status: 500 });\n\t\t}\n\t};\n};\n\nexport interface CustomerPortalConfig {\n\taccessToken?: string;\n\tgetCustomerId: (req: Context) => Promise<string>;\n\tserver?: \"sandbox\" | \"production\";\n\treturnUrl?: string;\n}\n\nexport const CustomerPortal = ({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (c: Context) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\tconst customerId = await getCustomerId(c);\n\n\t\tif (!customerId) {\n\t\t\treturn c.json({ error: \"customerId not defined\" }, { status: 400 });\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await spaire.customerSessions.create({\n\t\t\t\tcustomerId,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\treturn c.redirect(result.customerPortalUrl);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn c.json({ error: \"Internal server error\" }, { status: 500 });\n\t\t}\n\t};\n};\n\nexport const Webhooks = ({\n\twebhookSecret,\n\tonPayload,\n\tentitlements,\n\t...eventHandlers\n}: WebhooksConfig) => {\n\treturn async (c: Context) => {\n\t\tconst requestBody = await c.req.text();\n\n\t\tconst webhookHeaders = {\n\t\t\t\"webhook-id\": c.req.header(\"webhook-id\") ?? \"\",\n\t\t\t\"webhook-timestamp\": c.req.header(\"webhook-timestamp\") ?? \"\",\n\t\t\t\"webhook-signature\": c.req.header(\"webhook-signature\") ?? \"\",\n\t\t};\n\n\t\tlet webhookPayload: ReturnType<typeof validateEvent>;\n\t\ttry {\n\t\t\twebhookPayload = validateEvent(\n\t\t\t\trequestBody,\n\t\t\t\twebhookHeaders,\n\t\t\t\twebhookSecret,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn c.json({ received: false }, { status: 403 });\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\n\t\tawait handleWebhookPayload(webhookPayload, {\n\t\t\twebhookSecret,\n\t\t\tentitlements,\n\t\t\tonPayload,\n\t\t\t...eventHandlers,\n\t\t});\n\n\t\treturn c.json({ received: true });\n\t};\n};\n"],"mappings":"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","names":["import_adapter_utils"]}
@@ -0,0 +1,37 @@
1
+ import * as hono_utils_http_status from 'hono/utils/http-status';
2
+ import * as hono from 'hono';
3
+ import { Context } from 'hono';
4
+ import { WebhooksConfig } from '@spaire/adapter-utils';
5
+ export { EntitlementContext, EntitlementHandler, EntitlementProperties, EntitlementStrategy, Entitlements } from '@spaire/adapter-utils';
6
+
7
+ interface CheckoutConfig {
8
+ accessToken?: string;
9
+ successUrl?: string;
10
+ returnUrl?: string;
11
+ includeCheckoutId?: boolean;
12
+ server?: "sandbox" | "production";
13
+ theme?: "light" | "dark";
14
+ }
15
+ declare const Checkout: ({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => (c: Context) => Promise<(Response & hono.TypedResponse<{
16
+ error: string;
17
+ }, 400, "json">) | (Response & hono.TypedResponse<undefined, 302, "redirect">) | (Response & hono.TypedResponse<{
18
+ error: string;
19
+ }, 500, "json">)>;
20
+ interface CustomerPortalConfig {
21
+ accessToken?: string;
22
+ getCustomerId: (req: Context) => Promise<string>;
23
+ server?: "sandbox" | "production";
24
+ returnUrl?: string;
25
+ }
26
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => (c: Context) => Promise<(Response & hono.TypedResponse<undefined, 302, "redirect">) | (Response & hono.TypedResponse<{
27
+ error: string;
28
+ }, 400, "json">) | (Response & hono.TypedResponse<{
29
+ error: string;
30
+ }, 500, "json">)>;
31
+ declare const Webhooks: ({ webhookSecret, onPayload, entitlements, ...eventHandlers }: WebhooksConfig) => (c: Context) => Promise<(Response & hono.TypedResponse<{
32
+ received: false;
33
+ }, 403, "json">) | (Response & hono.TypedResponse<{
34
+ received: true;
35
+ }, hono_utils_http_status.ContentfulStatusCode, "json">)>;
36
+
37
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
@@ -0,0 +1,37 @@
1
+ import * as hono_utils_http_status from 'hono/utils/http-status';
2
+ import * as hono from 'hono';
3
+ import { Context } from 'hono';
4
+ import { WebhooksConfig } from '@spaire/adapter-utils';
5
+ export { EntitlementContext, EntitlementHandler, EntitlementProperties, EntitlementStrategy, Entitlements } from '@spaire/adapter-utils';
6
+
7
+ interface CheckoutConfig {
8
+ accessToken?: string;
9
+ successUrl?: string;
10
+ returnUrl?: string;
11
+ includeCheckoutId?: boolean;
12
+ server?: "sandbox" | "production";
13
+ theme?: "light" | "dark";
14
+ }
15
+ declare const Checkout: ({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => (c: Context) => Promise<(Response & hono.TypedResponse<{
16
+ error: string;
17
+ }, 400, "json">) | (Response & hono.TypedResponse<undefined, 302, "redirect">) | (Response & hono.TypedResponse<{
18
+ error: string;
19
+ }, 500, "json">)>;
20
+ interface CustomerPortalConfig {
21
+ accessToken?: string;
22
+ getCustomerId: (req: Context) => Promise<string>;
23
+ server?: "sandbox" | "production";
24
+ returnUrl?: string;
25
+ }
26
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => (c: Context) => Promise<(Response & hono.TypedResponse<undefined, 302, "redirect">) | (Response & hono.TypedResponse<{
27
+ error: string;
28
+ }, 400, "json">) | (Response & hono.TypedResponse<{
29
+ error: string;
30
+ }, 500, "json">)>;
31
+ declare const Webhooks: ({ webhookSecret, onPayload, entitlements, ...eventHandlers }: WebhooksConfig) => (c: Context) => Promise<(Response & hono.TypedResponse<{
32
+ received: false;
33
+ }, 403, "json">) | (Response & hono.TypedResponse<{
34
+ received: true;
35
+ }, hono_utils_http_status.ContentfulStatusCode, "json">)>;
36
+
37
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
package/dist/index.js ADDED
@@ -0,0 +1,135 @@
1
+ // src/index.ts
2
+ import {
3
+ handleWebhookPayload
4
+ } from "@spaire/adapter-utils";
5
+ import { Spaire } from "@spaire/sdk";
6
+ import { WebhookVerificationError, validateEvent } from "@spaire/sdk/webhooks";
7
+ import {
8
+ EntitlementStrategy,
9
+ Entitlements
10
+ } from "@spaire/adapter-utils";
11
+ var Checkout = ({
12
+ accessToken,
13
+ successUrl,
14
+ returnUrl,
15
+ server,
16
+ theme,
17
+ includeCheckoutId = true
18
+ }) => {
19
+ const spaire = new Spaire({
20
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
21
+ server
22
+ });
23
+ return async (c) => {
24
+ const url = new URL(c.req.url);
25
+ const products = url.searchParams.getAll("products");
26
+ if (products.length === 0) {
27
+ return c.json(
28
+ { error: "Missing products in query params" },
29
+ { status: 400 }
30
+ );
31
+ }
32
+ const success = successUrl ? new URL(successUrl) : void 0;
33
+ if (success && includeCheckoutId) {
34
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
35
+ }
36
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
37
+ try {
38
+ const result = await spaire.checkouts.create({
39
+ products,
40
+ successUrl: success ? decodeURI(success.toString()) : void 0,
41
+ customerId: url.searchParams.get("customerId") ?? void 0,
42
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
43
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
44
+ customerName: url.searchParams.get("customerName") ?? void 0,
45
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
46
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
47
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
48
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
49
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
50
+ discountId: url.searchParams.get("discountId") ?? void 0,
51
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
52
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
53
+ });
54
+ const redirectUrl = new URL(result.url);
55
+ if (theme) {
56
+ redirectUrl.searchParams.set("theme", theme);
57
+ }
58
+ return c.redirect(redirectUrl.toString());
59
+ } catch (error) {
60
+ console.error(error);
61
+ return c.json({ error: "Internal server error" }, { status: 500 });
62
+ }
63
+ };
64
+ };
65
+ var CustomerPortal = ({
66
+ accessToken,
67
+ server,
68
+ getCustomerId,
69
+ returnUrl
70
+ }) => {
71
+ const spaire = new Spaire({
72
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
73
+ server
74
+ });
75
+ return async (c) => {
76
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
77
+ const customerId = await getCustomerId(c);
78
+ if (!customerId) {
79
+ return c.json({ error: "customerId not defined" }, { status: 400 });
80
+ }
81
+ try {
82
+ const result = await spaire.customerSessions.create({
83
+ customerId,
84
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
85
+ });
86
+ return c.redirect(result.customerPortalUrl);
87
+ } catch (error) {
88
+ console.error(error);
89
+ return c.json({ error: "Internal server error" }, { status: 500 });
90
+ }
91
+ };
92
+ };
93
+ var Webhooks = ({
94
+ webhookSecret,
95
+ onPayload,
96
+ entitlements,
97
+ ...eventHandlers
98
+ }) => {
99
+ return async (c) => {
100
+ const requestBody = await c.req.text();
101
+ const webhookHeaders = {
102
+ "webhook-id": c.req.header("webhook-id") ?? "",
103
+ "webhook-timestamp": c.req.header("webhook-timestamp") ?? "",
104
+ "webhook-signature": c.req.header("webhook-signature") ?? ""
105
+ };
106
+ let webhookPayload;
107
+ try {
108
+ webhookPayload = validateEvent(
109
+ requestBody,
110
+ webhookHeaders,
111
+ webhookSecret
112
+ );
113
+ } catch (error) {
114
+ if (error instanceof WebhookVerificationError) {
115
+ return c.json({ received: false }, { status: 403 });
116
+ }
117
+ throw error;
118
+ }
119
+ await handleWebhookPayload(webhookPayload, {
120
+ webhookSecret,
121
+ entitlements,
122
+ onPayload,
123
+ ...eventHandlers
124
+ });
125
+ return c.json({ received: true });
126
+ };
127
+ };
128
+ export {
129
+ Checkout,
130
+ CustomerPortal,
131
+ EntitlementStrategy,
132
+ Entitlements,
133
+ Webhooks
134
+ };
135
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n\ttype WebhooksConfig,\n\thandleWebhookPayload,\n} from \"@spaire/adapter-utils\";\nimport { Spaire } from \"@spaire/sdk\";\nimport { WebhookVerificationError, validateEvent } from \"@spaire/sdk/webhooks\";\nimport type { Context } from \"hono\";\n\nexport {\n\ttype EntitlementContext,\n\ttype EntitlementHandler,\n\ttype EntitlementProperties,\n\tEntitlementStrategy,\n\tEntitlements,\n} from \"@spaire/adapter-utils\";\nexport interface CheckoutConfig {\n\taccessToken?: string;\n\tsuccessUrl?: string;\n\treturnUrl?: string;\n\tincludeCheckoutId?: boolean;\n\tserver?: \"sandbox\" | \"production\";\n\ttheme?: \"light\" | \"dark\";\n}\n\nexport const Checkout = ({\n\taccessToken,\n\tsuccessUrl,\n\treturnUrl,\n\tserver,\n\ttheme,\n\tincludeCheckoutId = true,\n}: CheckoutConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (c: Context) => {\n\t\tconst url = new URL(c.req.url);\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn c.json(\n\t\t\t\t{ error: \"Missing products in query params\" },\n\t\t\t\t{ status: 400 },\n\t\t\t);\n\t\t}\n\n\t\tconst success = successUrl ? new URL(successUrl) : undefined;\n\n\t\tif (success && includeCheckoutId) {\n\t\t\tsuccess.searchParams.set(\"checkoutId\", \"{CHECKOUT_ID}\");\n\t\t}\n\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\ttry {\n\t\t\tconst result = await spaire.checkouts.create({\n\t\t\t\tproducts,\n\t\t\t\tsuccessUrl: success ? decodeURI(success.toString()) : undefined,\n\t\t\t\tcustomerId: url.searchParams.get(\"customerId\") ?? undefined,\n\t\t\t\texternalCustomerId:\n\t\t\t\t\turl.searchParams.get(\"customerExternalId\") ?? undefined,\n\t\t\t\tcustomerEmail: url.searchParams.get(\"customerEmail\") ?? undefined,\n\t\t\t\tcustomerName: url.searchParams.get(\"customerName\") ?? undefined,\n\t\t\t\tcustomerBillingAddress: url.searchParams.has(\"customerBillingAddress\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerBillingAddress\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tcustomerTaxId: url.searchParams.get(\"customerTaxId\") ?? undefined,\n\t\t\t\tcustomerIpAddress:\n\t\t\t\t\turl.searchParams.get(\"customerIpAddress\") ?? undefined,\n\t\t\t\tcustomerMetadata: url.searchParams.has(\"customerMetadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerMetadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tallowDiscountCodes: url.searchParams.has(\"allowDiscountCodes\")\n\t\t\t\t\t? url.searchParams.get(\"allowDiscountCodes\") === \"true\"\n\t\t\t\t\t: undefined,\n\t\t\t\tdiscountId: url.searchParams.get(\"discountId\") ?? undefined,\n\t\t\t\tmetadata: url.searchParams.has(\"metadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"metadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\tconst redirectUrl = new URL(result.url);\n\n\t\t\tif (theme) {\n\t\t\t\tredirectUrl.searchParams.set(\"theme\", theme);\n\t\t\t}\n\n\t\t\treturn c.redirect(redirectUrl.toString());\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn c.json({ error: \"Internal server error\" }, { status: 500 });\n\t\t}\n\t};\n};\n\nexport interface CustomerPortalConfig {\n\taccessToken?: string;\n\tgetCustomerId: (req: Context) => Promise<string>;\n\tserver?: \"sandbox\" | \"production\";\n\treturnUrl?: string;\n}\n\nexport const CustomerPortal = ({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (c: Context) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\tconst customerId = await getCustomerId(c);\n\n\t\tif (!customerId) {\n\t\t\treturn c.json({ error: \"customerId not defined\" }, { status: 400 });\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await spaire.customerSessions.create({\n\t\t\t\tcustomerId,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\treturn c.redirect(result.customerPortalUrl);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn c.json({ error: \"Internal server error\" }, { status: 500 });\n\t\t}\n\t};\n};\n\nexport const Webhooks = ({\n\twebhookSecret,\n\tonPayload,\n\tentitlements,\n\t...eventHandlers\n}: WebhooksConfig) => {\n\treturn async (c: Context) => {\n\t\tconst requestBody = await c.req.text();\n\n\t\tconst webhookHeaders = {\n\t\t\t\"webhook-id\": c.req.header(\"webhook-id\") ?? \"\",\n\t\t\t\"webhook-timestamp\": c.req.header(\"webhook-timestamp\") ?? \"\",\n\t\t\t\"webhook-signature\": c.req.header(\"webhook-signature\") ?? \"\",\n\t\t};\n\n\t\tlet webhookPayload: ReturnType<typeof validateEvent>;\n\t\ttry {\n\t\t\twebhookPayload = validateEvent(\n\t\t\t\trequestBody,\n\t\t\t\twebhookHeaders,\n\t\t\t\twebhookSecret,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn c.json({ received: false }, { status: 403 });\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\n\t\tawait handleWebhookPayload(webhookPayload, {\n\t\t\twebhookSecret,\n\t\t\tentitlements,\n\t\t\tonPayload,\n\t\t\t...eventHandlers,\n\t\t});\n\n\t\treturn c.json({ received: true });\n\t};\n};\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@spaire/hono",
3
+ "version": "2.0.0",
4
+ "description": "Spaire integration for Hono",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ "import": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "require": {
14
+ "types": "./dist/index.d.cts",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "type": "module",
19
+ "engines": {
20
+ "node": ">=16"
21
+ },
22
+ "scripts": {
23
+ "test": "vitest",
24
+ "build": "tsup ./src/index.ts --format esm,cjs --dts --clean --sourcemap",
25
+ "dev": "tsc --watch",
26
+ "check": "biome check --write ./src"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "keywords": [
32
+ "spaire",
33
+ "hono",
34
+ "payments",
35
+ "subscriptions"
36
+ ],
37
+ "peerDependencies": {
38
+ "hono": "^4.6.16"
39
+ },
40
+ "devDependencies": {
41
+ "@biomejs/biome": "1.9.4",
42
+ "@sindresorhus/tsconfig": "^7.0.0",
43
+ "@types/node": "^20.0.0",
44
+ "hono": "^4.10.7",
45
+ "prettier": "^3.7.4",
46
+ "tsup": "^8.5.1",
47
+ "vitest": "^2.1.8"
48
+ },
49
+ "dependencies": {
50
+ "@spaire/adapter-utils": "^2.0.0",
51
+ "@spaire/sdk": "^0.45.1"
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ }
56
+ }