@kasuvia/sdk 0.0.2 → 0.0.5

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 (77) hide show
  1. package/dist/hooks/index.d.mts +430 -0
  2. package/dist/hooks/index.d.ts +430 -0
  3. package/dist/hooks/index.js +3073 -0
  4. package/dist/hooks/index.js.map +1 -0
  5. package/dist/hooks/index.mjs +2962 -0
  6. package/dist/hooks/index.mjs.map +1 -0
  7. package/dist/index-CxNLI4nw.d.ts +786 -0
  8. package/dist/index-CzVMyUs4.d.mts +492 -0
  9. package/dist/index-CzVMyUs4.d.ts +492 -0
  10. package/dist/index-Dowl5224.d.mts +786 -0
  11. package/dist/index.d.mts +48 -1739
  12. package/dist/index.d.ts +48 -1739
  13. package/dist/index.js +1544 -2359
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +1527 -2258
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/sdk-context-BuarJbeb.d.ts +75 -0
  18. package/dist/sdk-context-Db8kf1Tv.d.mts +75 -0
  19. package/dist/services/index.d.mts +2 -0
  20. package/dist/services/index.d.ts +2 -0
  21. package/dist/services/index.js +2369 -0
  22. package/dist/services/index.js.map +1 -0
  23. package/dist/services/index.mjs +2252 -0
  24. package/dist/services/index.mjs.map +1 -0
  25. package/package.json +11 -2
  26. package/src/config/index.ts +10 -91
  27. package/src/constants.ts +13 -0
  28. package/src/context/sdk-context.tsx +70 -0
  29. package/src/graphql/collections.graphql.ts +2 -10
  30. package/src/graphql/products.graphql.ts +215 -65
  31. package/src/graphql/wishlist.graphql.ts +7 -6
  32. package/src/hooks/index.ts +2 -0
  33. package/src/hooks/use-auth.ts +82 -158
  34. package/src/hooks/use-bespoke-availability.ts +25 -8
  35. package/src/hooks/use-cart.ts +222 -119
  36. package/src/hooks/use-cms.ts +179 -86
  37. package/src/hooks/use-collections.ts +52 -15
  38. package/src/hooks/use-consultation-stream.ts +4 -3
  39. package/src/hooks/use-consultations.ts +120 -51
  40. package/src/hooks/use-countries.ts +35 -13
  41. package/src/hooks/use-currencies.ts +26 -13
  42. package/src/hooks/use-google-translate.ts +22 -8
  43. package/src/hooks/use-languages.ts +40 -20
  44. package/src/hooks/use-mobile.ts +23 -0
  45. package/src/hooks/use-order-stream.ts +9 -5
  46. package/src/hooks/use-orders.ts +99 -44
  47. package/src/hooks/use-payment.ts +108 -40
  48. package/src/hooks/use-products.ts +251 -53
  49. package/src/hooks/use-service-booking.ts +152 -90
  50. package/src/hooks/use-states.ts +35 -15
  51. package/src/hooks/use-wishlist.ts +92 -91
  52. package/src/index.ts +26 -30
  53. package/src/services/auth.service.ts +209 -167
  54. package/src/services/bespoke.service.ts +12 -4
  55. package/src/services/cart.service.ts +172 -70
  56. package/src/services/cms.service.ts +70 -35
  57. package/src/services/collection.service.ts +22 -5
  58. package/src/services/config.service.ts +34 -14
  59. package/src/services/consultation.service.ts +72 -18
  60. package/src/services/logistics.service.ts +35 -11
  61. package/src/services/notifications.service.ts +27 -12
  62. package/src/services/order.service.ts +74 -15
  63. package/src/services/payment.service.ts +86 -31
  64. package/src/services/product.service.ts +279 -39
  65. package/src/services/service-booking.service.ts +98 -26
  66. package/src/services/wishlist.service.ts +69 -25
  67. package/src/types/auth/index.ts +6 -4
  68. package/src/types/business/index.ts +7 -2
  69. package/src/types/payments/index.ts +3 -3
  70. package/src/types/services/index.ts +2 -5
  71. package/src/types/store/index.ts +38 -3
  72. package/src/utils/error-handler.ts +10 -5
  73. package/src/utils/storage.ts +48 -26
  74. package/src/utils/validators.ts +85 -0
  75. package/src/client/authClient.ts +0 -135
  76. package/src/client/graphqlClient.ts +0 -53
  77. package/src/client/httpClient.ts +0 -298
@@ -2,8 +2,9 @@
2
2
  * Consultation Service
3
3
  *
4
4
  * Handles consultation operations for bespoke and service products.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { storeManagementAxios } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
  import type {
8
9
  Consultation,
9
10
  ConsultationCreatePayload,
@@ -11,33 +12,86 @@ import type {
11
12
  ConsultationQuoteAcceptPayload,
12
13
  } from '../types/consultations'
13
14
 
14
- export async function createConsultation(payload: ConsultationCreatePayload): Promise<Consultation> {
15
- const { data } = await storeManagementAxios.post<Consultation>('social/consultations/', payload)
16
- return data
15
+ export async function createConsultation(config: SdkConfig, accessToken: string, payload: ConsultationCreatePayload): Promise<Consultation> {
16
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {
17
+ method: 'POST',
18
+ headers: {
19
+ 'Content-Type': 'application/json',
20
+ "Authorization": `Bearer ${accessToken}`,
21
+ "X-Storefront-Key": config.storefrontApiKey,
22
+ "X-Business-ID": config.businessId,
23
+ },
24
+ body: JSON.stringify(payload),
25
+ })
26
+ if (!response.ok) throw new Error('Failed to create consultation')
27
+ return response.json()
17
28
  }
18
29
 
19
- export async function getConsultations(): Promise<Consultation[]> {
20
- const { data } = await storeManagementAxios.get<Consultation[]>('social/consultations/')
21
- return data
30
+ export async function getConsultations(config: SdkConfig, accessToken: string): Promise<Consultation[]> {
31
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/`, {
32
+ headers: {
33
+ "Authorization": `Bearer ${accessToken}`,
34
+ "X-Storefront-Key": config.storefrontApiKey,
35
+ "X-Business-ID": config.businessId,
36
+ },
37
+ })
38
+ if (!response.ok) throw new Error('Failed to get consultations')
39
+ return response.json()
22
40
  }
23
41
 
24
- export async function getConsultation(id: string): Promise<Consultation> {
25
- const { data } = await storeManagementAxios.get<Consultation>(`social/consultations/${id}`)
26
- return data
42
+ export async function getConsultation(config: SdkConfig, accessToken: string, id: string): Promise<Consultation> {
43
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}`, {
44
+ headers: {
45
+ "Authorization": `Bearer ${accessToken}`,
46
+ "X-Storefront-Key": config.storefrontApiKey,
47
+ "X-Business-ID": config.businessId,
48
+ },
49
+ })
50
+ if (!response.ok) throw new Error('Failed to get consultation')
51
+ return response.json()
27
52
  }
28
53
 
29
- export async function sendMessage(id: string, payload: ConsultationMessagePayload): Promise<void> {
30
- await storeManagementAxios.post(`social/consultations/${id}/messages`, payload)
54
+ export async function sendMessage(config: SdkConfig, accessToken: string, id: string, payload: ConsultationMessagePayload): Promise<void> {
55
+ await fetch(`${config.backendUrls.store}/social/consultations/${id}/messages`, {
56
+ method: 'POST',
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ "Authorization": `Bearer ${accessToken}`,
60
+ "X-Storefront-Key": config.storefrontApiKey,
61
+ "X-Business-ID": config.businessId,
62
+ },
63
+ body: JSON.stringify(payload),
64
+ })
31
65
  }
32
66
 
33
- export async function acceptQuote(id: string, payload: ConsultationQuoteAcceptPayload): Promise<Consultation> {
34
- const { data } = await storeManagementAxios.post<Consultation>(`social/consultations/${id}/accept-quote`, payload)
35
- return data
67
+ export async function acceptQuote(config: SdkConfig, accessToken: string, id: string, payload: ConsultationQuoteAcceptPayload): Promise<Consultation> {
68
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/accept-quote`, {
69
+ method: 'POST',
70
+ headers: {
71
+ 'Content-Type': 'application/json',
72
+ "Authorization": `Bearer ${accessToken}`,
73
+ "X-Storefront-Key": config.storefrontApiKey,
74
+ "X-Business-ID": config.businessId,
75
+ },
76
+ body: JSON.stringify(payload),
77
+ })
78
+ if (!response.ok) throw new Error('Failed to accept quote')
79
+ return response.json()
36
80
  }
37
81
 
38
- export async function rejectQuote(id: string, reason?: string): Promise<Consultation> {
39
- const { data } = await storeManagementAxios.post<Consultation>(`social/consultations/${id}/reject-quote`, { reason })
40
- return data
82
+ export async function rejectQuote(config: SdkConfig, accessToken: string, id: string, reason?: string): Promise<Consultation> {
83
+ const response = await fetch(`${config.backendUrls.store}/social/consultations/${id}/reject-quote`, {
84
+ method: 'POST',
85
+ headers: {
86
+ 'Content-Type': 'application/json',
87
+ "Authorization": `Bearer ${accessToken}`,
88
+ "X-Storefront-Key": config.storefrontApiKey,
89
+ "X-Business-ID": config.businessId,
90
+ },
91
+ body: JSON.stringify({ reason }),
92
+ })
93
+ if (!response.ok) throw new Error('Failed to reject quote')
94
+ return response.json()
41
95
  }
42
96
 
43
97
  // Service object export for backward compatibility
@@ -2,8 +2,9 @@
2
2
  * Logistics Service
3
3
  *
4
4
  * Handles shipping rates and address validation.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { storeManagementAxios } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
  import type { ShippingRatesResponse } from '../types/store/shipping'
8
9
  import type { Product, ProductVariant } from '../types/store'
9
10
 
@@ -34,19 +35,26 @@ export interface ShippingRatesRequest {
34
35
  * Fetch shipping rates for a cart.
35
36
  */
36
37
  export async function getShippingRates(
38
+ config: SdkConfig,
37
39
  payload: ShippingRatesRequest
38
40
  ): Promise<ShippingRatesResponse> {
39
- const { data } = await storeManagementAxios.post<ShippingRatesResponse>(
40
- 'logistics/shipping/rates',
41
- payload
42
- )
43
- return data
41
+ const response = await fetch(`${config.backendUrls.store}/logistics/shipping/rates`, {
42
+ method: 'POST',
43
+ headers: {
44
+ 'Content-Type': 'application/json',
45
+ "X-Storefront-Key": config.storefrontApiKey,
46
+ "X-Business-ID": config.businessId,
47
+ },
48
+ body: JSON.stringify(payload),
49
+ })
50
+ if (!response.ok) throw new Error('Failed to get shipping rates')
51
+ return response.json()
44
52
  }
45
53
 
46
54
  /**
47
55
  * Fetch the seller's registered shipping address.
48
56
  */
49
- export async function getSellerShippingAddress(): Promise<{
57
+ export async function getSellerShippingAddress(config: SdkConfig): Promise<{
50
58
  terminal_address_id: string | null
51
59
  address_details: {
52
60
  city: string
@@ -59,14 +67,21 @@ export async function getSellerShippingAddress(): Promise<{
59
67
  business_id: string
60
68
  message: string
61
69
  }> {
62
- const { data } = await storeManagementAxios.get('logistics/shipping-address')
63
- return data
70
+ const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address`, {
71
+ headers: {
72
+ "X-Storefront-Key": config.storefrontApiKey,
73
+ "X-Business-ID": config.businessId,
74
+ },
75
+ })
76
+ if (!response.ok) throw new Error('Failed to get seller shipping address')
77
+ return response.json()
64
78
  }
65
79
 
66
80
  /**
67
81
  * Validate a shipping address.
68
82
  */
69
83
  export async function validateShippingAddress(
84
+ config: SdkConfig,
70
85
  payload: {
71
86
  first_name: string
72
87
  last_name: string
@@ -83,8 +98,17 @@ export async function validateShippingAddress(
83
98
  message?: string
84
99
  data?: Array<{ name: string; city_id: string; stateCode: string; countryCode: string }>
85
100
  }> {
86
- const { data } = await storeManagementAxios.post('logistics/shipping-address/validate', payload)
87
- return data
101
+ const response = await fetch(`${config.backendUrls.store}/logistics/shipping-address/validate`, {
102
+ method: 'POST',
103
+ headers: {
104
+ 'Content-Type': 'application/json',
105
+ "X-Storefront-Key": config.storefrontApiKey,
106
+ "X-Business-ID": config.businessId,
107
+ },
108
+ body: JSON.stringify(payload),
109
+ })
110
+ if (!response.ok) throw new Error('Failed to validate shipping address')
111
+ return response.json()
88
112
  }
89
113
 
90
114
  // Service object for backward compatibility
@@ -2,8 +2,9 @@
2
2
  * Notification Service
3
3
  *
4
4
  * Handles contact form submissions and email notifications.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { notificationsAxios } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
 
8
9
  export interface ContactFormData {
9
10
  name: string
@@ -17,17 +18,24 @@ export interface ContactFormData {
17
18
  }
18
19
 
19
20
  /**
20
- * Send contact email to Luxe team.
21
+ * Send contact email to Kasuvia team.
21
22
  * POST /contact/send-contact-email
22
23
  */
23
24
  export async function sendContactEmail(
25
+ config: SdkConfig,
24
26
  payload: ContactFormData
25
27
  ): Promise<{ detail: string }> {
26
- const { data } = await notificationsAxios.post<{ detail: string }>(
27
- 'contact/send-contact-email',
28
- payload
29
- )
30
- return data
28
+ const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-email`, {
29
+ method: 'POST',
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ "X-Storefront-Key": config.storefrontApiKey,
33
+ "X-Business-ID": config.businessId,
34
+ },
35
+ body: JSON.stringify(payload),
36
+ })
37
+ if (!response.ok) throw new Error('Failed to send contact email')
38
+ return response.json()
31
39
  }
32
40
 
33
41
  /**
@@ -35,13 +43,20 @@ export async function sendContactEmail(
35
43
  * POST /contact/send-contact-confirmation
36
44
  */
37
45
  export async function sendContactConfirmation(
46
+ config: SdkConfig,
38
47
  payload: Omit<ContactFormData, 'turnstile_token'>
39
48
  ): Promise<{ detail: string }> {
40
- const { data } = await notificationsAxios.post<{ detail: string }>(
41
- 'contact/send-contact-confirmation',
42
- payload
43
- )
44
- return data
49
+ const response = await fetch(`${config.backendUrls.notifications}/contact/send-contact-confirmation`, {
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ "X-Storefront-Key": config.storefrontApiKey,
54
+ "X-Business-ID": config.businessId,
55
+ },
56
+ body: JSON.stringify(payload),
57
+ })
58
+ if (!response.ok) throw new Error('Failed to send contact confirmation')
59
+ return response.json()
45
60
  }
46
61
 
47
62
  export const notificationsService = {
@@ -2,8 +2,9 @@
2
2
  * Order Service
3
3
  *
4
4
  * Handles order operations including creation, lookup, and tracking.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { storeManagementAxios, publicStoreAxios } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
  import type { Order, OrderStatus, FindOrderParams, CreateOrderParams, OrderItem } from '../types/store'
8
9
  import type { DeliveryAddress } from '../types/store'
9
10
 
@@ -133,37 +134,95 @@ function normaliseStorefrontOrder(raw: RawOrder): Order {
133
134
  }
134
135
  }
135
136
 
136
- export async function createOrder(payload: CreateOrderParams): Promise<Order> {
137
- const { data } = await storeManagementAxios.post<RawOrder>('orders/storefront', payload)
137
+ export async function createOrder(config: SdkConfig, accessToken: string, payload: CreateOrderParams): Promise<Order> {
138
+ const response = await fetch(`${config.backendUrls.store}/orders/storefront`, {
139
+ method: 'POST',
140
+ headers: {
141
+ 'Content-Type': 'application/json',
142
+ "Authorization": `Bearer ${accessToken}`,
143
+ "X-Storefront-Key": config.storefrontApiKey,
144
+ "X-Business-ID": config.businessId,
145
+ },
146
+ body: JSON.stringify(payload),
147
+ })
148
+ if (!response.ok) throw new Error('Failed to create order')
149
+ const data = await response.json()
138
150
  return normaliseStorefrontOrder(data)
139
151
  }
140
152
 
141
- export async function findOrder(params: FindOrderParams): Promise<Order> {
142
- const { data } = await publicStoreAxios.get<RawOrder>('orders/find/', { params })
153
+ export async function findOrder(config: SdkConfig, params: FindOrderParams & { guest_token?: string }): Promise<Order> {
154
+ const queryParams = new URLSearchParams()
155
+ if (params.email) queryParams.set('email', params.email)
156
+ if (params.order_id) queryParams.set('order_id', params.order_id)
157
+ if (params.guest_token) queryParams.set('guest_token', params.guest_token)
158
+
159
+ const response = await fetch(`${config.backendUrls.store}/orders/find/?${queryParams.toString()}`, {
160
+ headers: {
161
+ "X-Storefront-Key": config.storefrontApiKey,
162
+ "X-Business-ID": config.businessId,
163
+ },
164
+ })
165
+ if (!response.ok) throw new Error('Failed to find order')
166
+ const data = await response.json()
143
167
  return normaliseStorefrontOrder(data)
144
168
  }
145
169
 
146
- export async function findOrderByToken(token: string): Promise<Order> {
147
- const { data } = await publicStoreAxios.get<RawOrder>('orders/find/', {
148
- params: { guest_token: token },
170
+ export async function findOrderByToken(config: SdkConfig, token: string): Promise<Order> {
171
+ const response = await fetch(`${config.backendUrls.store}/orders/find/?guest_token=${token}`, {
172
+ headers: {
173
+ "X-Storefront-Key": config.storefrontApiKey,
174
+ "X-Business-ID": config.businessId,
175
+ },
149
176
  })
177
+ if (!response.ok) throw new Error('Failed to find order by token')
178
+ const data = await response.json()
150
179
  return normaliseStorefrontOrder(data)
151
180
  }
152
181
 
153
- export async function getOrders(params?: { email?: string; page?: number; page_size?: number }): Promise<Order[]> {
154
- const { data } = await storeManagementAxios.get<RawOrder[] | { items: RawOrder[] }>('orders/', { params })
182
+ export async function getOrders(config: SdkConfig, accessToken: string, params?: { email?: string; page?: number; page_size?: number }): Promise<Order[]> {
183
+ const queryParams = new URLSearchParams()
184
+ if (params?.email) queryParams.set('email', params.email)
185
+ if (params?.page) queryParams.set('page', params.page.toString())
186
+ if (params?.page_size) queryParams.set('page_size', params.page_size.toString())
187
+
188
+ const response = await fetch(`${config.backendUrls.store}/orders/?${queryParams.toString()}`, {
189
+ headers: {
190
+ "Authorization": `Bearer ${accessToken}`,
191
+ "X-Storefront-Key": config.storefrontApiKey,
192
+ "X-Business-ID": config.businessId,
193
+ },
194
+ })
195
+ if (!response.ok) throw new Error('Failed to get orders')
196
+ const data = await response.json()
155
197
  const items: RawOrder[] = Array.isArray(data) ? data : (data.items ?? [])
156
198
  return items.map(normaliseStorefrontOrder)
157
199
  }
158
200
 
159
- export async function cancelOrder(orderId: string, reason: string): Promise<Order> {
160
- const { data } = await storeManagementAxios.post<RawOrder>(`orders/${orderId}/cancel/`, { reason })
201
+ export async function cancelOrder(config: SdkConfig, accessToken: string, orderId: string, reason: string): Promise<Order> {
202
+ const response = await fetch(`${config.backendUrls.store}/orders/${orderId}/cancel/`, {
203
+ method: 'POST',
204
+ headers: {
205
+ 'Content-Type': 'application/json',
206
+ "Authorization": `Bearer ${accessToken}`,
207
+ "X-Storefront-Key": config.storefrontApiKey,
208
+ "X-Business-ID": config.businessId,
209
+ },
210
+ body: JSON.stringify({ reason }),
211
+ })
212
+ if (!response.ok) throw new Error('Failed to cancel order')
213
+ const data = await response.json()
161
214
  return normaliseStorefrontOrder(data)
162
215
  }
163
216
 
164
- export async function trackOrder(orderId: string, token?: string): Promise<Order> {
165
- const { data } = await publicStoreAxios.get<RawOrder>(`orders/track/${orderId}`, {
166
- params: token ? { token } : undefined
217
+ export async function trackOrder(config: SdkConfig, orderId: string, token?: string): Promise<Order> {
218
+ const queryParams = token ? `?token=${token}` : ''
219
+ const response = await fetch(`${config.backendUrls.store}/orders/track/${orderId}${queryParams}`, {
220
+ headers: {
221
+ "X-Storefront-Key": config.storefrontApiKey,
222
+ "X-Business-ID": config.businessId,
223
+ },
167
224
  })
225
+ if (!response.ok) throw new Error('Failed to track order')
226
+ const data = await response.json()
168
227
  return normaliseStorefrontOrder(data)
169
228
  }
@@ -2,8 +2,9 @@
2
2
  * Payment Service
3
3
  *
4
4
  * Customer-facing payment API for payment initiation and verification.
5
+ * Stateless - all configuration passed as parameters.
5
6
  */
6
- import { paymentAxios } from '../client/httpClient'
7
+ import type { SdkConfig } from '../config'
7
8
  import type {
8
9
  ConversionQuote,
9
10
  DVACreateRequest,
@@ -19,6 +20,8 @@ import type {
19
20
  * will reject non-NGN requests for this payment method.
20
21
  */
21
22
  export async function createDedicatedAccount(
23
+ config: SdkConfig,
24
+ accessToken: string,
22
25
  request: DVACreateRequest
23
26
  ): Promise<DVADetails> {
24
27
  const isValidUUID = (str: string) => {
@@ -26,17 +29,25 @@ export async function createDedicatedAccount(
26
29
  return uuidRegex.test(str);
27
30
  }
28
31
 
29
- const { data } = await paymentAxios.post<DVADetails>(
30
- 'payments/dedicated-account',
31
- {
32
+ const response = await fetch(`${config.backendUrls.payment}/payments/dedicated-account`, {
33
+ method: 'POST',
34
+ headers: {
35
+ 'Content-Type': 'application/json',
36
+ "Authorization": `Bearer ${accessToken}`,
37
+ "X-Storefront-Key": config.storefrontApiKey,
38
+ "X-Business-ID": config.businessId,
39
+ },
40
+ body: JSON.stringify({
32
41
  order_id: request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined,
33
42
  amount: request.amount,
34
43
  customer_email: request.customer_email,
35
44
  customer_name: request.customer_name,
36
45
  currency: request.currency,
37
46
  idempotency_key: request.idempotency_key,
38
- }
39
- )
47
+ }),
48
+ })
49
+ if (!response.ok) throw new Error('Failed to create dedicated account')
50
+ const data = await response.json()
40
51
  return data
41
52
  }
42
53
 
@@ -46,6 +57,8 @@ export async function createDedicatedAccount(
46
57
  * Returns a checkout_url to redirect the customer to the gateway.
47
58
  */
48
59
  export async function initiatePayment(
60
+ config: SdkConfig,
61
+ accessToken: string,
49
62
  request: PaymentInitiateRequest
50
63
  ): Promise<PaymentInitiateResponse> {
51
64
  const isValidUUID = (str: string) => {
@@ -55,25 +68,30 @@ export async function initiatePayment(
55
68
 
56
69
  const validOrderId = request.order_id && isValidUUID(request.order_id) ? request.order_id : undefined;
57
70
 
58
- const { data } = await paymentAxios.post<{
59
- id: string
60
- gateway_ref: string
61
- gateway: string
62
- status: string
63
- metadata_json?: { checkout_url?: string }
64
- }>('payments/storefront/initiate', {
65
- amount: request.amount,
66
- currency: request.currency,
67
- order_id: validOrderId,
68
- quote_id: request.quote_id,
69
- metadata_json: {
70
- customer_email: request.customer_email,
71
- customer_name: request.customer_name ?? '',
72
- order_id: validOrderId,
73
- ...(request.metadata ?? {}),
71
+ const response = await fetch(`${config.backendUrls.payment}/payments/storefront/initiate`, {
72
+ method: 'POST',
73
+ headers: {
74
+ 'Content-Type': 'application/json',
75
+ "Authorization": `Bearer ${accessToken}`,
76
+ "X-Storefront-Key": config.storefrontApiKey,
77
+ "X-Business-ID": config.businessId,
74
78
  },
75
- idempotency_key: request.idempotency_key,
79
+ body: JSON.stringify({
80
+ amount: request.amount,
81
+ currency: request.currency,
82
+ order_id: validOrderId,
83
+ quote_id: request.quote_id,
84
+ metadata_json: {
85
+ customer_email: request.customer_email,
86
+ customer_name: request.customer_name ?? '',
87
+ order_id: validOrderId,
88
+ ...(request.metadata ?? {}),
89
+ },
90
+ idempotency_key: request.idempotency_key,
91
+ }),
76
92
  })
93
+ if (!response.ok) throw new Error('Failed to initiate payment')
94
+ const data = await response.json()
77
95
 
78
96
  return {
79
97
  id: data.id,
@@ -88,9 +106,20 @@ export async function initiatePayment(
88
106
  * Request a 15-minute rate-locked conversion quote for non-NGN transactions.
89
107
  */
90
108
  export async function requestQuote(
109
+ config: SdkConfig,
91
110
  amount: number
92
111
  ): Promise<ConversionQuote> {
93
- const { data } = await paymentAxios.post<ConversionQuote>('payments/quote', { amount })
112
+ const response = await fetch(`${config.backendUrls.payment}/payments/quote`, {
113
+ method: 'POST',
114
+ headers: {
115
+ 'Content-Type': 'application/json',
116
+ "X-Storefront-Key": config.storefrontApiKey,
117
+ "X-Business-ID": config.businessId,
118
+ },
119
+ body: JSON.stringify({ amount }),
120
+ })
121
+ if (!response.ok) throw new Error('Failed to request quote')
122
+ const data = await response.json()
94
123
  return data
95
124
  }
96
125
 
@@ -98,11 +127,31 @@ export async function requestQuote(
98
127
  * Verify a payment after the gateway redirects back to /checkout/verify.
99
128
  */
100
129
  export async function verifyTransaction(
101
- reference: string
130
+ configOrReference: SdkConfig | string,
131
+ reference?: string
102
132
  ): Promise<TransactionVerifyResponse> {
103
- const { data } = await paymentAxios.post<TransactionVerifyResponse>(
104
- `payments/verify/${reference}`
105
- )
133
+ if (typeof configOrReference === 'string') {
134
+ const ref = configOrReference
135
+ const response = await fetch(`/api/payments/verify/${ref}`, {
136
+ method: 'POST',
137
+ headers: { 'Content-Type': 'application/json' },
138
+ })
139
+ if (!response.ok) throw new Error('Failed to verify transaction')
140
+ return response.json()
141
+ }
142
+
143
+ const config = configOrReference
144
+ const ref = reference || ''
145
+ const response = await fetch(`${config.backendUrls.payment}/payments/verify/${ref}`, {
146
+ method: 'POST',
147
+ headers: {
148
+ 'Content-Type': 'application/json',
149
+ "X-Storefront-Key": config.storefrontApiKey,
150
+ "X-Business-ID": config.businessId,
151
+ },
152
+ })
153
+ if (!response.ok) throw new Error('Failed to verify transaction')
154
+ const data = await response.json()
106
155
  return data
107
156
  }
108
157
 
@@ -110,11 +159,17 @@ export async function verifyTransaction(
110
159
  * Poll transaction status by internal transaction ID.
111
160
  */
112
161
  export async function getTransactionStatus(
162
+ config: SdkConfig,
113
163
  transactionId: string
114
164
  ): Promise<TransactionVerifyResponse> {
115
- const { data } = await paymentAxios.get<TransactionVerifyResponse>(
116
- `payments/transactions/${transactionId}`
117
- )
165
+ const response = await fetch(`${config.backendUrls.payment}/payments/transactions/${transactionId}`, {
166
+ headers: {
167
+ "X-Storefront-Key": config.storefrontApiKey,
168
+ "X-Business-ID": config.businessId,
169
+ },
170
+ })
171
+ if (!response.ok) throw new Error('Failed to get transaction status')
172
+ const data = await response.json()
118
173
  return data
119
174
  }
120
175