@flopay/shared 0.1.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,147 @@
1
+ # @flopay/shared
2
+
3
+ Shared types, error classes, constants, and validation helpers used across all FloPay packages. This package contains no runtime logic beyond error factories and validation functions -- it is primarily a type/constant library.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @flopay/shared
9
+ ```
10
+
11
+ Within the monorepo, packages depend on it via `workspace:*`.
12
+
13
+ ## Quick Start
14
+
15
+ ### Environment Configuration
16
+
17
+ ```ts
18
+ import { configureFlopay } from '@flopay/shared';
19
+
20
+ // Call once at app startup — determines which billing API URL is used
21
+ configureFlopay({ environment: 'production' }); // or 'staging'
22
+
23
+ // Or set NEXT_PUBLIC_FLOPAY_ENV=production in your .env file (no code needed)
24
+ ```
25
+
26
+ ### Resolve Billing API URL
27
+
28
+ ```ts
29
+ import { resolveBillingApiUrl } from '@flopay/shared';
30
+
31
+ // Reads from: explicit param → env var → configureFlopay() → staging fallback
32
+ const url = resolveBillingApiUrl();
33
+ ```
34
+
35
+ ### Other Imports
36
+
37
+ ```ts
38
+ import {
39
+ FloPayError,
40
+ validationError,
41
+ SDK_VERSION,
42
+ DEFAULT_APPEARANCE,
43
+ NIGHT_APPEARANCE,
44
+ CURRENCY_MAP,
45
+ getCurrencyByCountry,
46
+ isValidPublishableKey,
47
+ } from '@flopay/shared';
48
+
49
+ import type {
50
+ FloPayConfig,
51
+ FloPayEnvironment,
52
+ CheckoutSession,
53
+ PaymentResult,
54
+ PaymentProviderAdapter,
55
+ ElementType,
56
+ FloPayAppearance,
57
+ } from '@flopay/shared';
58
+
59
+ // Validate a key
60
+ isValidPublishableKey('pk_test_abc123'); // true
61
+
62
+ // Look up currency by country
63
+ const info = getCurrencyByCountry('DE');
64
+ // { currency: 'EUR', symbol: '\u20ac', country: 'Germany', countryCode: 'DE', tax: 1 }
65
+
66
+ // Create a structured error
67
+ throw validationError('Email is required', 'email');
68
+ ```
69
+
70
+ ## API Reference
71
+
72
+ ### Types
73
+
74
+ | Type | Description |
75
+ |------|-------------|
76
+ | `FloPayConfig` | Top-level config: `publishableKey`, `locale?`, `appearance?`, `apiVersion?` |
77
+ | `FloPayAppearance` | Theme config: `theme` (`'default'`/`'flat'`/`'night'`/`'none'`), `variables?`, `rules?` |
78
+ | `FloPayThemeVariables` | CSS custom property overrides: `colorPrimary`, `colorBackground`, `colorText`, `colorDanger`, `borderRadius`, `fontFamily`, `fontSizeBase`, `spacingUnit` |
79
+ | `CheckoutMode` | Checkout mode: `'full'` / `'auto'` / `'confirm'` |
80
+ | `CheckoutSession` | Session object: `id`, `clientSecret`, `mode`, `status`, `amount`, `currency`, `customer?`, `checkoutMode?`, `items?`, `subscriptions?`, `successUrl?`, `cancelUrl?`, `coupons?`, `gateway?`, `accountData?`, `tagsData?` |
81
+ | `CheckoutSessionItem` | Session item from billing API: `uuid`, `providerItemId`, `providerItemName`, `quantity`, `totalAmount`, `overrideAmount`, `currency` |
82
+ | `CheckoutSessionSubscription` | Session subscription from billing API: `uuid`, `providerPlanId`, `providerPlanName`, `quantity`, `totalAmount`, `overrideAmount`, `currency` |
83
+ | `PaymentResult` | Payment outcome: `status` (`'succeeded'`/`'processing'`/`'requires_action'`/`'failed'`), `paymentIntentId?`, `error?` |
84
+ | `ConfirmPaymentParams` | `clientSecret`, `returnUrl?` |
85
+ | `CreatePaymentMethodResult` | `paymentMethodId`, `error?` |
86
+ | `ConfirmCardPaymentParams` | `clientSecret`, `paymentMethodId` |
87
+ | `ConfirmCardPaymentResult` | `status`, `paymentIntentId?`, `paymentMethodId?`, `error?` |
88
+ | `ElementType` | `'payment'` / `'card'` / `'cardNumber'` / `'cardExpiry'` / `'cardCvc'` / `'address'` |
89
+ | `ElementOptions` | Options for creating elements: `appearance?`, `clientSecret?`, `amount?`, `currency?`, `paymentMethodCreation?`, `layout?`, `defaultValues?`, `readOnly?`, `mode?` |
90
+ | `MountedElement` | Runtime element: `mount()`, `unmount()`, `update()`, `on()`, `off()`, `destroy()` |
91
+ | `PaymentProviderAdapter` | Provider interface: `initialize()`, `createElement()`, `getElement()`, `submitElements()`, `createPaymentMethod()`, `confirmCardPayment()`, `confirmPayment()`, `confirmPayPalPayment()`, `resumePayPalPayment()`, `getRawProvider()`, `createPayPalElements()`, `destroy()` |
92
+ | `ElementChangeEvent` | Change event: `elementType`, `complete`, `empty`, `error?`, `value?` |
93
+ | `Customer` | `id`, `email`, `firstName?`, `lastName?`, `gender?`, `city?`, `state?`, `country?`, `zip?` |
94
+ | `LineItem` | `price?`, `priceData?`, `quantity` |
95
+ | `PriceData` | `currency`, `unitAmount`, `productData`, `recurring?` |
96
+ | `RecurringInterval` | `interval` (`'month'`/`'year'`), `intervalCount?` |
97
+ | `BillingProvider` | `'recurly'` / `'chargebee'` / `'stripe'` |
98
+ | `TokenizedBody` | `id?`, `type?`, `threeDSecureActionResultTokenId?`, `isPaypal?` |
99
+ | `NormalizedCheckoutSession` | Provider-agnostic session: `provider`, `mode`, `data`, `raw?` |
100
+ | `CheckoutModeKind` | `'tokenize'` / `'redirect'` |
101
+ | `CreateSessionParams` | Full session creation params: `billingApiUrl`, `checkoutBaseUrl`, `clientId`, `items?`, `subscriptions?`, `account`, `successUrl`, `cancelUrl`, `checkoutMode?`, `couponCodes?`, `tagsData?`, `redirectParams?`, `setCookie?`, `timeoutMs?`, `utmMetadata?` |
102
+ | `CheckoutSessionResult` | `{ status: 201; redirectUrl }` / `{ status: 204 }` / `{ status: number }` |
103
+ | `CheckoutItem` | `providerItemId`, `providerItemName?`, `quantity?`, `totalAmount`, `overrideAmount?`, `currency?` |
104
+ | `CheckoutSubscription` | `providerPlanId`, `providerPlanName?`, `quantity?`, `totalAmount`, `overrideAmount?`, `currency?` |
105
+ | `CheckoutAccount` | `userId`, `firstName?`, `lastName?`, `email`, `country?`, `gender?`, `city?`, `state?`, `zip?` |
106
+ | `ProcessPaymentParams` | `sessionId`, `tokenizedData?`, `accountData`, `chv?` |
107
+ | `CreateCustomerParams` | `email`, `name?`, `metadata?` |
108
+ | `UpdateCustomerParams` | `email?`, `name?`, `metadata?` |
109
+ | `WebhookEvent` | `id`, `type`, `data`, `created` |
110
+ | `CurrencyInfo` | `currency`, `symbol`, `country`, `countryCode`, `tax` |
111
+ | `CountryOption` | `code`, `name`, `flag` |
112
+ | `TagsData` | `googleContainerId?`, `sessionId?`, `testEventCode?` |
113
+
114
+ ### Error Classes
115
+
116
+ | Export | Description |
117
+ |--------|-------------|
118
+ | `FloPayError` | Custom error class with `type`, `code?`, `declineCode?`, `param?` |
119
+ | `FloPayErrorType` | `'validation_error'` / `'api_error'` / `'authentication_error'` / `'rate_limit_error'` / `'network_error'` |
120
+ | `validationError(message, param?)` | Factory for validation errors |
121
+ | `apiError(message, code?)` | Factory for API errors |
122
+ | `authenticationError(message)` | Factory for auth errors |
123
+ | `rateLimitError(message)` | Factory for rate limit errors |
124
+ | `networkError(message)` | Factory for network errors |
125
+
126
+ ### Constants
127
+
128
+ | Export | Description |
129
+ |--------|-------------|
130
+ | `SDK_VERSION` | Current SDK version (`'0.1.0'`) |
131
+ | `DEFAULT_API_BASE_URL` | `'https://api.flopay.io'` |
132
+ | `DEFAULT_API_VERSION` | `'2024-01-01'` |
133
+ | `DEFAULT_APPEARANCE` | Default theme (primary `#4A49FF`, white background, Poppins font) |
134
+ | `FLAT_APPEARANCE` | Flat theme (minimal borders, 4px radius) |
135
+ | `NIGHT_APPEARANCE` | Dark theme (dark background `#1A1A2E`, light text) |
136
+ | `ELEMENT_TYPES` | `['payment', 'card', 'cardNumber', 'cardExpiry', 'cardCvc', 'address']` |
137
+ | `SUPPORTED_CARD_BRANDS` | `['visa', 'mastercard', 'mastercard_debit', 'amex', 'discover']` |
138
+ | `CURRENCY_MAP` | Country code to `CurrencyInfo` mapping (EU, GB, US, CA, NZ, AU) |
139
+ | `DEFAULT_CURRENCY` | USD fallback |
140
+
141
+ ### Validation Helpers
142
+
143
+ | Export | Description |
144
+ |--------|-------------|
145
+ | `getCurrencyByCountry(countryCode)` | Returns `CurrencyInfo` for a country code, falls back to USD |
146
+ | `isValidPublishableKey(key)` | Returns `true` if the key matches `pk_(test|live)_...` |
147
+ | `isValidSecretKey(key)` | Returns `true` if the key matches `sk_(test|live)_...` |
package/dist/index.cjs ADDED
@@ -0,0 +1,307 @@
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
+ BILLING_API_URL: () => BILLING_API_URL,
24
+ BILLING_API_URL_PRODUCTION: () => BILLING_API_URL_PRODUCTION,
25
+ BILLING_API_URL_STAGING: () => BILLING_API_URL_STAGING,
26
+ CURRENCY_MAP: () => CURRENCY_MAP,
27
+ DEFAULT_API_BASE_URL: () => DEFAULT_API_BASE_URL,
28
+ DEFAULT_API_VERSION: () => DEFAULT_API_VERSION,
29
+ DEFAULT_APPEARANCE: () => DEFAULT_APPEARANCE,
30
+ DEFAULT_CURRENCY: () => DEFAULT_CURRENCY,
31
+ ELEMENT_TYPES: () => ELEMENT_TYPES,
32
+ FLAT_APPEARANCE: () => FLAT_APPEARANCE,
33
+ FloPayError: () => FloPayError,
34
+ NIGHT_APPEARANCE: () => NIGHT_APPEARANCE,
35
+ SDK_VERSION: () => SDK_VERSION,
36
+ SUPPORTED_CARD_BRANDS: () => SUPPORTED_CARD_BRANDS,
37
+ apiError: () => apiError,
38
+ authenticationError: () => authenticationError,
39
+ buildCheckoutDisplayData: () => buildCheckoutDisplayData,
40
+ configureFlopay: () => configureFlopay,
41
+ getConfiguredBillingApiUrl: () => getConfiguredBillingApiUrl,
42
+ getCurrencyByCountry: () => getCurrencyByCountry,
43
+ getFloPayEnvironment: () => getFloPayEnvironment,
44
+ isValidPublishableKey: () => isValidPublishableKey,
45
+ isValidSecretKey: () => isValidSecretKey,
46
+ networkError: () => networkError,
47
+ rateLimitError: () => rateLimitError,
48
+ resolveBillingApiUrl: () => resolveBillingApiUrl,
49
+ validationError: () => validationError
50
+ });
51
+ module.exports = __toCommonJS(index_exports);
52
+
53
+ // src/errors.ts
54
+ var FloPayError = class extends Error {
55
+ constructor(message, type, options) {
56
+ super(message);
57
+ this.name = "FloPayError";
58
+ this.type = type;
59
+ this.code = options?.code;
60
+ this.declineCode = options?.declineCode;
61
+ this.param = options?.param;
62
+ Object.setPrototypeOf(this, new.target.prototype);
63
+ }
64
+ };
65
+ function validationError(message, param) {
66
+ return new FloPayError(message, "validation_error", { param });
67
+ }
68
+ function apiError(message, code) {
69
+ return new FloPayError(message, "api_error", { code });
70
+ }
71
+ function authenticationError(message) {
72
+ return new FloPayError(message, "authentication_error");
73
+ }
74
+ function rateLimitError(message) {
75
+ return new FloPayError(message, "rate_limit_error");
76
+ }
77
+ function networkError(message) {
78
+ return new FloPayError(message, "network_error");
79
+ }
80
+
81
+ // src/config.ts
82
+ var ENV_URL_MAP = {
83
+ staging: "https://api.stage.flopay.com",
84
+ production: "https://api.flopay.com"
85
+ };
86
+ var globalEnvironment = "staging";
87
+ function configureFlopay(config) {
88
+ globalEnvironment = config.environment;
89
+ }
90
+ function getConfiguredBillingApiUrl() {
91
+ return ENV_URL_MAP[globalEnvironment];
92
+ }
93
+ function getFloPayEnvironment() {
94
+ return globalEnvironment;
95
+ }
96
+
97
+ // src/constants.ts
98
+ var SDK_VERSION = "0.1.0";
99
+ var BILLING_API_URL_STAGING = "https://api.stage.flopay.com";
100
+ var BILLING_API_URL_PRODUCTION = "https://api.flopay.com";
101
+ var DEFAULT_API_BASE_URL = BILLING_API_URL_STAGING;
102
+ var BILLING_API_URL = BILLING_API_URL_STAGING;
103
+ function resolveBillingApiUrl(billingApiUrl) {
104
+ if (billingApiUrl) return billingApiUrl;
105
+ if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_FLOPAY_ENV) {
106
+ const env = process.env.NEXT_PUBLIC_FLOPAY_ENV;
107
+ if (env === "production") return BILLING_API_URL_PRODUCTION;
108
+ return BILLING_API_URL_STAGING;
109
+ }
110
+ return getConfiguredBillingApiUrl();
111
+ }
112
+ var DEFAULT_API_VERSION = "2024-01-01";
113
+ var DEFAULT_APPEARANCE = {
114
+ theme: "default",
115
+ variables: {
116
+ colorPrimary: "#4A49FF",
117
+ colorBackground: "#FFFFFF",
118
+ colorText: "#262833",
119
+ colorDanger: "#DF1B41",
120
+ borderRadius: "8px",
121
+ fontFamily: "Poppins, system-ui, sans-serif",
122
+ fontSizeBase: "16px",
123
+ spacingUnit: "4px"
124
+ }
125
+ };
126
+ var FLAT_APPEARANCE = {
127
+ theme: "flat",
128
+ variables: {
129
+ ...DEFAULT_APPEARANCE.variables,
130
+ borderRadius: "4px"
131
+ }
132
+ };
133
+ var NIGHT_APPEARANCE = {
134
+ theme: "night",
135
+ variables: {
136
+ colorPrimary: "#7B7BFF",
137
+ colorBackground: "#1A1A2E",
138
+ colorText: "#E0E0E0",
139
+ colorDanger: "#FF6B6B",
140
+ borderRadius: "8px",
141
+ fontFamily: "Poppins, system-ui, sans-serif",
142
+ fontSizeBase: "16px",
143
+ spacingUnit: "4px"
144
+ }
145
+ };
146
+ var ELEMENT_TYPES = [
147
+ "payment",
148
+ "card",
149
+ "cardNumber",
150
+ "cardExpiry",
151
+ "cardCvc",
152
+ "address"
153
+ ];
154
+ var SUPPORTED_CARD_BRANDS = [
155
+ "visa",
156
+ "mastercard",
157
+ "mastercard_debit",
158
+ "amex",
159
+ "discover"
160
+ ];
161
+ var CURRENCY_MAP = {
162
+ // EUR (VAT applies)
163
+ AT: { currency: "EUR", symbol: "\u20AC", country: "Austria", countryCode: "AT", tax: 1 },
164
+ BE: { currency: "EUR", symbol: "\u20AC", country: "Belgium", countryCode: "BE", tax: 1 },
165
+ CY: { currency: "EUR", symbol: "\u20AC", country: "Cyprus", countryCode: "CY", tax: 1 },
166
+ DE: { currency: "EUR", symbol: "\u20AC", country: "Germany", countryCode: "DE", tax: 1 },
167
+ EE: { currency: "EUR", symbol: "\u20AC", country: "Estonia", countryCode: "EE", tax: 1 },
168
+ ES: { currency: "EUR", symbol: "\u20AC", country: "Spain", countryCode: "ES", tax: 1 },
169
+ FI: { currency: "EUR", symbol: "\u20AC", country: "Finland", countryCode: "FI", tax: 1 },
170
+ FR: { currency: "EUR", symbol: "\u20AC", country: "France", countryCode: "FR", tax: 1 },
171
+ GR: { currency: "EUR", symbol: "\u20AC", country: "Greece", countryCode: "GR", tax: 1 },
172
+ HR: { currency: "EUR", symbol: "\u20AC", country: "Croatia", countryCode: "HR", tax: 1 },
173
+ IE: { currency: "EUR", symbol: "\u20AC", country: "Ireland", countryCode: "IE", tax: 1 },
174
+ IT: { currency: "EUR", symbol: "\u20AC", country: "Italy", countryCode: "IT", tax: 1 },
175
+ LT: { currency: "EUR", symbol: "\u20AC", country: "Lithuania", countryCode: "LT", tax: 1 },
176
+ LU: { currency: "EUR", symbol: "\u20AC", country: "Luxembourg", countryCode: "LU", tax: 1 },
177
+ LV: { currency: "EUR", symbol: "\u20AC", country: "Latvia", countryCode: "LV", tax: 1 },
178
+ MT: { currency: "EUR", symbol: "\u20AC", country: "Malta", countryCode: "MT", tax: 1 },
179
+ NL: { currency: "EUR", symbol: "\u20AC", country: "Netherlands", countryCode: "NL", tax: 1 },
180
+ PT: { currency: "EUR", symbol: "\u20AC", country: "Portugal", countryCode: "PT", tax: 1 },
181
+ SI: { currency: "EUR", symbol: "\u20AC", country: "Slovenia", countryCode: "SI", tax: 1 },
182
+ SK: { currency: "EUR", symbol: "\u20AC", country: "Slovakia", countryCode: "SK", tax: 1 },
183
+ BG: { currency: "EUR", symbol: "\u20AC", country: "Bulgaria", countryCode: "BG", tax: 1 },
184
+ RO: { currency: "EUR", symbol: "\u20AC", country: "Romania", countryCode: "RO", tax: 1 },
185
+ CZ: { currency: "EUR", symbol: "\u20AC", country: "Czech Republic", countryCode: "CZ", tax: 1 },
186
+ SE: { currency: "EUR", symbol: "\u20AC", country: "Sweden", countryCode: "SE", tax: 1 },
187
+ DK: { currency: "EUR", symbol: "\u20AC", country: "Denmark", countryCode: "DK", tax: 1 },
188
+ PL: { currency: "EUR", symbol: "\u20AC", country: "Poland", countryCode: "PL", tax: 1 },
189
+ HU: { currency: "EUR", symbol: "\u20AC", country: "Hungary", countryCode: "HU", tax: 1 },
190
+ // GBP (VAT applies)
191
+ GB: { currency: "GBP", symbol: "\xA3", country: "United Kingdom", countryCode: "GB", tax: 1 },
192
+ // USD (no VAT)
193
+ US: { currency: "USD", symbol: "$", country: "United States", countryCode: "US", tax: 0 },
194
+ // CAD (no VAT)
195
+ CA: { currency: "CAD", symbol: "CA$", country: "Canada", countryCode: "CA", tax: 0 },
196
+ // NZD (no VAT)
197
+ NZ: { currency: "NZD", symbol: "NZ$", country: "New Zealand", countryCode: "NZ", tax: 0 },
198
+ // AUD (no VAT)
199
+ AU: { currency: "AUD", symbol: "AU$", country: "Australia", countryCode: "AU", tax: 0 }
200
+ };
201
+ var DEFAULT_CURRENCY = {
202
+ currency: "USD",
203
+ symbol: "$",
204
+ country: "United States",
205
+ countryCode: "US",
206
+ tax: 0
207
+ };
208
+
209
+ // src/display.ts
210
+ function buildCheckoutDisplayData(session) {
211
+ const itemsList = [];
212
+ let currency = "USD";
213
+ const subscriptions = session.subscriptions ?? [];
214
+ const items = session.items ?? [];
215
+ for (const sub of subscriptions) {
216
+ const originalPrice = sub.totalAmount;
217
+ const discountedPrice = sub.overrideAmount ?? originalPrice;
218
+ let name = sub.providerPlanName || "Subscription";
219
+ if (name === "4-WEEK PLAN" && discountedPrice <= 1) {
220
+ name = "7-DAY TRIAL: FULL ACCESS";
221
+ }
222
+ itemsList.push({
223
+ name,
224
+ quantity: sub.quantity,
225
+ price: discountedPrice,
226
+ originalPrice
227
+ });
228
+ if (sub.currency) currency = sub.currency.toUpperCase();
229
+ }
230
+ const hideItems = subscriptions.length > 0 && items.length > 0;
231
+ if (!hideItems) {
232
+ for (const item of items) {
233
+ const originalPrice = item.totalAmount;
234
+ const discountedPrice = item.overrideAmount ?? originalPrice;
235
+ itemsList.push({
236
+ name: item.providerItemName || "Item",
237
+ quantity: item.quantity,
238
+ price: discountedPrice,
239
+ originalPrice
240
+ });
241
+ if (item.currency) currency = item.currency.toUpperCase();
242
+ }
243
+ }
244
+ if (itemsList.length === 0) {
245
+ itemsList.push({
246
+ name: "Purchase",
247
+ quantity: 1,
248
+ price: session.amount / 100,
249
+ originalPrice: session.amount / 100
250
+ });
251
+ currency = session.currency?.toUpperCase() ?? "USD";
252
+ }
253
+ const originalTotal = itemsList.reduce((sum, i) => sum + i.originalPrice * i.quantity, 0);
254
+ const total = itemsList.reduce((sum, i) => sum + i.price * i.quantity, 0);
255
+ const totalSave = Math.max(0, originalTotal - total);
256
+ const discountPercent = originalTotal > 0 ? Math.round(totalSave / originalTotal * 100) : 0;
257
+ return {
258
+ items: itemsList,
259
+ currency,
260
+ total,
261
+ originalTotal,
262
+ totalSave,
263
+ discountPercent
264
+ };
265
+ }
266
+
267
+ // src/validation.ts
268
+ function getCurrencyByCountry(countryCode) {
269
+ return CURRENCY_MAP[countryCode.toUpperCase()] ?? DEFAULT_CURRENCY;
270
+ }
271
+ function isValidPublishableKey(key) {
272
+ return /^pk_(test|live)_[A-Za-z0-9]+$/.test(key);
273
+ }
274
+ function isValidSecretKey(key) {
275
+ return /^sk_(test|live)_[A-Za-z0-9]+$/.test(key);
276
+ }
277
+ // Annotate the CommonJS export names for ESM import in node:
278
+ 0 && (module.exports = {
279
+ BILLING_API_URL,
280
+ BILLING_API_URL_PRODUCTION,
281
+ BILLING_API_URL_STAGING,
282
+ CURRENCY_MAP,
283
+ DEFAULT_API_BASE_URL,
284
+ DEFAULT_API_VERSION,
285
+ DEFAULT_APPEARANCE,
286
+ DEFAULT_CURRENCY,
287
+ ELEMENT_TYPES,
288
+ FLAT_APPEARANCE,
289
+ FloPayError,
290
+ NIGHT_APPEARANCE,
291
+ SDK_VERSION,
292
+ SUPPORTED_CARD_BRANDS,
293
+ apiError,
294
+ authenticationError,
295
+ buildCheckoutDisplayData,
296
+ configureFlopay,
297
+ getConfiguredBillingApiUrl,
298
+ getCurrencyByCountry,
299
+ getFloPayEnvironment,
300
+ isValidPublishableKey,
301
+ isValidSecretKey,
302
+ networkError,
303
+ rateLimitError,
304
+ resolveBillingApiUrl,
305
+ validationError
306
+ });
307
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/config.ts","../src/constants.ts","../src/display.ts","../src/validation.ts"],"sourcesContent":["// Types\nexport type {\n FloPayThemeVariables,\n FloPayAppearance,\n Customer,\n RecurringInterval,\n PriceData,\n LineItem,\n CheckoutMode,\n CheckoutSession,\n CheckoutSessionItem,\n CheckoutSessionSubscription,\n PaymentResult,\n ConfirmPaymentParams,\n CreatePaymentMethodResult,\n ConfirmCardPaymentParams,\n ConfirmCardPaymentResult,\n ElementType,\n ElementChangeEvent,\n ElementOptions,\n MountedElement,\n FloPayConfig,\n PaymentProviderAdapter,\n BillingProvider,\n TokenizedBody,\n CheckoutModeKind,\n NormalizedCheckoutSession,\n CheckoutItem,\n CheckoutSubscription,\n CheckoutAccount,\n TagsData,\n CreateSessionParams,\n CheckoutSessionResult,\n ProcessPaymentParams,\n CreateCustomerParams,\n UpdateCustomerParams,\n WebhookEvent,\n CurrencyInfo,\n CountryOption,\n} from './types.js';\n\n// Errors\nexport {\n FloPayError,\n validationError,\n apiError,\n authenticationError,\n rateLimitError,\n networkError,\n} from './errors.js';\nexport type { FloPayErrorType } from './errors.js';\n\n// Configuration\nexport { configureFlopay, getConfiguredBillingApiUrl, getFloPayEnvironment } from './config.js';\nexport type { FloPayEnvironment } from './config.js';\n\n// Constants\nexport {\n SDK_VERSION,\n DEFAULT_API_BASE_URL,\n DEFAULT_API_VERSION,\n BILLING_API_URL,\n BILLING_API_URL_STAGING,\n BILLING_API_URL_PRODUCTION,\n resolveBillingApiUrl,\n DEFAULT_APPEARANCE,\n FLAT_APPEARANCE,\n NIGHT_APPEARANCE,\n ELEMENT_TYPES,\n SUPPORTED_CARD_BRANDS,\n CURRENCY_MAP,\n DEFAULT_CURRENCY,\n} from './constants.js';\n\n// Display helpers\nexport { buildCheckoutDisplayData } from './display.js';\nexport type { DisplayLineItem, CheckoutDisplayData } from './display.js';\n\n// Validation helpers\nexport {\n getCurrencyByCountry,\n isValidPublishableKey,\n isValidSecretKey,\n} from './validation.js';\n","/** Discriminated error types returned by the FloPay SDK. */\nexport type FloPayErrorType =\n | 'validation_error'\n | 'api_error'\n | 'authentication_error'\n | 'rate_limit_error'\n | 'network_error';\n\n/**\n * Custom error class for all FloPay SDK errors.\n *\n * Extends the native `Error` and adds structured fields that mirror\n * Stripe-style error responses for familiarity.\n */\nexport class FloPayError extends Error {\n readonly type: FloPayErrorType;\n readonly code?: string;\n readonly declineCode?: string;\n readonly param?: string;\n\n constructor(\n message: string,\n type: FloPayErrorType,\n options?: { code?: string; declineCode?: string; param?: string },\n ) {\n super(message);\n this.name = 'FloPayError';\n this.type = type;\n this.code = options?.code;\n this.declineCode = options?.declineCode;\n this.param = options?.param;\n\n // Restore prototype chain (required when extending built-ins)\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Error Factories\n// ---------------------------------------------------------------------------\n\n/** Create a validation error (e.g. missing required field). */\nexport function validationError(\n message: string,\n param?: string,\n): FloPayError {\n return new FloPayError(message, 'validation_error', { param });\n}\n\n/** Create an API error (e.g. upstream provider returned an error). */\nexport function apiError(\n message: string,\n code?: string,\n): FloPayError {\n return new FloPayError(message, 'api_error', { code });\n}\n\n/** Create an authentication error (e.g. invalid publishable key). */\nexport function authenticationError(message: string): FloPayError {\n return new FloPayError(message, 'authentication_error');\n}\n\n/** Create a rate limit error. */\nexport function rateLimitError(message: string): FloPayError {\n return new FloPayError(message, 'rate_limit_error');\n}\n\n/** Create a network error (e.g. fetch failed). */\nexport function networkError(message: string): FloPayError {\n return new FloPayError(message, 'network_error');\n}\n","/** FloPay environment — determines which billing API URL is used. */\nexport type FloPayEnvironment = 'staging' | 'production';\n\nconst ENV_URL_MAP: Record<FloPayEnvironment, string> = {\n staging: 'https://api.stage.flopay.com',\n production: 'https://api.flopay.com',\n};\n\nlet globalEnvironment: FloPayEnvironment = 'staging';\n\n/**\n * Configure the FloPay SDK globally. Call once at app startup.\n *\n * The environment determines which billing API URL is used for all\n * FloPay operations (session creation, payment processing, etc.).\n *\n * @example\n * ```ts\n * import { configureFlopay } from '@flopay/shared';\n *\n * // In production\n * configureFlopay({ environment: 'production' });\n *\n * // In staging/development\n * configureFlopay({ environment: 'staging' });\n * ```\n *\n * Alternatively, set the `NEXT_PUBLIC_FLOPAY_ENV` environment variable\n * to `'staging'` or `'production'` — the SDK reads it automatically.\n */\nexport function configureFlopay(config: { environment: FloPayEnvironment }): void {\n globalEnvironment = config.environment;\n}\n\n/** Get the billing API URL for the currently configured environment. */\nexport function getConfiguredBillingApiUrl(): string {\n return ENV_URL_MAP[globalEnvironment];\n}\n\n/** Get the current configured environment. */\nexport function getFloPayEnvironment(): FloPayEnvironment {\n return globalEnvironment;\n}\n","import type { CurrencyInfo, FloPayAppearance } from './types.js';\nimport type { FloPayEnvironment } from './config.js';\nimport { getConfiguredBillingApiUrl } from './config.js';\n\n// ---------------------------------------------------------------------------\n// SDK Version & API\n// ---------------------------------------------------------------------------\n\n/** Current SDK version. */\nexport const SDK_VERSION = '0.1.0';\n\n/** Billing API URL for staging environment. */\nexport const BILLING_API_URL_STAGING = 'https://api.stage.flopay.com';\n\n/** Billing API URL for production environment. */\nexport const BILLING_API_URL_PRODUCTION = 'https://api.flopay.com';\n\n/** Default FloPay API base URL (used by @flopay/node). Alias for staging. */\nexport const DEFAULT_API_BASE_URL = BILLING_API_URL_STAGING;\n\n/** Default billing API base URL. Alias for staging — prefer `resolveBillingApiUrl()`. */\nexport const BILLING_API_URL = BILLING_API_URL_STAGING;\n\n/**\n * Resolve the billing API URL from available configuration.\n *\n * Priority:\n * 1. Explicit `billingApiUrl` (prop/param override)\n * 2. `NEXT_PUBLIC_FLOPAY_ENV` environment variable (`'staging'` | `'production'`)\n * 3. `configureFlopay()` global environment setting\n * 4. Fallback: staging URL\n *\n * @example\n * ```ts\n * import { resolveBillingApiUrl } from '@flopay/shared';\n *\n * // Reads from env var or configureFlopay() — no args needed\n * const url = resolveBillingApiUrl();\n *\n * // Explicit override takes priority\n * const url = resolveBillingApiUrl('https://custom.example.com');\n * ```\n */\nexport function resolveBillingApiUrl(billingApiUrl?: string): string {\n if (billingApiUrl) return billingApiUrl;\n\n // Environment variable (works in Next.js and bundlers that inline process.env)\n if (typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_FLOPAY_ENV) {\n const env = process.env.NEXT_PUBLIC_FLOPAY_ENV as FloPayEnvironment;\n if (env === 'production') return BILLING_API_URL_PRODUCTION;\n return BILLING_API_URL_STAGING;\n }\n\n // Global config from configureFlopay()\n return getConfiguredBillingApiUrl();\n}\n\n/** Default API version header value. */\nexport const DEFAULT_API_VERSION = '2024-01-01';\n\n// ---------------------------------------------------------------------------\n// Default Themes\n// ---------------------------------------------------------------------------\n\n/** The default appearance applied when no custom appearance is provided. */\nexport const DEFAULT_APPEARANCE: FloPayAppearance = {\n theme: 'default',\n variables: {\n colorPrimary: '#4A49FF',\n colorBackground: '#FFFFFF',\n colorText: '#262833',\n colorDanger: '#DF1B41',\n borderRadius: '8px',\n fontFamily: 'Poppins, system-ui, sans-serif',\n fontSizeBase: '16px',\n spacingUnit: '4px',\n },\n};\n\n/** Flat theme — minimal borders and shadows. */\nexport const FLAT_APPEARANCE: FloPayAppearance = {\n theme: 'flat',\n variables: {\n ...DEFAULT_APPEARANCE.variables,\n borderRadius: '4px',\n },\n};\n\n/** Night theme — dark background. */\nexport const NIGHT_APPEARANCE: FloPayAppearance = {\n theme: 'night',\n variables: {\n colorPrimary: '#7B7BFF',\n colorBackground: '#1A1A2E',\n colorText: '#E0E0E0',\n colorDanger: '#FF6B6B',\n borderRadius: '8px',\n fontFamily: 'Poppins, system-ui, sans-serif',\n fontSizeBase: '16px',\n spacingUnit: '4px',\n },\n};\n\n// ---------------------------------------------------------------------------\n// Supported Element Types\n// ---------------------------------------------------------------------------\n\n/** All supported element type identifiers. */\nexport const ELEMENT_TYPES = [\n 'payment',\n 'card',\n 'cardNumber',\n 'cardExpiry',\n 'cardCvc',\n 'address',\n] as const;\n\n// ---------------------------------------------------------------------------\n// Supported Card Brands\n// ---------------------------------------------------------------------------\n\nexport const SUPPORTED_CARD_BRANDS = [\n 'visa',\n 'mastercard',\n 'mastercard_debit',\n 'amex',\n 'discover',\n] as const;\n\n// ---------------------------------------------------------------------------\n// Currency Mapping (from checkout project)\n// ---------------------------------------------------------------------------\n\n/** Country code to currency information mapping. */\nexport const CURRENCY_MAP: Record<string, CurrencyInfo> = {\n // EUR (VAT applies)\n AT: { currency: 'EUR', symbol: '\\u20AC', country: 'Austria', countryCode: 'AT', tax: 1 },\n BE: { currency: 'EUR', symbol: '\\u20AC', country: 'Belgium', countryCode: 'BE', tax: 1 },\n CY: { currency: 'EUR', symbol: '\\u20AC', country: 'Cyprus', countryCode: 'CY', tax: 1 },\n DE: { currency: 'EUR', symbol: '\\u20AC', country: 'Germany', countryCode: 'DE', tax: 1 },\n EE: { currency: 'EUR', symbol: '\\u20AC', country: 'Estonia', countryCode: 'EE', tax: 1 },\n ES: { currency: 'EUR', symbol: '\\u20AC', country: 'Spain', countryCode: 'ES', tax: 1 },\n FI: { currency: 'EUR', symbol: '\\u20AC', country: 'Finland', countryCode: 'FI', tax: 1 },\n FR: { currency: 'EUR', symbol: '\\u20AC', country: 'France', countryCode: 'FR', tax: 1 },\n GR: { currency: 'EUR', symbol: '\\u20AC', country: 'Greece', countryCode: 'GR', tax: 1 },\n HR: { currency: 'EUR', symbol: '\\u20AC', country: 'Croatia', countryCode: 'HR', tax: 1 },\n IE: { currency: 'EUR', symbol: '\\u20AC', country: 'Ireland', countryCode: 'IE', tax: 1 },\n IT: { currency: 'EUR', symbol: '\\u20AC', country: 'Italy', countryCode: 'IT', tax: 1 },\n LT: { currency: 'EUR', symbol: '\\u20AC', country: 'Lithuania', countryCode: 'LT', tax: 1 },\n LU: { currency: 'EUR', symbol: '\\u20AC', country: 'Luxembourg', countryCode: 'LU', tax: 1 },\n LV: { currency: 'EUR', symbol: '\\u20AC', country: 'Latvia', countryCode: 'LV', tax: 1 },\n MT: { currency: 'EUR', symbol: '\\u20AC', country: 'Malta', countryCode: 'MT', tax: 1 },\n NL: { currency: 'EUR', symbol: '\\u20AC', country: 'Netherlands', countryCode: 'NL', tax: 1 },\n PT: { currency: 'EUR', symbol: '\\u20AC', country: 'Portugal', countryCode: 'PT', tax: 1 },\n SI: { currency: 'EUR', symbol: '\\u20AC', country: 'Slovenia', countryCode: 'SI', tax: 1 },\n SK: { currency: 'EUR', symbol: '\\u20AC', country: 'Slovakia', countryCode: 'SK', tax: 1 },\n BG: { currency: 'EUR', symbol: '\\u20AC', country: 'Bulgaria', countryCode: 'BG', tax: 1 },\n RO: { currency: 'EUR', symbol: '\\u20AC', country: 'Romania', countryCode: 'RO', tax: 1 },\n CZ: { currency: 'EUR', symbol: '\\u20AC', country: 'Czech Republic', countryCode: 'CZ', tax: 1 },\n SE: { currency: 'EUR', symbol: '\\u20AC', country: 'Sweden', countryCode: 'SE', tax: 1 },\n DK: { currency: 'EUR', symbol: '\\u20AC', country: 'Denmark', countryCode: 'DK', tax: 1 },\n PL: { currency: 'EUR', symbol: '\\u20AC', country: 'Poland', countryCode: 'PL', tax: 1 },\n HU: { currency: 'EUR', symbol: '\\u20AC', country: 'Hungary', countryCode: 'HU', tax: 1 },\n // GBP (VAT applies)\n GB: { currency: 'GBP', symbol: '\\u00A3', country: 'United Kingdom', countryCode: 'GB', tax: 1 },\n // USD (no VAT)\n US: { currency: 'USD', symbol: '$', country: 'United States', countryCode: 'US', tax: 0 },\n // CAD (no VAT)\n CA: { currency: 'CAD', symbol: 'CA$', country: 'Canada', countryCode: 'CA', tax: 0 },\n // NZD (no VAT)\n NZ: { currency: 'NZD', symbol: 'NZ$', country: 'New Zealand', countryCode: 'NZ', tax: 0 },\n // AUD (no VAT)\n AU: { currency: 'AUD', symbol: 'AU$', country: 'Australia', countryCode: 'AU', tax: 0 },\n};\n\n/** Default currency info when country is unknown. */\nexport const DEFAULT_CURRENCY: CurrencyInfo = {\n currency: 'USD',\n symbol: '$',\n country: 'United States',\n countryCode: 'US',\n tax: 0,\n};\n","import type { CheckoutSession } from './types.js';\n\n/** A single line item formatted for display in the checkout UI. */\nexport interface DisplayLineItem {\n name: string;\n quantity: number;\n /** Price per unit in the session's currency (major units, e.g. 24.95). */\n price: number;\n /** Original price per unit before any discount (major units). */\n originalPrice: number;\n}\n\n/** Computed display data for rendering an order summary. */\nexport interface CheckoutDisplayData {\n /** Individual items/subscriptions with names, prices, and quantities. */\n items: DisplayLineItem[];\n /** ISO 4217 currency code (uppercase). */\n currency: string;\n /** Total amount due after discounts (major units, e.g. 24.95). */\n total: number;\n /** Sum of original prices before discounts (major units). */\n originalTotal: number;\n /** Total savings (originalTotal - total), clamped to >= 0. */\n totalSave: number;\n /** Discount percentage (0–100). */\n discountPercent: number;\n}\n\n/**\n * Builds display data from a `CheckoutSession` for rendering an order summary.\n *\n * Matches the display logic in checkout/CheckoutModal exactly:\n * - Subscriptions are always shown\n * - Items are hidden when the session has both subscriptions AND items\n * - `overrideAmount` (when not null/undefined) is the discounted price\n * - Plan name \"4-WEEK PLAN\" with price <= 1 is renamed to \"7-DAY TRIAL: FULL ACCESS\"\n * - Discount percentage and savings are computed from the difference\n *\n * All amounts are in **major currency units** (dollars, not cents).\n *\n * @example\n * ```ts\n * import { buildCheckoutDisplayData } from '@flopay/shared';\n *\n * const display = buildCheckoutDisplayData(session);\n * // display.items → [{ name: 'Starter', price: 24.95, originalPrice: 24.95, quantity: 1 }]\n * // display.total → 24.95\n * // display.currency → 'EUR'\n * ```\n */\nexport function buildCheckoutDisplayData(session: CheckoutSession): CheckoutDisplayData {\n const itemsList: DisplayLineItem[] = [];\n let currency = 'USD';\n\n const subscriptions = session.subscriptions ?? [];\n const items = session.items ?? [];\n\n // Subscriptions\n for (const sub of subscriptions) {\n const originalPrice = sub.totalAmount;\n const discountedPrice = sub.overrideAmount ?? originalPrice;\n\n // Match checkout/CheckoutModal: rename \"4-WEEK PLAN\" to \"7-DAY TRIAL: FULL ACCESS\"\n // when the discounted price is $1 or less\n let name = sub.providerPlanName || 'Subscription';\n if (name === '4-WEEK PLAN' && discountedPrice <= 1) {\n name = '7-DAY TRIAL: FULL ACCESS';\n }\n\n itemsList.push({\n name,\n quantity: sub.quantity,\n price: discountedPrice,\n originalPrice,\n });\n\n if (sub.currency) currency = sub.currency.toUpperCase();\n }\n\n // Items — hidden when session has both subscriptions and items\n // (matches checkout/CheckoutModal: hideItems logic)\n const hideItems = subscriptions.length > 0 && items.length > 0;\n\n if (!hideItems) {\n for (const item of items) {\n const originalPrice = item.totalAmount;\n const discountedPrice = item.overrideAmount ?? originalPrice;\n\n itemsList.push({\n name: item.providerItemName || 'Item',\n quantity: item.quantity,\n price: discountedPrice,\n originalPrice,\n });\n\n if (item.currency) currency = item.currency.toUpperCase();\n }\n }\n\n // Fallback if session has no items/subscriptions\n if (itemsList.length === 0) {\n itemsList.push({\n name: 'Purchase',\n quantity: 1,\n price: session.amount / 100,\n originalPrice: session.amount / 100,\n });\n currency = session.currency?.toUpperCase() ?? 'USD';\n }\n\n const originalTotal = itemsList.reduce((sum, i) => sum + i.originalPrice * i.quantity, 0);\n const total = itemsList.reduce((sum, i) => sum + i.price * i.quantity, 0);\n const totalSave = Math.max(0, originalTotal - total);\n const discountPercent = originalTotal > 0\n ? Math.round((totalSave / originalTotal) * 100)\n : 0;\n\n return {\n items: itemsList,\n currency,\n total,\n originalTotal,\n totalSave,\n discountPercent,\n };\n}\n","import type { CurrencyInfo } from './types.js';\nimport { CURRENCY_MAP, DEFAULT_CURRENCY } from './constants.js';\n\n/**\n * Look up currency information by ISO 3166-1 alpha-2 country code.\n * Falls back to USD when the country is not in the map.\n */\nexport function getCurrencyByCountry(countryCode: string): CurrencyInfo {\n return CURRENCY_MAP[countryCode.toUpperCase()] ?? DEFAULT_CURRENCY;\n}\n\n/** Returns `true` if the string looks like a Stripe publishable key. */\nexport function isValidPublishableKey(key: string): boolean {\n return /^pk_(test|live)_[A-Za-z0-9]+$/.test(key);\n}\n\n/** Returns `true` if the string looks like a Stripe secret key. */\nexport function isValidSecretKey(key: string): boolean {\n return /^sk_(test|live)_[A-Za-z0-9]+$/.test(key);\n}\n"],"mappings":"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","names":[]}