@superlogic/spree-pay 0.1.17 → 0.1.18

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 CHANGED
@@ -14,13 +14,14 @@ npm i @superlogic/spree-pay
14
14
  import { useState } from 'react';
15
15
 
16
16
  import { SpreePay, SpreePayProvider, useSpreePay } from '@superlogic/spree-pay';
17
+ import { useCapture3DS } from '@superlogic/spree-pay';
17
18
  import '@superlogic/spree-pay/styles.css';
18
19
 
19
20
  const spreeEnv = {
20
- tenantId: 'moca' // Keep moca for crypto payments on BASE network
21
+ tenantId: 'moca', // Keep moca for crypto payments on BASE network
21
22
  environment: 'dev' as const,
22
- redirect3dsURI: '/3ds' // Any valid URI in your app that captures 3ds redirect
23
- ssoPageURI: '/silent-check-sso.html' // Any valid URI in your app that will handle keyklock SSO (example below)
23
+ redirect3dsURI: '/3ds', // Any valid URI in your app that captures 3ds redirect
24
+ ssoPageURI: '/silent-check-sso.html', // Any valid URI in your app that will handle Keycloak SSO (example below)
24
25
  };
25
26
 
26
27
  function Checkout() {
@@ -48,16 +49,20 @@ function CheckoutContent() {
48
49
  }
49
50
 
50
51
  return (
51
- <div style={{ maxWidth: 540 }}>
52
- <SpreePay isLoading={status === 'processing'} amount={99} onProcess={handleProcess} />
52
+ <div>
53
+ <SpreePay
54
+ amount={99}
55
+ onProcess={handleProcess}
56
+ transactionFeePercentage={0.04}
57
+ className="w-full max-w-[540px]"
58
+ isProcessing={status === 'processing'}
59
+ />
53
60
  {status === 'success' && <p>Payment successful! Thank you for your order.</p>}
54
61
  {status === 'error' && <p>Payment failed. Please try again.</p>}
55
62
  </div>
56
63
  );
57
64
  }
58
65
 
59
- import { useCapture3DS } from '@superlogic/spree-pay';
60
-
61
66
  // example 3DS redirect page hosted on /3ds
62
67
  export default function ThreeDSRedirectPage() {
63
68
  // take payment intent from search params as payment_intent
@@ -69,10 +74,17 @@ export default function ThreeDSRedirectPage() {
69
74
  // Render null or any other UI/Loader
70
75
  return null;
71
76
  }
72
-
73
77
  ```
74
78
 
75
- ## Keyklock SSO page example (/silent-check-sso.html)
79
+ ### SpreePay props
80
+
81
+ - amount: number — USD amount to charge (e.g., 99 for $99). Used for display and fee calculation.
82
+ - onProcess: () => Promise<void> — Called when the Checkout button is clicked. Implement your order flow here and call useSpreePay().process({ hash, ... }).
83
+ - isProcessing: boolean — Optional, shows a loading state and disables interactions when true (useful while your onProcess runs).
84
+ - transactionFeePercentage: number — Optional fee multiplier applied to the USD portion (e.g., 0.04 for 4%).
85
+ - className: string — Optional wrapper class for layout/styling.
86
+
87
+ ## Keycloak SSO page example (/silent-check-sso.html)
76
88
 
77
89
  ```html
78
90
  <!doctype html>
package/build/index.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ PaymentType: () => PaymentType,
33
34
  SpreePay: () => SpreePay,
34
35
  SpreePayProvider: () => SpreePayProvider,
35
36
  useCapture3DS: () => useCapture3DS,
@@ -57,6 +58,15 @@ var PaymentError = class extends Error {
57
58
  }
58
59
  };
59
60
 
61
+ // src/types/payments.ts
62
+ var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
63
+ PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
64
+ PaymentType2["CRYPTO"] = "CRYPTO";
65
+ PaymentType2["SPLIT"] = "SPLIT";
66
+ PaymentType2["POINTS"] = "POINTS";
67
+ return PaymentType2;
68
+ })(PaymentType || {});
69
+
60
70
  // src/context/SpreePayActionsContext.tsx
61
71
  var import_jsx_runtime = require("react/jsx-runtime");
62
72
  var SpreePayActionsContext = (0, import_react.createContext)(void 0);
@@ -130,15 +140,15 @@ var CONFIG = {
130
140
  dev: {
131
141
  bookit: {
132
142
  slapiUrl: "https://slapi.dev.superlogic.com",
133
- keyklockUrl: "https://auth.dev.join.bookit.com",
134
- keyklockClientId: "oneof-next",
143
+ keycloakUrl: "https://auth.dev.join.bookit.com",
144
+ keycloakClientId: "oneof-next",
135
145
  pointsConversionRatio: 100,
136
146
  pointsTitle: "AIR SP"
137
147
  },
138
148
  moca: {
139
149
  slapiUrl: "https://slapi.dev.air.shop",
140
- keyklockUrl: "https://login.dev.air.shop",
141
- keyklockClientId: "oneof-next",
150
+ keycloakUrl: "https://login.dev.air.shop",
151
+ keycloakClientId: "oneof-next",
142
152
  pointsConversionRatio: 100,
143
153
  pointsTitle: "AIR SP"
144
154
  }
@@ -146,15 +156,15 @@ var CONFIG = {
146
156
  stg: {
147
157
  bookit: {
148
158
  slapiUrl: "https://slapi.stg.superlogic.com",
149
- keyklockUrl: "https://auth.stg.join.bookit.com",
150
- keyklockClientId: "oneof-next",
159
+ keycloakUrl: "https://auth.stg.join.bookit.com",
160
+ keycloakClientId: "oneof-next",
151
161
  pointsConversionRatio: 100,
152
162
  pointsTitle: "AIR SP"
153
163
  },
154
164
  moca: {
155
165
  slapiUrl: "https://slapi.stg.air.shop",
156
- keyklockUrl: "https://login.stg.air.shop",
157
- keyklockClientId: "oneof-next",
166
+ keycloakUrl: "https://login.stg.air.shop",
167
+ keycloakClientId: "oneof-next",
158
168
  pointsConversionRatio: 100,
159
169
  pointsTitle: "AIR SP"
160
170
  }
@@ -162,15 +172,15 @@ var CONFIG = {
162
172
  prod: {
163
173
  bookit: {
164
174
  slapiUrl: "https://slapi.superlogic.com",
165
- keyklockUrl: "https://auth.join.bookit.com",
166
- keyklockClientId: "oneof-next",
175
+ keycloakUrl: "https://auth.join.bookit.com",
176
+ keycloakClientId: "oneof-next",
167
177
  pointsConversionRatio: 100,
168
178
  pointsTitle: "AIR SP"
169
179
  },
170
180
  moca: {
171
181
  slapiUrl: "https://slapi.air.shop",
172
- keyklockUrl: "https://login.air.shop",
173
- keyklockClientId: "oneof-next",
182
+ keycloakUrl: "https://login.air.shop",
183
+ keycloakClientId: "oneof-next",
174
184
  pointsConversionRatio: 100,
175
185
  pointsTitle: "AIR SP"
176
186
  }
@@ -184,7 +194,9 @@ var StaticConfigProvider = ({ children, props }) => {
184
194
  setAppProps(props);
185
195
  }, [props]);
186
196
  const staticConfig = (0, import_react2.useMemo)(() => {
187
- return CONFIG[env.environment][env.tenantId];
197
+ const envConfig = CONFIG[env.environment];
198
+ const appKey = env.tenantId in envConfig ? env.tenantId : "moca";
199
+ return envConfig[appKey];
188
200
  }, [env.environment, env.tenantId]);
189
201
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(StaticConfigContext.Provider, { value: { staticConfig, appProps }, children });
190
202
  };
@@ -639,7 +651,7 @@ var SlapiPaymentService = {
639
651
  return slapiApi.post("/v1/payments/validate", { paymentId, type: "CREDIT_CARD" /* CREDIT_CARD */ }).then((data) => ({ data }));
640
652
  },
641
653
  validatePoints: ({ paymentId, txHash }) => {
642
- return slapiApi.post("/v1/payments/validate", { txHash, paymentId, type: "SPLIT" /* SPLIT */ }).then((data) => ({ data }));
654
+ return slapiApi.post("/v1/payments/validate", { txHash, paymentId, type: "POINTS" /* POINTS */ }).then((data) => ({ data }));
643
655
  },
644
656
  getStatus: (paymentId) => {
645
657
  return slapiApi.get(`/v1/payments/${paymentId}/status`);
@@ -2380,6 +2392,7 @@ var Points = () => {
2380
2392
  const [usePoints, setUsePoints] = (0, import_react12.useState)(false);
2381
2393
  const [selectedPointsType, setSelectedPointsType] = (0, import_react12.useState)(null);
2382
2394
  const { setSelectedPaymentMethod, selectedPaymentMethod } = useSpreePaymentMethod();
2395
+ const { spreePayConfig } = useSpreePayConfig();
2383
2396
  const handleTogglePoints = (enabled) => {
2384
2397
  setUsePoints(enabled);
2385
2398
  if (!enabled) {
@@ -2388,7 +2401,7 @@ var Points = () => {
2388
2401
  }
2389
2402
  };
2390
2403
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
2391
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PointsSwitch, { value: usePoints, onChange: handleTogglePoints }),
2404
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PointsSwitch, { disabled: !spreePayConfig?.creditCard.enabled, value: usePoints, onChange: handleTogglePoints }),
2392
2405
  usePoints && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SplitBlock, { isSelected: selectedPointsType === "air", onSelect: setSelectedPointsType })
2393
2406
  ] });
2394
2407
  };
@@ -3231,8 +3244,8 @@ var SpreePayInner = () => {
3231
3244
  const tenantId = env?.tenantId || "bookit";
3232
3245
  const { isChecking, accessToken } = useKeycloakSSO({
3233
3246
  realm: tenantId,
3234
- url: staticConfig.keyklockUrl,
3235
- clientId: staticConfig.keyklockClientId,
3247
+ url: staticConfig.keycloakUrl,
3248
+ clientId: staticConfig.keycloakClientId,
3236
3249
  ssoPageURI: env?.ssoPageURI,
3237
3250
  enabled: !env?.accessToken
3238
3251
  });
@@ -3279,13 +3292,14 @@ var SpreePay = (props) => {
3279
3292
  var import_react17 = require("react");
3280
3293
  var useCapture3DS = (searchParams) => {
3281
3294
  (0, import_react17.useEffect)(() => {
3282
- if (window?.parent && searchParams?.paymentIntent) {
3295
+ if (typeof window !== "undefined" && window.parent && searchParams?.paymentIntent) {
3283
3296
  window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
3284
3297
  }
3285
3298
  }, [searchParams]);
3286
3299
  };
3287
3300
  // Annotate the CommonJS export names for ESM import in node:
3288
3301
  0 && (module.exports = {
3302
+ PaymentType,
3289
3303
  SpreePay,
3290
3304
  SpreePayProvider,
3291
3305
  useCapture3DS,
package/build/index.css CHANGED
@@ -438,6 +438,9 @@
438
438
  .sl-spreepay .max-w-\[100px\] {
439
439
  max-width: 100px;
440
440
  }
441
+ .sl-spreepay .max-w-\[540px\] {
442
+ max-width: 540px;
443
+ }
441
444
  .sl-spreepay .max-w-\[680px\] {
442
445
  max-width: 680px;
443
446
  }
@@ -1614,7 +1617,7 @@
1614
1617
  --card-foreground: oklch(0.145 0 0);
1615
1618
  --popover: oklch(1 0 0);
1616
1619
  --popover-foreground: oklch(0.145 0 0);
1617
- --primary: oklch(0.205 0 0);
1620
+ --primary: #022664;
1618
1621
  --primary-foreground: oklch(0.985 0 0);
1619
1622
  --secondary: oklch(0.97 0 0);
1620
1623
  --secondary-foreground: oklch(0.205 0 0);
@@ -1689,9 +1692,6 @@
1689
1692
  cursor: pointer;
1690
1693
  }
1691
1694
  }
1692
- .sl-spreepay {
1693
- --primary: #022664;
1694
- }
1695
1695
  .sl-spreepay .sl-spreepay__portal {
1696
1696
  position: relative;
1697
1697
  }
package/build/index.d.cts CHANGED
@@ -72,7 +72,7 @@ type NewCard = Pick<Card, 'expireMonth' | 'expireYear' | 'lastFourNumbers' | 'sc
72
72
  };
73
73
  type CardPaymentMethod = {
74
74
  method: NewCard | Card | null;
75
- type: PaymentType.CREDIT_CARD | PaymentType.SPLIT;
75
+ type: PaymentType.CREDIT_CARD;
76
76
  splitAmount?: number;
77
77
  };
78
78
  type CryptoPaymentMethod = {
@@ -84,7 +84,8 @@ type SelectedPaymentMethod = CardPaymentMethod | CryptoPaymentMethod;
84
84
  declare enum PaymentType {
85
85
  CREDIT_CARD = "CREDIT_CARD",
86
86
  CRYPTO = "CRYPTO",
87
- SPLIT = "SPLIT"
87
+ SPLIT = "SPLIT",
88
+ POINTS = "POINTS"
88
89
  }
89
90
  declare const enum SlapiPaymentStatus {
90
91
  NOT_INITIALIZED = "NOT_INITIALIZED",// back-end only
@@ -132,4 +133,4 @@ declare global {
132
133
  }
133
134
  }
134
135
 
135
- export { SpreePay, SpreePayProvider, useCapture3DS, useSpreePay };
136
+ export { type ENV, type PaymentMethodResult, PaymentType, type ProcessFn, type ProcessFnParams, type SelectedPaymentMethod, SlapiPaymentStatus, SpreePay, type SpreePayProps, SpreePayProvider, useCapture3DS, useSpreePay };
package/build/index.d.ts CHANGED
@@ -72,7 +72,7 @@ type NewCard = Pick<Card, 'expireMonth' | 'expireYear' | 'lastFourNumbers' | 'sc
72
72
  };
73
73
  type CardPaymentMethod = {
74
74
  method: NewCard | Card | null;
75
- type: PaymentType.CREDIT_CARD | PaymentType.SPLIT;
75
+ type: PaymentType.CREDIT_CARD;
76
76
  splitAmount?: number;
77
77
  };
78
78
  type CryptoPaymentMethod = {
@@ -84,7 +84,8 @@ type SelectedPaymentMethod = CardPaymentMethod | CryptoPaymentMethod;
84
84
  declare enum PaymentType {
85
85
  CREDIT_CARD = "CREDIT_CARD",
86
86
  CRYPTO = "CRYPTO",
87
- SPLIT = "SPLIT"
87
+ SPLIT = "SPLIT",
88
+ POINTS = "POINTS"
88
89
  }
89
90
  declare const enum SlapiPaymentStatus {
90
91
  NOT_INITIALIZED = "NOT_INITIALIZED",// back-end only
@@ -132,4 +133,4 @@ declare global {
132
133
  }
133
134
  }
134
135
 
135
- export { SpreePay, SpreePayProvider, useCapture3DS, useSpreePay };
136
+ export { type ENV, type PaymentMethodResult, PaymentType, type ProcessFn, type ProcessFnParams, type SelectedPaymentMethod, SlapiPaymentStatus, SpreePay, type SpreePayProps, SpreePayProvider, useCapture3DS, useSpreePay };
package/build/index.js CHANGED
@@ -18,6 +18,15 @@ var PaymentError = class extends Error {
18
18
  }
19
19
  };
20
20
 
21
+ // src/types/payments.ts
22
+ var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
23
+ PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
24
+ PaymentType2["CRYPTO"] = "CRYPTO";
25
+ PaymentType2["SPLIT"] = "SPLIT";
26
+ PaymentType2["POINTS"] = "POINTS";
27
+ return PaymentType2;
28
+ })(PaymentType || {});
29
+
21
30
  // src/context/SpreePayActionsContext.tsx
22
31
  import { jsx } from "react/jsx-runtime";
23
32
  var SpreePayActionsContext = createContext(void 0);
@@ -91,15 +100,15 @@ var CONFIG = {
91
100
  dev: {
92
101
  bookit: {
93
102
  slapiUrl: "https://slapi.dev.superlogic.com",
94
- keyklockUrl: "https://auth.dev.join.bookit.com",
95
- keyklockClientId: "oneof-next",
103
+ keycloakUrl: "https://auth.dev.join.bookit.com",
104
+ keycloakClientId: "oneof-next",
96
105
  pointsConversionRatio: 100,
97
106
  pointsTitle: "AIR SP"
98
107
  },
99
108
  moca: {
100
109
  slapiUrl: "https://slapi.dev.air.shop",
101
- keyklockUrl: "https://login.dev.air.shop",
102
- keyklockClientId: "oneof-next",
110
+ keycloakUrl: "https://login.dev.air.shop",
111
+ keycloakClientId: "oneof-next",
103
112
  pointsConversionRatio: 100,
104
113
  pointsTitle: "AIR SP"
105
114
  }
@@ -107,15 +116,15 @@ var CONFIG = {
107
116
  stg: {
108
117
  bookit: {
109
118
  slapiUrl: "https://slapi.stg.superlogic.com",
110
- keyklockUrl: "https://auth.stg.join.bookit.com",
111
- keyklockClientId: "oneof-next",
119
+ keycloakUrl: "https://auth.stg.join.bookit.com",
120
+ keycloakClientId: "oneof-next",
112
121
  pointsConversionRatio: 100,
113
122
  pointsTitle: "AIR SP"
114
123
  },
115
124
  moca: {
116
125
  slapiUrl: "https://slapi.stg.air.shop",
117
- keyklockUrl: "https://login.stg.air.shop",
118
- keyklockClientId: "oneof-next",
126
+ keycloakUrl: "https://login.stg.air.shop",
127
+ keycloakClientId: "oneof-next",
119
128
  pointsConversionRatio: 100,
120
129
  pointsTitle: "AIR SP"
121
130
  }
@@ -123,15 +132,15 @@ var CONFIG = {
123
132
  prod: {
124
133
  bookit: {
125
134
  slapiUrl: "https://slapi.superlogic.com",
126
- keyklockUrl: "https://auth.join.bookit.com",
127
- keyklockClientId: "oneof-next",
135
+ keycloakUrl: "https://auth.join.bookit.com",
136
+ keycloakClientId: "oneof-next",
128
137
  pointsConversionRatio: 100,
129
138
  pointsTitle: "AIR SP"
130
139
  },
131
140
  moca: {
132
141
  slapiUrl: "https://slapi.air.shop",
133
- keyklockUrl: "https://login.air.shop",
134
- keyklockClientId: "oneof-next",
142
+ keycloakUrl: "https://login.air.shop",
143
+ keycloakClientId: "oneof-next",
135
144
  pointsConversionRatio: 100,
136
145
  pointsTitle: "AIR SP"
137
146
  }
@@ -145,7 +154,9 @@ var StaticConfigProvider = ({ children, props }) => {
145
154
  setAppProps(props);
146
155
  }, [props]);
147
156
  const staticConfig = useMemo(() => {
148
- return CONFIG[env.environment][env.tenantId];
157
+ const envConfig = CONFIG[env.environment];
158
+ const appKey = env.tenantId in envConfig ? env.tenantId : "moca";
159
+ return envConfig[appKey];
149
160
  }, [env.environment, env.tenantId]);
150
161
  return /* @__PURE__ */ jsx2(StaticConfigContext.Provider, { value: { staticConfig, appProps }, children });
151
162
  };
@@ -600,7 +611,7 @@ var SlapiPaymentService = {
600
611
  return slapiApi.post("/v1/payments/validate", { paymentId, type: "CREDIT_CARD" /* CREDIT_CARD */ }).then((data) => ({ data }));
601
612
  },
602
613
  validatePoints: ({ paymentId, txHash }) => {
603
- return slapiApi.post("/v1/payments/validate", { txHash, paymentId, type: "SPLIT" /* SPLIT */ }).then((data) => ({ data }));
614
+ return slapiApi.post("/v1/payments/validate", { txHash, paymentId, type: "POINTS" /* POINTS */ }).then((data) => ({ data }));
604
615
  },
605
616
  getStatus: (paymentId) => {
606
617
  return slapiApi.get(`/v1/payments/${paymentId}/status`);
@@ -2341,6 +2352,7 @@ var Points = () => {
2341
2352
  const [usePoints, setUsePoints] = useState10(false);
2342
2353
  const [selectedPointsType, setSelectedPointsType] = useState10(null);
2343
2354
  const { setSelectedPaymentMethod, selectedPaymentMethod } = useSpreePaymentMethod();
2355
+ const { spreePayConfig } = useSpreePayConfig();
2344
2356
  const handleTogglePoints = (enabled) => {
2345
2357
  setUsePoints(enabled);
2346
2358
  if (!enabled) {
@@ -2349,7 +2361,7 @@ var Points = () => {
2349
2361
  }
2350
2362
  };
2351
2363
  return /* @__PURE__ */ jsxs14(Fragment3, { children: [
2352
- /* @__PURE__ */ jsx26(PointsSwitch, { value: usePoints, onChange: handleTogglePoints }),
2364
+ /* @__PURE__ */ jsx26(PointsSwitch, { disabled: !spreePayConfig?.creditCard.enabled, value: usePoints, onChange: handleTogglePoints }),
2353
2365
  usePoints && /* @__PURE__ */ jsx26(SplitBlock, { isSelected: selectedPointsType === "air", onSelect: setSelectedPointsType })
2354
2366
  ] });
2355
2367
  };
@@ -3192,8 +3204,8 @@ var SpreePayInner = () => {
3192
3204
  const tenantId = env?.tenantId || "bookit";
3193
3205
  const { isChecking, accessToken } = useKeycloakSSO({
3194
3206
  realm: tenantId,
3195
- url: staticConfig.keyklockUrl,
3196
- clientId: staticConfig.keyklockClientId,
3207
+ url: staticConfig.keycloakUrl,
3208
+ clientId: staticConfig.keycloakClientId,
3197
3209
  ssoPageURI: env?.ssoPageURI,
3198
3210
  enabled: !env?.accessToken
3199
3211
  });
@@ -3240,12 +3252,13 @@ var SpreePay = (props) => {
3240
3252
  import { useEffect as useEffect11 } from "react";
3241
3253
  var useCapture3DS = (searchParams) => {
3242
3254
  useEffect11(() => {
3243
- if (window?.parent && searchParams?.paymentIntent) {
3255
+ if (typeof window !== "undefined" && window.parent && searchParams?.paymentIntent) {
3244
3256
  window.parent.SP_EVENT_BUS?.emit("paymentIntent", { paymentIntent: searchParams.paymentIntent });
3245
3257
  }
3246
3258
  }, [searchParams]);
3247
3259
  };
3248
3260
  export {
3261
+ PaymentType,
3249
3262
  SpreePay,
3250
3263
  SpreePayProvider,
3251
3264
  useCapture3DS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superlogic/spree-pay",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "Spree-pay React component and utilities",
5
5
  "private": false,
6
6
  "type": "module",