@sintecinformatik/checkout 1.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,106 @@
1
+ # @sintec/checkout
2
+
3
+ React components for integrating Sintec License Server checkout into your product website.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @sintec/checkout
9
+ ```
10
+
11
+ > **Note**: Package not yet published to npm. For now, copy the source from this directory or use a local path reference.
12
+
13
+ ## Usage
14
+
15
+ ### CheckoutButton Component
16
+
17
+ The simplest way to add a buy button:
18
+
19
+ ```tsx
20
+ import { CheckoutButton } from "@sintec/checkout";
21
+
22
+ function BuyPage() {
23
+ return (
24
+ <CheckoutButton
25
+ productSlug="your-product"
26
+ licenseType="perpetual"
27
+ customerEmail="user@example.com"
28
+ className="buy-button"
29
+ >
30
+ Buy License - $99
31
+ </CheckoutButton>
32
+ );
33
+ }
34
+ ```
35
+
36
+ ### useCheckout Hook
37
+
38
+ For custom UI implementations:
39
+
40
+ ```tsx
41
+ import { useCheckout } from "@sintec/checkout";
42
+
43
+ function CustomCheckout() {
44
+ const { startCheckout, isLoading, error } = useCheckout();
45
+
46
+ const handleBuy = async () => {
47
+ await startCheckout({
48
+ productSlug: "your-product",
49
+ licenseType: "perpetual",
50
+ customerEmail: "user@example.com",
51
+ });
52
+ };
53
+
54
+ return (
55
+ <div>
56
+ <button onClick={handleBuy} disabled={isLoading}>
57
+ {isLoading ? "Processing..." : "Purchase"}
58
+ </button>
59
+ {error && <p className="error">{error}</p>}
60
+ </div>
61
+ );
62
+ }
63
+ ```
64
+
65
+ ## API Reference
66
+
67
+ ### CheckoutButton Props
68
+
69
+ | Prop | Type | Required | Description |
70
+ |------|------|----------|-------------|
71
+ | `productSlug` | `string` | Yes | Product identifier |
72
+ | `licenseType` | `"perpetual" \| "monthly" \| "yearly"` | Yes | License type |
73
+ | `customerEmail` | `string` | No | Pre-fill customer email in Stripe |
74
+ | `serverUrl` | `string` | No | License server URL (default: `https://license.sintec.ch`) |
75
+ | `className` | `string` | No | CSS class for styling |
76
+ | `children` | `ReactNode` | No | Button content (default: "Buy Now") |
77
+ | `onCheckoutStart` | `() => void` | No | Called when checkout begins |
78
+ | `onError` | `(error: string) => void` | No | Called on error |
79
+
80
+ ### useCheckout Options
81
+
82
+ ```tsx
83
+ const { startCheckout, isLoading, error } = useCheckout({
84
+ serverUrl: "https://license.sintec.ch", // optional
85
+ });
86
+ ```
87
+
88
+ ### startCheckout Parameters
89
+
90
+ | Param | Type | Required | Description |
91
+ |-------|------|----------|-------------|
92
+ | `productSlug` | `string` | Yes | Product identifier |
93
+ | `licenseType` | `"perpetual" \| "monthly" \| "yearly"` | Yes | License type |
94
+ | `customerEmail` | `string` | No | Pre-fill customer email |
95
+
96
+ ## How It Works
97
+
98
+ 1. User clicks the checkout button
99
+ 2. Package calls the license server API to create a Stripe checkout session
100
+ 3. User is redirected to Stripe to complete payment
101
+ 4. After payment, user is redirected to the license server success page
102
+ 5. Success page displays the generated license key
103
+
104
+ ## License
105
+
106
+ MIT
@@ -0,0 +1,47 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type LicenseType = "perpetual" | "monthly" | "yearly";
4
+ interface CheckoutOptions {
5
+ /** Base URL of the license server (defaults to https://license.sintec.ch) */
6
+ serverUrl?: string;
7
+ }
8
+ interface StartCheckoutParams {
9
+ /** Product slug identifier */
10
+ productSlug: string;
11
+ /** Type of license to purchase */
12
+ licenseType: LicenseType;
13
+ /** Customer email (optional, pre-fills Stripe checkout) */
14
+ customerEmail?: string;
15
+ }
16
+ interface CheckoutButtonProps extends StartCheckoutParams {
17
+ /** Base URL of the license server */
18
+ serverUrl?: string;
19
+ /** Additional CSS classes */
20
+ className?: string;
21
+ /** Button content */
22
+ children?: React.ReactNode;
23
+ /** Callback when checkout starts */
24
+ onCheckoutStart?: () => void;
25
+ /** Callback on error */
26
+ onError?: (error: string) => void;
27
+ }
28
+ interface CheckoutSessionResponse {
29
+ checkoutUrl: string;
30
+ }
31
+ interface CheckoutErrorResponse {
32
+ error: string;
33
+ }
34
+
35
+ declare function CheckoutButton({ productSlug, licenseType, customerEmail, serverUrl, className, children, onCheckoutStart, onError, }: CheckoutButtonProps): react_jsx_runtime.JSX.Element;
36
+
37
+ interface UseCheckoutReturn {
38
+ /** Start the checkout process */
39
+ startCheckout: (params: StartCheckoutParams) => Promise<void>;
40
+ /** Whether a checkout is currently in progress */
41
+ isLoading: boolean;
42
+ /** Last error message, if any */
43
+ error: string | null;
44
+ }
45
+ declare function useCheckout(options?: CheckoutOptions): UseCheckoutReturn;
46
+
47
+ export { CheckoutButton, type CheckoutButtonProps, type CheckoutErrorResponse, type CheckoutOptions, type CheckoutSessionResponse, type LicenseType, type StartCheckoutParams, type UseCheckoutReturn, useCheckout };
@@ -0,0 +1,47 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type LicenseType = "perpetual" | "monthly" | "yearly";
4
+ interface CheckoutOptions {
5
+ /** Base URL of the license server (defaults to https://license.sintec.ch) */
6
+ serverUrl?: string;
7
+ }
8
+ interface StartCheckoutParams {
9
+ /** Product slug identifier */
10
+ productSlug: string;
11
+ /** Type of license to purchase */
12
+ licenseType: LicenseType;
13
+ /** Customer email (optional, pre-fills Stripe checkout) */
14
+ customerEmail?: string;
15
+ }
16
+ interface CheckoutButtonProps extends StartCheckoutParams {
17
+ /** Base URL of the license server */
18
+ serverUrl?: string;
19
+ /** Additional CSS classes */
20
+ className?: string;
21
+ /** Button content */
22
+ children?: React.ReactNode;
23
+ /** Callback when checkout starts */
24
+ onCheckoutStart?: () => void;
25
+ /** Callback on error */
26
+ onError?: (error: string) => void;
27
+ }
28
+ interface CheckoutSessionResponse {
29
+ checkoutUrl: string;
30
+ }
31
+ interface CheckoutErrorResponse {
32
+ error: string;
33
+ }
34
+
35
+ declare function CheckoutButton({ productSlug, licenseType, customerEmail, serverUrl, className, children, onCheckoutStart, onError, }: CheckoutButtonProps): react_jsx_runtime.JSX.Element;
36
+
37
+ interface UseCheckoutReturn {
38
+ /** Start the checkout process */
39
+ startCheckout: (params: StartCheckoutParams) => Promise<void>;
40
+ /** Whether a checkout is currently in progress */
41
+ isLoading: boolean;
42
+ /** Last error message, if any */
43
+ error: string | null;
44
+ }
45
+ declare function useCheckout(options?: CheckoutOptions): UseCheckoutReturn;
46
+
47
+ export { CheckoutButton, type CheckoutButtonProps, type CheckoutErrorResponse, type CheckoutOptions, type CheckoutSessionResponse, type LicenseType, type StartCheckoutParams, type UseCheckoutReturn, useCheckout };
package/dist/index.js ADDED
@@ -0,0 +1,120 @@
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
+ CheckoutButton: () => CheckoutButton,
24
+ useCheckout: () => useCheckout
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/useCheckout.ts
29
+ var import_react = require("react");
30
+ var DEFAULT_SERVER_URL = "https://license.sintec.ch";
31
+ function useCheckout(options = {}) {
32
+ const { serverUrl = DEFAULT_SERVER_URL } = options;
33
+ const [isLoading, setIsLoading] = (0, import_react.useState)(false);
34
+ const [error, setError] = (0, import_react.useState)(null);
35
+ const startCheckout = (0, import_react.useCallback)(
36
+ async (params) => {
37
+ setIsLoading(true);
38
+ setError(null);
39
+ try {
40
+ const response = await fetch(`${serverUrl}/api/v1/checkout/session`, {
41
+ method: "POST",
42
+ headers: {
43
+ "Content-Type": "application/json"
44
+ },
45
+ body: JSON.stringify({
46
+ productSlug: params.productSlug,
47
+ licenseType: params.licenseType,
48
+ customerEmail: params.customerEmail
49
+ })
50
+ });
51
+ const data = await response.json();
52
+ if (!response.ok) {
53
+ const errorData = data;
54
+ throw new Error(errorData.error || "Failed to create checkout session");
55
+ }
56
+ const successData = data;
57
+ if (successData.checkoutUrl) {
58
+ window.location.href = successData.checkoutUrl;
59
+ } else {
60
+ throw new Error("No checkout URL returned");
61
+ }
62
+ } catch (err) {
63
+ const message = err instanceof Error ? err.message : "Failed to start checkout";
64
+ setError(message);
65
+ throw err;
66
+ } finally {
67
+ setIsLoading(false);
68
+ }
69
+ },
70
+ [serverUrl]
71
+ );
72
+ return {
73
+ startCheckout,
74
+ isLoading,
75
+ error
76
+ };
77
+ }
78
+
79
+ // src/CheckoutButton.tsx
80
+ var import_jsx_runtime = require("react/jsx-runtime");
81
+ function CheckoutButton({
82
+ productSlug,
83
+ licenseType,
84
+ customerEmail,
85
+ serverUrl,
86
+ className,
87
+ children = "Buy Now",
88
+ onCheckoutStart,
89
+ onError
90
+ }) {
91
+ const { startCheckout, isLoading } = useCheckout({ serverUrl });
92
+ const handleClick = async () => {
93
+ onCheckoutStart?.();
94
+ try {
95
+ await startCheckout({
96
+ productSlug,
97
+ licenseType,
98
+ customerEmail
99
+ });
100
+ } catch (err) {
101
+ const message = err instanceof Error ? err.message : "Checkout failed";
102
+ onError?.(message);
103
+ }
104
+ };
105
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ onClick: handleClick,
110
+ disabled: isLoading,
111
+ className,
112
+ children: isLoading ? "Loading..." : children
113
+ }
114
+ );
115
+ }
116
+ // Annotate the CommonJS export names for ESM import in node:
117
+ 0 && (module.exports = {
118
+ CheckoutButton,
119
+ useCheckout
120
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,92 @@
1
+ // src/useCheckout.ts
2
+ import { useState, useCallback } from "react";
3
+ var DEFAULT_SERVER_URL = "https://license.sintec.ch";
4
+ function useCheckout(options = {}) {
5
+ const { serverUrl = DEFAULT_SERVER_URL } = options;
6
+ const [isLoading, setIsLoading] = useState(false);
7
+ const [error, setError] = useState(null);
8
+ const startCheckout = useCallback(
9
+ async (params) => {
10
+ setIsLoading(true);
11
+ setError(null);
12
+ try {
13
+ const response = await fetch(`${serverUrl}/api/v1/checkout/session`, {
14
+ method: "POST",
15
+ headers: {
16
+ "Content-Type": "application/json"
17
+ },
18
+ body: JSON.stringify({
19
+ productSlug: params.productSlug,
20
+ licenseType: params.licenseType,
21
+ customerEmail: params.customerEmail
22
+ })
23
+ });
24
+ const data = await response.json();
25
+ if (!response.ok) {
26
+ const errorData = data;
27
+ throw new Error(errorData.error || "Failed to create checkout session");
28
+ }
29
+ const successData = data;
30
+ if (successData.checkoutUrl) {
31
+ window.location.href = successData.checkoutUrl;
32
+ } else {
33
+ throw new Error("No checkout URL returned");
34
+ }
35
+ } catch (err) {
36
+ const message = err instanceof Error ? err.message : "Failed to start checkout";
37
+ setError(message);
38
+ throw err;
39
+ } finally {
40
+ setIsLoading(false);
41
+ }
42
+ },
43
+ [serverUrl]
44
+ );
45
+ return {
46
+ startCheckout,
47
+ isLoading,
48
+ error
49
+ };
50
+ }
51
+
52
+ // src/CheckoutButton.tsx
53
+ import { jsx } from "react/jsx-runtime";
54
+ function CheckoutButton({
55
+ productSlug,
56
+ licenseType,
57
+ customerEmail,
58
+ serverUrl,
59
+ className,
60
+ children = "Buy Now",
61
+ onCheckoutStart,
62
+ onError
63
+ }) {
64
+ const { startCheckout, isLoading } = useCheckout({ serverUrl });
65
+ const handleClick = async () => {
66
+ onCheckoutStart?.();
67
+ try {
68
+ await startCheckout({
69
+ productSlug,
70
+ licenseType,
71
+ customerEmail
72
+ });
73
+ } catch (err) {
74
+ const message = err instanceof Error ? err.message : "Checkout failed";
75
+ onError?.(message);
76
+ }
77
+ };
78
+ return /* @__PURE__ */ jsx(
79
+ "button",
80
+ {
81
+ type: "button",
82
+ onClick: handleClick,
83
+ disabled: isLoading,
84
+ className,
85
+ children: isLoading ? "Loading..." : children
86
+ }
87
+ );
88
+ }
89
+ export {
90
+ CheckoutButton,
91
+ useCheckout
92
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@sintecinformatik/checkout",
3
+ "version": "1.0.0",
4
+ "description": "Checkout components for Sintec License Server",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts",
20
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
21
+ "lint": "eslint src/",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@types/react": "^19.0.0",
29
+ "react": "^19.0.0",
30
+ "tsup": "^8.0.0",
31
+ "typescript": "^5.0.0"
32
+ },
33
+ "keywords": [
34
+ "checkout",
35
+ "stripe",
36
+ "license",
37
+ "sintec"
38
+ ],
39
+ "author": "Sintec",
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/gitmeupchris/SintecLicenseServer.git",
44
+ "directory": "checkout"
45
+ }
46
+ }