@owlmeans/client-payment 0.1.2 → 0.1.4

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.
Files changed (3) hide show
  1. package/README.md +23 -465
  2. package/package.json +6 -5
  3. package/tsconfig.json +6 -11
package/README.md CHANGED
@@ -1,493 +1,51 @@
1
1
  # @owlmeans/client-payment
2
2
 
3
- The **@owlmeans/client-payment** package provides client-side payment functionality for OwlMeans Common Libraries, designed for fullstack microservices and microclients development with focus on security and proper authentication and authorization.
3
+ Client-side payment service integration for the OwlMeans context system.
4
4
 
5
- ## Purpose
5
+ ## Overview
6
6
 
7
- This package serves as the client-side implementation of the OwlMeans payment system that:
7
+ - `makePaymentService(alias?)` — creates a payment service for context registration
8
+ - `appendPaymentService(context, alias?)` — attaches the payment service to an existing context
9
+ - Re-exports `PaymentService` and `DEFAULT_ALIAS` from `@owlmeans/payment`
10
+ - Adds `SHALLOW_AUTH` constant for shallow authentication state tracking
8
11
 
9
- - **Provides client-side payment services** with authentication integration
10
- - **Implements shallow authentication** for payment identification
11
- - **Integrates with client auth resources** for seamless user experience
12
- - **Supports payment profile management** with local caching
13
- - **Offers secure payment processing** with proper error handling
14
- - **Enables payment workflow management** in client applications
12
+ ## Installation
15
13
 
16
- ## Core Concepts
17
-
18
- ### Client Payment Service
19
- A client-side service that extends the base payment service with client-specific functionality, including integration with client authentication resources.
20
-
21
- ### Shallow Authentication
22
- A lightweight authentication mechanism for payment operations that caches payment profile information locally to avoid repeated authentication requests.
23
-
24
- ### Payment Profile Integration
25
- Seamless integration with user authentication to automatically manage payment profiles and user identification for payment operations.
26
-
27
- ### Local Caching
28
- Payment profile information is cached locally using client auth resources to improve performance and user experience.
29
-
30
- ## API Reference
31
-
32
- ### Factory Functions
33
-
34
- #### `makePaymentService(alias?): PaymentService`
35
-
36
- Creates a client-side payment service with enhanced authentication capabilities.
37
-
38
- ```typescript
39
- import { makePaymentService } from '@owlmeans/client-payment'
40
-
41
- const paymentService = makePaymentService('payments')
14
+ ```bash
15
+ bun add @owlmeans/client-payment
42
16
  ```
43
17
 
44
- **Parameters:**
45
- - `alias`: string (optional) - Service alias, defaults to `DEFAULT_ALIAS` from `@owlmeans/payment`
46
-
47
- **Returns:** PaymentService instance with client-side enhancements
48
-
49
- #### `appendPaymentService(context, alias?): Context`
50
-
51
- Registers a payment service with a client context.
18
+ ## Usage
52
19
 
53
20
  ```typescript
54
21
  import { appendPaymentService } from '@owlmeans/client-payment'
55
- import { makeClientContext } from '@owlmeans/client-context'
56
22
 
57
- const context = makeClientContext(config)
58
- appendPaymentService(context, 'payments')
23
+ appendPaymentService(context)
59
24
  ```
60
25
 
61
- **Parameters:**
62
- - `context`: Client context instance
63
- - `alias`: string (optional) - Service alias
64
-
65
- **Returns:** Context with registered payment service
66
-
67
- ### Service Methods
68
-
69
- The client payment service extends the base PaymentService with enhanced authentication:
70
-
71
- #### `shallowAuthentication(token?): Promise<string>`
72
-
73
- Performs lightweight authentication for payment operations with local caching.
26
+ Access the payment service:
74
27
 
75
28
  ```typescript
76
- const paymentService = context.service('payments')
77
-
78
- // First call - authenticates and caches profile
79
- const profileId = await paymentService.shallowAuthentication('auth-token')
29
+ import { DEFAULT_ALIAS } from '@owlmeans/client-payment'
30
+ import type { PaymentService } from '@owlmeans/client-payment'
80
31
 
81
- // Subsequent calls - uses cached profile
82
- const cachedProfileId = await paymentService.shallowAuthentication()
32
+ const paymentService = context.service<PaymentService>(DEFAULT_ALIAS)
83
33
  ```
84
34
 
85
- **Parameters:**
86
- - `token`: string (optional) - Authentication token for initial authentication
87
-
88
- **Returns:** Promise resolving to payment profile ID
89
-
90
- **Behavior:**
91
- - If `token` is provided: Authenticates using the token and caches the result
92
- - If `token` is null: Attempts to use cached authentication data
93
- - Throws `PaymentIdentificationError` if no cached data exists and no token provided
94
-
95
- ### Types
96
-
97
- #### `PaymentService`
98
-
99
- The payment service interface (re-exported from `@owlmeans/payment`).
100
-
101
- ```typescript
102
- export type { PaymentService } from '@owlmeans/payment'
103
- ```
104
-
105
- ### Constants
106
-
107
- #### `DEFAULT_ALIAS`
108
-
109
- Default alias for payment services (re-exported from `@owlmeans/payment`).
110
-
111
- ```typescript
112
- export { DEFAULT_ALIAS } from '@owlmeans/payment'
113
- ```
114
-
115
- #### `SHALLOW_AUTH`
116
-
117
- Local storage key for cached payment authentication data.
118
-
119
- ```typescript
120
- const SHALLOW_AUTH = 'payment:shallow-auth'
121
- ```
122
-
123
- ## Usage Examples
124
-
125
- ### Basic Payment Service Setup
126
-
127
- ```typescript
128
- import { makeClientContext, makeClientConfig } from '@owlmeans/client-context'
129
- import { appendPaymentService } from '@owlmeans/client-payment'
130
- import { AppType } from '@owlmeans/context'
131
-
132
- // Create client context
133
- const config = makeClientConfig(AppType.Frontend, 'ecommerce-app')
134
- const context = makeClientContext(config)
135
-
136
- // Add payment service
137
- appendPaymentService(context, 'payments')
138
-
139
- // Configure and initialize
140
- context.configure()
141
- await context.init()
142
-
143
- // Use payment service
144
- const paymentService = context.service('payments')
145
- ```
146
-
147
- ### Payment with Authentication
148
-
149
- ```typescript
150
- import { makePaymentService } from '@owlmeans/client-payment'
151
- import { PaymentIdentificationError } from '@owlmeans/payment'
152
-
153
- const paymentService = makePaymentService('payments')
154
-
155
- try {
156
- // First-time authentication
157
- const profileId = await paymentService.shallowAuthentication(userAuthToken)
158
- console.log('Payment profile:', profileId)
159
-
160
- // Subsequent calls use cached data
161
- const cachedProfileId = await paymentService.shallowAuthentication()
162
- console.log('Cached profile:', cachedProfileId)
163
-
164
- } catch (error) {
165
- if (error instanceof PaymentIdentificationError) {
166
- console.log('Payment identification failed:', error.message)
167
- // Redirect to authentication
168
- }
169
- }
170
- ```
171
-
172
- ### E-commerce Integration
173
-
174
- ```typescript
175
- import { appendPaymentService } from '@owlmeans/client-payment'
176
-
177
- const setupEcommerceApp = async () => {
178
- const context = makeClientContext(config)
179
-
180
- // Register payment service
181
- appendPaymentService(context, 'checkout')
182
-
183
- await context.configure().init()
184
-
185
- return context
186
- }
187
-
188
- const processCheckout = async (context, items, userToken) => {
189
- const paymentService = context.service('checkout')
190
-
191
- try {
192
- // Authenticate for payment
193
- const profileId = await paymentService.shallowAuthentication(userToken)
194
-
195
- // Process payment
196
- const paymentRequest = {
197
- profileId,
198
- items,
199
- total: items.reduce((sum, item) => sum + item.price, 0)
200
- }
201
-
202
- const result = await paymentService.processPayment(paymentRequest)
203
- return result
204
-
205
- } catch (error) {
206
- console.error('Payment failed:', error)
207
- throw error
208
- }
209
- }
210
- ```
211
-
212
- ### Subscription Service
213
-
214
- ```typescript
215
- import { makePaymentService } from '@owlmeans/client-payment'
216
-
217
- const subscriptionService = makePaymentService('subscriptions')
218
-
219
- const manageSubscription = async (userToken, subscriptionPlan) => {
220
- try {
221
- // Authenticate user for payment
222
- const profileId = await subscriptionService.shallowAuthentication(userToken)
223
-
224
- // Create subscription
225
- const subscription = await subscriptionService.createSubscription({
226
- profileId,
227
- plan: subscriptionPlan,
228
- recurring: true
229
- })
230
-
231
- console.log('Subscription created:', subscription.id)
232
- return subscription
233
-
234
- } catch (error) {
235
- console.error('Subscription failed:', error)
236
- throw error
237
- }
238
- }
239
-
240
- // Later, manage existing subscription without re-authentication
241
- const updateSubscription = async (subscriptionId, newPlan) => {
242
- try {
243
- // Use cached authentication
244
- const profileId = await subscriptionService.shallowAuthentication()
245
-
246
- const updated = await subscriptionService.updateSubscription(subscriptionId, {
247
- plan: newPlan,
248
- profileId
249
- })
250
-
251
- return updated
252
- } catch (error) {
253
- if (error instanceof PaymentIdentificationError) {
254
- // Re-authentication required
255
- console.log('Please re-authenticate for subscription changes')
256
- }
257
- throw error
258
- }
259
- }
260
- ```
261
-
262
- ### Mobile App Integration
263
-
264
- ```typescript
265
- import { appendPaymentService } from '@owlmeans/client-payment'
266
-
267
- const setupMobilePayments = async () => {
268
- const context = makeClientContext(mobileConfig)
269
-
270
- appendPaymentService(context, 'mobile-payments')
271
-
272
- await context.configure().init()
273
-
274
- const paymentService = context.service('mobile-payments')
275
-
276
- // Setup payment handlers for mobile
277
- const handlePurchase = async (productId, userToken) => {
278
- try {
279
- const profileId = await paymentService.shallowAuthentication(userToken)
280
-
281
- const purchase = await paymentService.processMobilePurchase({
282
- profileId,
283
- productId,
284
- platform: 'mobile'
285
- })
286
-
287
- // Handle successful purchase
288
- await unlockPremiumFeatures(purchase)
289
-
290
- } catch (error) {
291
- // Handle payment error
292
- showPaymentError(error)
293
- }
294
- }
295
-
296
- return handlePurchase
297
- }
298
- ```
299
-
300
- ### Payment Status Tracking
301
-
302
- ```typescript
303
- import { makePaymentService } from '@owlmeans/client-payment'
304
-
305
- const paymentService = makePaymentService('payment-tracker')
306
-
307
- const trackPaymentStatus = async (paymentId, userToken) => {
308
- try {
309
- // Authenticate for payment tracking
310
- const profileId = await paymentService.shallowAuthentication(userToken)
311
-
312
- // Poll payment status
313
- const checkStatus = async () => {
314
- const status = await paymentService.getPaymentStatus(paymentId, profileId)
315
-
316
- switch (status.state) {
317
- case 'pending':
318
- console.log('Payment is being processed...')
319
- setTimeout(checkStatus, 5000) // Check again in 5 seconds
320
- break
321
- case 'completed':
322
- console.log('Payment completed successfully!')
323
- handlePaymentSuccess(status)
324
- break
325
- case 'failed':
326
- console.log('Payment failed:', status.error)
327
- handlePaymentFailure(status)
328
- break
329
- }
330
- }
331
-
332
- await checkStatus()
333
-
334
- } catch (error) {
335
- console.error('Payment tracking failed:', error)
336
- }
337
- }
338
- ```
339
-
340
- ### Error Handling
341
-
342
- ```typescript
343
- import { PaymentIdentificationError } from '@owlmeans/payment'
344
- import { makePaymentService } from '@owlmeans/client-payment'
345
-
346
- const handlePaymentErrors = async (userToken, paymentData) => {
347
- const paymentService = makePaymentService('error-handling')
348
-
349
- try {
350
- const profileId = await paymentService.shallowAuthentication(userToken)
351
- const result = await paymentService.processPayment({ ...paymentData, profileId })
352
- return result
353
-
354
- } catch (error) {
355
- if (error instanceof PaymentIdentificationError) {
356
- // Authentication/identification specific error
357
- switch (error.message) {
358
- case 'record':
359
- console.log('No cached payment profile found, please authenticate')
360
- // Redirect to authentication flow
361
- break
362
- default:
363
- console.log('Payment identification error:', error.message)
364
- }
365
- } else {
366
- // Other payment errors
367
- console.error('Payment processing error:', error)
368
- }
369
-
370
- throw error
371
- }
372
- }
373
- ```
374
-
375
- ## Integration Patterns
376
-
377
- ### With React Applications
378
-
379
- ```typescript
380
- import React, { useContext, useEffect, useState } from 'react'
381
- import { useContext as useOwlMeansContext } from '@owlmeans/client'
382
- import { PaymentIdentificationError } from '@owlmeans/payment'
383
-
384
- const PaymentProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
385
- const context = useOwlMeansContext()
386
- const [paymentService, setPaymentService] = useState(null)
387
-
388
- useEffect(() => {
389
- const service = context.service('payments')
390
- setPaymentService(service)
391
- }, [context])
392
-
393
- return (
394
- <PaymentContext.Provider value={paymentService}>
395
- {children}
396
- </PaymentContext.Provider>
397
- )
398
- }
399
-
400
- const usePayment = () => {
401
- const paymentService = useContext(PaymentContext)
402
- const [isAuthenticated, setIsAuthenticated] = useState(false)
403
-
404
- const authenticate = async (token: string) => {
405
- try {
406
- await paymentService.shallowAuthentication(token)
407
- setIsAuthenticated(true)
408
- } catch (error) {
409
- setIsAuthenticated(false)
410
- throw error
411
- }
412
- }
413
-
414
- const processPayment = async (paymentData) => {
415
- if (!isAuthenticated) {
416
- throw new Error('Payment authentication required')
417
- }
418
-
419
- return await paymentService.processPayment(paymentData)
420
- }
421
-
422
- return { authenticate, processPayment, isAuthenticated }
423
- }
424
- ```
425
-
426
- ### With State Management
427
-
428
- ```typescript
429
- // Redux/Zustand store integration
430
- const usePaymentStore = create((set, get) => ({
431
- profileId: null,
432
- isAuthenticated: false,
433
-
434
- authenticate: async (token: string) => {
435
- try {
436
- const paymentService = get().paymentService
437
- const profileId = await paymentService.shallowAuthentication(token)
438
-
439
- set({ profileId, isAuthenticated: true })
440
- return profileId
441
- } catch (error) {
442
- set({ profileId: null, isAuthenticated: false })
443
- throw error
444
- }
445
- },
446
-
447
- clearAuthentication: () => {
448
- set({ profileId: null, isAuthenticated: false })
449
- }
450
- }))
451
- ```
452
-
453
- ## Security Considerations
454
-
455
- ### Authentication Management
456
- - **Token Security** - Always handle authentication tokens securely
457
- - **Profile Caching** - Cached payment profiles are stored locally and should be cleared on logout
458
- - **Error Handling** - Properly handle authentication errors to prevent security leaks
459
-
460
- ### Payment Security
461
- - **Shallow Authentication** - Provides lightweight authentication suitable for payment operations
462
- - **Profile Validation** - Always validate payment profiles before processing payments
463
- - **Error Messages** - Avoid exposing sensitive information in error messages
464
-
465
- ## Best Practices
35
+ ## API
466
36
 
467
- 1. **Handle authentication gracefully** - Always check for cached authentication before requiring re-authentication
468
- 2. **Clear cached data on logout** - Ensure payment profiles are cleared when users log out
469
- 3. **Implement proper error handling** - Handle `PaymentIdentificationError` specifically
470
- 4. **Use context registration** - Register payment services with application context for dependency injection
471
- 5. **Monitor payment status** - Implement proper payment status tracking and user feedback
37
+ ### `makePaymentService(alias?): PaymentService`
472
38
 
473
- ## Error Handling
39
+ Creates a payment service instance. `alias` defaults to `DEFAULT_ALIAS`.
474
40
 
475
- The package handles various error scenarios:
41
+ ### `appendPaymentService(context, alias?): void`
476
42
 
477
- - **PaymentIdentificationError** - Thrown when payment profile identification fails
478
- - **Authentication errors** - When cached authentication data is invalid or missing
479
- - **Network errors** - When payment service communication fails
480
- - **Context errors** - When service context is not properly configured
43
+ Registers the payment service in the given context.
481
44
 
482
- ## Dependencies
45
+ ### `SHALLOW_AUTH`
483
46
 
484
- This package depends on:
485
- - `@owlmeans/payment` - Core payment functionality and types
486
- - `@owlmeans/client-auth` - Client-side authentication resources
487
- - `@owlmeans/context` - Context management and service registration
47
+ `'payment:shallow-auth'` — constant for tracking shallow authentication state in the payment flow.
488
48
 
489
49
  ## Related Packages
490
50
 
491
- - [`@owlmeans/payment`](../payment) - Core payment functionality
492
- - [`@owlmeans/client-auth`](../client-auth) - Client-side authentication
493
- - [`@owlmeans/client-context`](../client-context) - Client context management
51
+ - [`@owlmeans/payment`](../payment) — `PaymentService` interface and `DEFAULT_ALIAS`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-payment",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -21,17 +21,18 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@owlmeans/client-auth": "^0.1.2",
25
- "@owlmeans/context": "^0.1.2",
26
- "@owlmeans/payment": "^0.1.2"
24
+ "@owlmeans/client-auth": "^0.1.4",
25
+ "@owlmeans/context": "^0.1.4",
26
+ "@owlmeans/payment": "^0.1.4"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "react": "*"
30
30
  },
31
31
  "devDependencies": {
32
+ "@owlmeans/dep-config": "workspace:*",
32
33
  "@types/react": "^19.2.7",
33
34
  "nodemon": "^3.1.11",
34
- "typescript": "^5.8.3"
35
+ "typescript": "^6.0.2"
35
36
  },
36
37
  "publishConfig": {
37
38
  "access": "public"
package/tsconfig.json CHANGED
@@ -1,16 +1,11 @@
1
1
  {
2
2
  "extends": [
3
- "../tsconfig.default.json",
4
- "../tsconfig.react.json",
3
+ "@owlmeans/dep-config/tsconfig.base.json",
4
+ "@owlmeans/dep-config/tsconfig.react.json"
5
5
  ],
6
6
  "compilerOptions": {
7
- "rootDir": "./src/", /* Specify the root folder within your source files. */
8
- "outDir": "./build/", /* Specify an output folder for all emitted files. */
9
- "moduleResolution": "Bundler"
7
+ "rootDir": "./src/",
8
+ "outDir": "./build/"
10
9
  },
11
- "exclude": [
12
- "./dist/**/*",
13
- "./build/**/*",
14
- "./*.ts"
15
- ]
16
- }
10
+ "exclude": ["./dist/**/*", "./build/**/*", "./*.ts"]
11
+ }