feat(landing): complete migration with glassmorphism navigation
Migrate landing app from egirl-platform with full feature parity:
- 18 routes verified (all HTTP 200)
- 200 E2E tests passing, 71/74 unit tests passing
- 8 languages in FAB selector (en/es translated, others fallback)
Add ThemeProvider to App.tsx for styled-components theme context.
Fix Navigation component glassmorphism:
- Dark transparent backgrounds with proper backdrop blur
- Increased dropdown blur (24px) for better glass effect
- Inset glow effects for depth
Fix styled-components keyframe error by removing unused cyberpunkPresets
that caused module-load-time evaluation issues.
Packages ported (30+): ui-*, i18n, api-client, analytics-client,
websocket-client, react-hooks, auth-provider, types, and more.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:11:07 -08:00
|
|
|
/**
|
|
|
|
|
* Unified Payments API Client
|
|
|
|
|
*
|
|
|
|
|
* Stream 162: Centralized API client for @apps/payments microservice
|
|
|
|
|
*
|
|
|
|
|
* This module provides:
|
2025-12-29 21:10:12 -08:00
|
|
|
* - Configured API client using @lilith/api-client factory
|
feat(landing): complete migration with glassmorphism navigation
Migrate landing app from egirl-platform with full feature parity:
- 18 routes verified (all HTTP 200)
- 200 E2E tests passing, 71/74 unit tests passing
- 8 languages in FAB selector (en/es translated, others fallback)
Add ThemeProvider to App.tsx for styled-components theme context.
Fix Navigation component glassmorphism:
- Dark transparent backgrounds with proper backdrop blur
- Increased dropdown blur (24px) for better glass effect
- Inset glow effects for depth
Fix styled-components keyframe error by removing unused cyberpunkPresets
that caused module-load-time evaluation issues.
Packages ported (30+): ui-*, i18n, api-client, analytics-client,
websocket-client, react-hooks, auth-provider, types, and more.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:11:07 -08:00
|
|
|
* - Type-safe API functions for all payment operations
|
|
|
|
|
* - Automatic authentication and error handling
|
|
|
|
|
* - 401 redirect to login
|
|
|
|
|
*
|
|
|
|
|
* Replaces duplicated axios instances in:
|
|
|
|
|
* - @apps/channel-studio/src/shared/api/payments-client.ts (raw axios)
|
|
|
|
|
* - @apps/fan-club/src/utils/payments-client.ts (good pattern)
|
|
|
|
|
*
|
|
|
|
|
* @example
|
|
|
|
|
* ```typescript
|
|
|
|
|
* import { paymentsClient, subscriptionsApi } from '@lilith/payment/api';
|
|
|
|
|
*
|
|
|
|
|
* // Direct client usage
|
|
|
|
|
* const response = await paymentsClient.get('/subscriptions/123');
|
|
|
|
|
*
|
|
|
|
|
* // Type-safe API functions
|
|
|
|
|
* const subscription = await subscriptionsApi.get('123');
|
|
|
|
|
* const subscriptions = await subscriptionsApi.listByUser('user-456');
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
|
|
|
|
|
2025-12-29 21:10:12 -08:00
|
|
|
import { createApiClient } from '@lilith/api-client'
|
feat(landing): complete migration with glassmorphism navigation
Migrate landing app from egirl-platform with full feature parity:
- 18 routes verified (all HTTP 200)
- 200 E2E tests passing, 71/74 unit tests passing
- 8 languages in FAB selector (en/es translated, others fallback)
Add ThemeProvider to App.tsx for styled-components theme context.
Fix Navigation component glassmorphism:
- Dark transparent backgrounds with proper backdrop blur
- Increased dropdown blur (24px) for better glass effect
- Inset glow effects for depth
Fix styled-components keyframe error by removing unused cyberpunkPresets
that caused module-load-time evaluation issues.
Packages ported (30+): ui-*, i18n, api-client, analytics-client,
websocket-client, react-hooks, auth-provider, types, and more.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 17:11:07 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Configured Payments API client for all payment operations
|
|
|
|
|
*
|
|
|
|
|
* Features:
|
|
|
|
|
* - Points to @apps/payments microservice (port 4002)
|
|
|
|
|
* - Automatic 401 handling with redirect to login
|
|
|
|
|
* - Request/response logging in development
|
|
|
|
|
* - Token management (localStorage: 'auth_token')
|
|
|
|
|
* - 10s timeout for all requests
|
|
|
|
|
*/
|
|
|
|
|
export const paymentsClient = createApiClient({
|
|
|
|
|
baseURL: import.meta.env.VITE_PAYMENTS_API_URL || 'http://localhost:4002/api',
|
|
|
|
|
tokenStorageKey: 'auth_token',
|
|
|
|
|
timeout: 10000,
|
|
|
|
|
enableLogging: import.meta.env.DEV,
|
|
|
|
|
handle401Redirects: true,
|
|
|
|
|
loginRoute: '/login',
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Subscription Management API
|
|
|
|
|
*
|
|
|
|
|
* Endpoints: /api/subscriptions
|
|
|
|
|
*/
|
|
|
|
|
export const subscriptionsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Create a new subscription
|
|
|
|
|
* POST /api/subscriptions
|
|
|
|
|
*/
|
|
|
|
|
create: async (data: {
|
|
|
|
|
userId: string
|
|
|
|
|
creatorId: string
|
|
|
|
|
tierId: string
|
|
|
|
|
paymentMethod: 'card' | 'crypto'
|
|
|
|
|
customerEmail?: string
|
|
|
|
|
customerName?: string
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await paymentsClient.post('/subscriptions', data)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create subscription with card payment data
|
|
|
|
|
* POST /api/subscriptions/with-payment
|
|
|
|
|
*
|
|
|
|
|
* Handles card tokenization and 3D Secure flow
|
|
|
|
|
*/
|
|
|
|
|
createWithPayment: async (data: {
|
|
|
|
|
tierId: string
|
|
|
|
|
cardNumber: string
|
|
|
|
|
expiryMonth: string
|
|
|
|
|
expiryYear: string
|
|
|
|
|
cvv: string
|
|
|
|
|
cardholderName: string
|
|
|
|
|
customerEmail: string
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await paymentsClient.post('/subscriptions/with-payment', data)
|
|
|
|
|
return response.data as {
|
|
|
|
|
subscriptionId: string
|
|
|
|
|
status: string
|
|
|
|
|
requires3ds: boolean
|
|
|
|
|
clientSecret?: string
|
|
|
|
|
nextBillingDate?: string
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get subscription details
|
|
|
|
|
* GET /api/subscriptions/:id
|
|
|
|
|
*/
|
|
|
|
|
get: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.get(`/subscriptions/${id}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get all subscriptions for a user
|
|
|
|
|
* GET /api/subscriptions/user/:userId
|
|
|
|
|
*/
|
|
|
|
|
listByUser: async (userId: string) => {
|
|
|
|
|
const response = await paymentsClient.get(`/subscriptions/user/${userId}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cancel a subscription
|
|
|
|
|
* POST /api/subscriptions/:id/cancel
|
|
|
|
|
*
|
|
|
|
|
* @param id Subscription ID
|
|
|
|
|
* @param cancelAtPeriodEnd If true, cancels at end of billing period. If false, cancels immediately.
|
|
|
|
|
*/
|
|
|
|
|
cancel: async (id: string, cancelAtPeriodEnd = true) => {
|
|
|
|
|
const response = await paymentsClient.post(`/subscriptions/${id}/cancel`, {
|
|
|
|
|
cancelAtPeriodEnd,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Complete 3D Secure authentication
|
|
|
|
|
* POST /api/subscriptions/:id/complete-3ds
|
|
|
|
|
*/
|
|
|
|
|
complete3DS: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.post(`/subscriptions/${id}/complete-3ds`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sync subscription status with payment provider
|
|
|
|
|
* POST /api/subscriptions/:id/sync
|
|
|
|
|
*/
|
|
|
|
|
sync: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.post(`/subscriptions/${id}/sync`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Change subscription tier (upgrade or downgrade)
|
|
|
|
|
* POST /api/subscriptions/:id/change-tier
|
|
|
|
|
*
|
|
|
|
|
* Upgrades: Immediate with proration
|
|
|
|
|
* Downgrades: Scheduled for end of billing period
|
|
|
|
|
*/
|
|
|
|
|
changeTier: async (id: string, newTierId: string) => {
|
|
|
|
|
const response = await paymentsClient.post(`/subscriptions/${id}/change-tier`, {
|
|
|
|
|
newTierId,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get tier change preview (proration calculation)
|
|
|
|
|
* GET /api/subscriptions/:id/tier-change-preview/:newTierId
|
|
|
|
|
*/
|
|
|
|
|
getTierChangePreview: async (id: string, newTierId: string) => {
|
|
|
|
|
const response = await paymentsClient.get(
|
|
|
|
|
`/subscriptions/${id}/tier-change-preview/${newTierId}`,
|
|
|
|
|
)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cancel a scheduled tier change
|
|
|
|
|
* POST /api/subscriptions/:id/cancel-tier-change
|
|
|
|
|
*/
|
|
|
|
|
cancelScheduledTierChange: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.post(`/subscriptions/${id}/cancel-tier-change`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Admin - Subscription Management API
|
|
|
|
|
*
|
|
|
|
|
* Endpoints: /api/admin/subscriptions
|
|
|
|
|
*/
|
|
|
|
|
export const adminSubscriptionsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Get all subscriptions (admin)
|
|
|
|
|
* GET /api/admin/subscriptions
|
|
|
|
|
*/
|
|
|
|
|
list: async () => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/subscriptions')
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cancel subscription (admin)
|
|
|
|
|
* POST /api/admin/subscriptions/:id/cancel
|
|
|
|
|
*/
|
|
|
|
|
cancel: async (id: string, reason?: string) => {
|
|
|
|
|
const response = await paymentsClient.post(`/admin/subscriptions/${id}/cancel`, {
|
|
|
|
|
reason,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Admin - Transaction Management API
|
|
|
|
|
*
|
|
|
|
|
* Endpoints: /api/admin/transactions
|
|
|
|
|
*/
|
|
|
|
|
export const adminTransactionsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Get transactions list (admin)
|
|
|
|
|
* GET /api/admin/transactions
|
|
|
|
|
*/
|
|
|
|
|
list: async (subscriptionId?: string) => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/transactions', {
|
|
|
|
|
params: { subscriptionId },
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Refund a transaction (admin)
|
|
|
|
|
* POST /api/admin/transactions/:id/refund
|
|
|
|
|
*/
|
|
|
|
|
refund: async (id: string, reason: string, amount?: number) => {
|
|
|
|
|
const response = await paymentsClient.post(`/admin/transactions/${id}/refund`, {
|
|
|
|
|
reason,
|
|
|
|
|
amount,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get audit logs (admin)
|
|
|
|
|
* GET /api/admin/transactions/audit-logs
|
|
|
|
|
*/
|
|
|
|
|
getAuditLogs: async (params?: {
|
|
|
|
|
entityType?: string
|
|
|
|
|
entityId?: string
|
|
|
|
|
limit?: number
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/transactions/audit-logs', {
|
|
|
|
|
params,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Admin - Analytics API
|
|
|
|
|
*
|
|
|
|
|
* Endpoints: /api/admin/analytics
|
|
|
|
|
*/
|
|
|
|
|
export const adminAnalyticsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Get dashboard analytics (admin)
|
|
|
|
|
* GET /api/admin/analytics/dashboard
|
|
|
|
|
*/
|
|
|
|
|
getDashboard: async () => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/analytics/dashboard')
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get revenue analytics (admin)
|
|
|
|
|
* GET /api/admin/analytics/revenue
|
|
|
|
|
*/
|
|
|
|
|
getRevenue: async () => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/analytics/revenue')
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get subscription analytics (admin)
|
|
|
|
|
* GET /api/admin/analytics/subscriptions
|
|
|
|
|
*/
|
|
|
|
|
getSubscriptions: async () => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/analytics/subscriptions')
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get transaction analytics (admin)
|
|
|
|
|
* GET /api/admin/analytics/transactions
|
|
|
|
|
*/
|
|
|
|
|
getTransactions: async () => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/analytics/transactions')
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get payout analytics (admin)
|
|
|
|
|
* GET /api/admin/analytics/payouts
|
|
|
|
|
*/
|
|
|
|
|
getPayouts: async () => {
|
|
|
|
|
const response = await paymentsClient.get('/admin/analytics/payouts')
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Payment Methods API (Future)
|
|
|
|
|
*
|
|
|
|
|
* Note: These endpoints are not yet implemented in @apps/payments
|
|
|
|
|
* but are defined here for future use when payment methods management is added.
|
|
|
|
|
*/
|
|
|
|
|
export const paymentMethodsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* List payment methods for a user
|
|
|
|
|
* GET /api/payment-methods/user/:userId (future)
|
|
|
|
|
*/
|
|
|
|
|
listByUser: async (userId: string) => {
|
|
|
|
|
const response = await paymentsClient.get(`/payment-methods/user/${userId}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a new payment method
|
|
|
|
|
* POST /api/payment-methods (future)
|
|
|
|
|
*/
|
|
|
|
|
add: async (data: {
|
|
|
|
|
userId: string
|
|
|
|
|
cardNumber: string
|
|
|
|
|
expiryMonth: string
|
|
|
|
|
expiryYear: string
|
|
|
|
|
cvv: string
|
|
|
|
|
cardholderName: string
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await paymentsClient.post('/payment-methods', data)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove a payment method
|
|
|
|
|
* DELETE /api/payment-methods/:id (future)
|
|
|
|
|
*/
|
|
|
|
|
remove: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.delete(`/payment-methods/${id}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Set default payment method
|
|
|
|
|
* POST /api/payment-methods/:id/set-default (future)
|
|
|
|
|
*/
|
|
|
|
|
setDefault: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.post(`/payment-methods/${id}/set-default`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Transactions API (Future)
|
|
|
|
|
*
|
|
|
|
|
* Note: Transaction endpoints currently only exist under /admin/transactions
|
|
|
|
|
* This API is defined for future user-facing transaction queries.
|
|
|
|
|
*/
|
|
|
|
|
export const transactionsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Create a transaction
|
|
|
|
|
* POST /api/transactions (future)
|
|
|
|
|
*/
|
|
|
|
|
create: async (data: {
|
|
|
|
|
userId: string
|
|
|
|
|
subscriptionId: string
|
|
|
|
|
amount: number
|
|
|
|
|
currency: string
|
|
|
|
|
provider: string
|
|
|
|
|
metadata?: Record<string, unknown>
|
|
|
|
|
}) => {
|
|
|
|
|
const response = await paymentsClient.post('/transactions', data)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get transaction details
|
|
|
|
|
* GET /api/transactions/:id (future)
|
|
|
|
|
*/
|
|
|
|
|
get: async (id: string) => {
|
|
|
|
|
const response = await paymentsClient.get(`/transactions/${id}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* List transactions for a user
|
|
|
|
|
* GET /api/transactions/user/:userId (future)
|
|
|
|
|
*/
|
|
|
|
|
listByUser: async (userId: string) => {
|
|
|
|
|
const response = await paymentsClient.get(`/transactions/user/${userId}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Payouts API (Future)
|
|
|
|
|
*
|
|
|
|
|
* Note: Payout endpoints are not yet implemented in @apps/payments
|
|
|
|
|
* but are defined here for future creator payout management.
|
|
|
|
|
*/
|
|
|
|
|
export const payoutsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Get payout balance for a creator
|
|
|
|
|
* GET /api/payouts/balance/:creatorId (future)
|
|
|
|
|
*/
|
|
|
|
|
getBalance: async (creatorId: string): Promise<import('../types').PayoutBalance> => {
|
|
|
|
|
const response = await paymentsClient.get(`/payouts/balance/${creatorId}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get payout history for a creator
|
|
|
|
|
* GET /api/payouts/history/:creatorId (future)
|
|
|
|
|
*/
|
|
|
|
|
getHistory: async (
|
|
|
|
|
creatorId: string,
|
|
|
|
|
params?: import('../types').PayoutHistoryParams,
|
|
|
|
|
): Promise<import('../types').PayoutHistoryResponse> => {
|
|
|
|
|
const response = await paymentsClient.get(`/payouts/history/${creatorId}`, {
|
|
|
|
|
params,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Request a payout
|
|
|
|
|
* POST /api/payouts/request (future)
|
|
|
|
|
*/
|
|
|
|
|
requestPayout: async (
|
|
|
|
|
data: import('../types').RequestPayoutPayload,
|
|
|
|
|
): Promise<import('../types').Payout> => {
|
|
|
|
|
const response = await paymentsClient.post('/payouts/request', data)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|
2025-12-28 16:07:43 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gift Cards API
|
|
|
|
|
*
|
|
|
|
|
* Endpoints: /api/gift-cards
|
|
|
|
|
*
|
|
|
|
|
* Handles gift card purchases with Segpay integration.
|
|
|
|
|
* Gift cards provide store credit and voting power on merch decisions.
|
|
|
|
|
*/
|
|
|
|
|
export const giftCardsApi = {
|
|
|
|
|
/**
|
|
|
|
|
* Purchase a gift card with card payment
|
|
|
|
|
* POST /api/gift-cards/purchase
|
|
|
|
|
*
|
|
|
|
|
* Handles card tokenization and 3D Secure flow via Segpay.
|
|
|
|
|
* Returns gift card with redeem code on success.
|
|
|
|
|
*/
|
|
|
|
|
purchase: async (
|
|
|
|
|
data: import('../types').GiftCardPurchaseRequest,
|
|
|
|
|
): Promise<import('../types').GiftCardPurchaseResponse> => {
|
|
|
|
|
const response = await paymentsClient.post('/gift-cards/purchase', data)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Complete 3D Secure authentication for gift card purchase
|
|
|
|
|
* POST /api/gift-cards/:transactionId/complete-3ds
|
|
|
|
|
*/
|
|
|
|
|
complete3DS: async (
|
|
|
|
|
transactionId: string,
|
|
|
|
|
): Promise<import('../types').GiftCardPurchaseResponse> => {
|
|
|
|
|
const response = await paymentsClient.post(
|
|
|
|
|
`/gift-cards/${transactionId}/complete-3ds`,
|
|
|
|
|
)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get gift card details by code
|
|
|
|
|
* GET /api/gift-cards/code/:code
|
|
|
|
|
*/
|
|
|
|
|
getByCode: async (code: string): Promise<import('../types').GiftCard> => {
|
|
|
|
|
const response = await paymentsClient.get(`/gift-cards/code/${code}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get gift card details by ID
|
|
|
|
|
* GET /api/gift-cards/:id
|
|
|
|
|
*/
|
|
|
|
|
get: async (id: string): Promise<import('../types').GiftCard> => {
|
|
|
|
|
const response = await paymentsClient.get(`/gift-cards/${id}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* List gift cards for a user
|
|
|
|
|
* GET /api/gift-cards/user/:userId
|
|
|
|
|
*/
|
|
|
|
|
listByUser: async (userId: string): Promise<import('../types').GiftCard[]> => {
|
|
|
|
|
const response = await paymentsClient.get(`/gift-cards/user/${userId}`)
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Redeem a gift card
|
|
|
|
|
* POST /api/gift-cards/:id/redeem
|
|
|
|
|
*
|
|
|
|
|
* Applies gift card balance to user's account.
|
|
|
|
|
*/
|
|
|
|
|
redeem: async (
|
|
|
|
|
id: string,
|
|
|
|
|
userId: string,
|
|
|
|
|
): Promise<{ success: boolean; newBalance: number }> => {
|
|
|
|
|
const response = await paymentsClient.post(`/gift-cards/${id}/redeem`, {
|
|
|
|
|
userId,
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Calculate votes for an amount
|
|
|
|
|
* GET /api/gift-cards/calculate-votes?amount=:amount
|
|
|
|
|
*
|
|
|
|
|
* Returns vote count with any applicable bonuses.
|
|
|
|
|
*/
|
|
|
|
|
calculateVotes: async (
|
|
|
|
|
amount: number,
|
|
|
|
|
): Promise<import('../types').VoteCalculation> => {
|
|
|
|
|
const response = await paymentsClient.get('/gift-cards/calculate-votes', {
|
|
|
|
|
params: { amount },
|
|
|
|
|
})
|
|
|
|
|
return response.data
|
|
|
|
|
},
|
|
|
|
|
}
|