@applite/duticotac 0.0.1

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/dist/index.mjs ADDED
@@ -0,0 +1,308 @@
1
+ // src/utils/errors.ts
2
+ var ERROR_MESSAGES = {
3
+ "payment-failed": "\xC9chec du paiement",
4
+ "ref-or-idFromClient-required": "R\xE9f\xE9rence ou IDFromClient requis",
5
+ "product-not-found": "Produit non trouv\xE9",
6
+ "no-api-key": "Cl\xE9 API non fournie",
7
+ "phone-required": "Num\xE9ro de t\xE9l\xE9phone requis",
8
+ "iap-not-available": "Les achats in-app ne sont pas disponibles.",
9
+ "iap-purchase-failed": "Echec de l'achat",
10
+ "otp-required": "Code OTP requis pour les paiements Orange Money",
11
+ "app-not-found": "Application non trouv\xE9e dans AppLite UI",
12
+ "duticotac-setting-not-found": "Configuration Duticotac non trouv\xE9e",
13
+ "payment-method-not-activated": "M\xE9thode de paiement non activ\xE9e",
14
+ "no-provider-found": "M\xE9thode de paiement non activ\xE9e",
15
+ "customer-not-found": "Client non trouv\xE9",
16
+ "invalid-plateform": "Plateforme invalide",
17
+ "unknown-error": "Une erreur inconnue est survenue",
18
+ "reference-required": "R\xE9f\xE9rence requise",
19
+ "polling-timeout": "Temps d'attente de la transaction expir\xE9",
20
+ "payment-cancelled": "Paiement annul\xE9",
21
+ "wait-before-retry": "Veuillez attendre avant de r\xE9essayer",
22
+ "context-not-mounted": "Contexte non mont\xE9",
23
+ "show-modal-bottom-sheet-error": "Erreur lors de l'affichage de la fen\xEAtre modale"
24
+ };
25
+ function getErrorMessage(code) {
26
+ return ERROR_MESSAGES[code] ?? ERROR_MESSAGES["unknown-error"];
27
+ }
28
+
29
+ // src/errors.ts
30
+ var DuticotacError = class extends Error {
31
+ constructor(code, message) {
32
+ super(message ?? getErrorMessage(code));
33
+ this.code = code;
34
+ this.name = "DuticotacError";
35
+ }
36
+ };
37
+
38
+ // src/http.ts
39
+ var DEFAULT_BASE_URL = "https://api.applite.freddydro.dev";
40
+ var HttpClient = class {
41
+ constructor(config = {}) {
42
+ this.baseUrl = config.baseUrl?.replace(/\/$/, "") ?? DEFAULT_BASE_URL;
43
+ this.headers = config.headers ?? {};
44
+ this.fetchImpl = config.fetchFn ?? fetch;
45
+ this.apiKey = config.apiKey;
46
+ this.appId = config.appId;
47
+ }
48
+ async post(path, body) {
49
+ const mergedBody = {
50
+ ...this.apiKey ? { apiKey: this.apiKey } : {},
51
+ ...this.appId !== void 0 ? { appId: this.appId } : {},
52
+ ...body
53
+ };
54
+ const url = `${this.baseUrl}${path}`;
55
+ const response = await this.fetchImpl(url, {
56
+ method: "POST",
57
+ headers: {
58
+ "Content-Type": "application/json",
59
+ ...this.headers
60
+ },
61
+ body: JSON.stringify(mergedBody)
62
+ });
63
+ const contentType = response.headers.get("content-type") ?? "";
64
+ const isJson = contentType.includes("application/json");
65
+ const payload = isJson ? await response.json() : null;
66
+ if (!response.ok) {
67
+ const errorCode = typeof payload?.error === "string" ? payload.error : "unknown-error";
68
+ throw new DuticotacError(
69
+ errorCode,
70
+ `Request failed with status ${response.status}: ${payload?.error ?? response.statusText}`
71
+ );
72
+ }
73
+ if (!payload || payload.success !== true) {
74
+ const errorCode = typeof payload?.error === "string" ? payload.error : "unknown-error";
75
+ throw new DuticotacError(errorCode);
76
+ }
77
+ return payload;
78
+ }
79
+ };
80
+
81
+ // src/modules/balance.ts
82
+ var BalanceModule = class {
83
+ constructor(http) {
84
+ this.http = http;
85
+ }
86
+ balance(params = {}) {
87
+ return this.http.post("/duticotac/balance", params);
88
+ }
89
+ };
90
+
91
+ // src/modules/offer.ts
92
+ var OfferModule = class {
93
+ constructor(http) {
94
+ this.http = http;
95
+ }
96
+ create(params) {
97
+ return this.http.post("/duticotac/offer/create", params);
98
+ }
99
+ list(params = {}) {
100
+ return this.http.post("/duticotac/offer/list", params);
101
+ }
102
+ get(params) {
103
+ const { ref, ...body } = params;
104
+ return this.http.post(`/duticotac/offer/${ref}`, body);
105
+ }
106
+ update(params) {
107
+ const { ref, ...body } = params;
108
+ return this.http.post(`/duticotac/offer/${ref}/edit`, body);
109
+ }
110
+ delete(params) {
111
+ const { ref, ...body } = params;
112
+ return this.http.post(`/duticotac/offer/${ref}/delete`, body);
113
+ }
114
+ };
115
+
116
+ // src/modules/mobile-money.ts
117
+ var MobileMoneyModule = class {
118
+ constructor(http) {
119
+ this.http = http;
120
+ }
121
+ cashin(params) {
122
+ return this.http.post(
123
+ "/duticotac/pay/mobile-money/cashin",
124
+ params
125
+ );
126
+ }
127
+ cashout(params) {
128
+ if (params.paymentMethod === "OM_CI" && !params.otp) {
129
+ throw new DuticotacError("otp-required");
130
+ }
131
+ if (!params.ref && !params.idFromClient) {
132
+ throw new DuticotacError("ref-or-idFromClient-required");
133
+ }
134
+ return this.http.post(
135
+ "/duticotac/pay/mobile-money/cashout",
136
+ params
137
+ );
138
+ }
139
+ handleCashinWebhook(params) {
140
+ return this.http.post("/duticotac/pay/mobile-money/cashin/webhook", params);
141
+ }
142
+ handleCashoutWebhook(params) {
143
+ return this.http.post(
144
+ "/duticotac/pay/mobile-money/cashout/webhook",
145
+ params
146
+ );
147
+ }
148
+ };
149
+
150
+ // src/modules/payment-method.ts
151
+ var PaymentMethodModule = class {
152
+ constructor(http) {
153
+ this.http = http;
154
+ }
155
+ get(params = {}) {
156
+ return this.http.post(
157
+ "/duticotac/payment-method",
158
+ params
159
+ );
160
+ }
161
+ set(params) {
162
+ return this.http.post(
163
+ "/duticotac/payment-method/set",
164
+ params
165
+ );
166
+ }
167
+ };
168
+
169
+ // src/modules/webhook.ts
170
+ var WebhookModule = class {
171
+ constructor(http) {
172
+ this.http = http;
173
+ }
174
+ get(params = {}) {
175
+ return this.http.post("/duticotac/webhook", params);
176
+ }
177
+ set(params) {
178
+ return this.http.post("/duticotac/webhook/set", params);
179
+ }
180
+ };
181
+
182
+ // src/modules/transaction.ts
183
+ function backoff(attempt) {
184
+ switch (attempt) {
185
+ case 1:
186
+ return 1e3;
187
+ case 2:
188
+ return 2e3;
189
+ case 3:
190
+ return 3e3;
191
+ case 4:
192
+ return 5e3;
193
+ default:
194
+ return 8e3;
195
+ }
196
+ }
197
+ function delay(ms) {
198
+ return new Promise((resolve) => setTimeout(resolve, ms));
199
+ }
200
+ var TransactionModule = class {
201
+ constructor(http) {
202
+ this.http = http;
203
+ }
204
+ get(params) {
205
+ return this.http.post(
206
+ "/duticotac/transaction/get",
207
+ params
208
+ );
209
+ }
210
+ async poll(id, options) {
211
+ const intervalMs = options?.intervalMs ?? 2e3;
212
+ const timeoutMs = options?.timeoutMs ?? 9e4;
213
+ const start = Date.now();
214
+ let attempt = 0;
215
+ while (true) {
216
+ attempt++;
217
+ const elapsed = Date.now() - start;
218
+ if (elapsed > timeoutMs) {
219
+ throw new DuticotacError("polling-timeout");
220
+ }
221
+ if (options?.signal?.aborted) {
222
+ throw new DuticotacError("payment-cancelled");
223
+ }
224
+ options?.onPoll?.(attempt, elapsed);
225
+ try {
226
+ const result = await this.get({ id });
227
+ const status = result.data?.status;
228
+ if (status === "CONFIRMED") return result;
229
+ if (status === "CANCELLED") throw new DuticotacError("payment-cancelled");
230
+ if (status === "FAILED")
231
+ throw new DuticotacError("payment-failed");
232
+ const wait = Math.max(backoff(attempt), intervalMs);
233
+ await delay(wait);
234
+ } catch (e) {
235
+ if (e instanceof DuticotacError) throw e;
236
+ const wait = Math.max(backoff(attempt), intervalMs);
237
+ await delay(wait);
238
+ }
239
+ }
240
+ }
241
+ };
242
+
243
+ // src/utils/providers.ts
244
+ function getProviderName(provider) {
245
+ switch (provider) {
246
+ case "OM_CI":
247
+ return "Orange Money";
248
+ case "MTN_CI":
249
+ return "MTN Momo";
250
+ case "MOOV_CI":
251
+ return "Moov (Flooz)";
252
+ case "WAVE_CI":
253
+ return "Wave";
254
+ case "CREDIT_CARD":
255
+ return "Carte de cr\xE9dit";
256
+ case "CASH":
257
+ return "Esp\xE8ces";
258
+ case "IAP":
259
+ return "Achat Int\xE9gr\xE9";
260
+ }
261
+ }
262
+ function getProviderLogo(provider) {
263
+ switch (provider) {
264
+ case "OM_CI":
265
+ return "https://payto.freddydro.dev/images/OM.png";
266
+ case "MTN_CI":
267
+ return "https://payto.freddydro.dev/images/MTN.png";
268
+ case "MOOV_CI":
269
+ return "https://payto.freddydro.dev/images/MOOV.png";
270
+ case "WAVE_CI":
271
+ return "https://payto.freddydro.dev/images/WAVE.png";
272
+ case "CREDIT_CARD":
273
+ return "https://payto.freddydro.dev/images/CREDIT_CARD.png";
274
+ case "CASH":
275
+ return "https://payto.freddydro.dev/images/CASH.png";
276
+ case "IAP":
277
+ return "https://payto.freddydro.dev/images/IAP.png";
278
+ }
279
+ }
280
+
281
+ // src/index.ts
282
+ var DuticotacSDK = class {
283
+ constructor(config = {}) {
284
+ this.http = new HttpClient(config);
285
+ this.balance = new BalanceModule(this.http);
286
+ this.offer = new OfferModule(this.http);
287
+ this.mobileMoney = new MobileMoneyModule(this.http);
288
+ this.paymentMethod = new PaymentMethodModule(this.http);
289
+ this.webhook = new WebhookModule(this.http);
290
+ this.transaction = new TransactionModule(this.http);
291
+ }
292
+ };
293
+ export {
294
+ BalanceModule,
295
+ DuticotacError,
296
+ DuticotacSDK,
297
+ ERROR_MESSAGES,
298
+ HttpClient,
299
+ MobileMoneyModule,
300
+ OfferModule,
301
+ PaymentMethodModule,
302
+ TransactionModule,
303
+ WebhookModule,
304
+ getErrorMessage,
305
+ getProviderLogo,
306
+ getProviderName
307
+ };
308
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/errors.ts","../src/errors.ts","../src/http.ts","../src/modules/balance.ts","../src/modules/offer.ts","../src/modules/mobile-money.ts","../src/modules/payment-method.ts","../src/modules/webhook.ts","../src/modules/transaction.ts","../src/utils/providers.ts","../src/index.ts"],"sourcesContent":["export const ERROR_MESSAGES: Record<string, string> = {\n \"payment-failed\": \"Échec du paiement\",\n \"ref-or-idFromClient-required\": \"Référence ou IDFromClient requis\",\n \"product-not-found\": \"Produit non trouvé\",\n \"no-api-key\": \"Clé API non fournie\",\n \"phone-required\": \"Numéro de téléphone requis\",\n \"iap-not-available\": \"Les achats in-app ne sont pas disponibles.\",\n \"iap-purchase-failed\": \"Echec de l'achat\",\n \"otp-required\": \"Code OTP requis pour les paiements Orange Money\",\n \"app-not-found\": \"Application non trouvée dans AppLite UI\",\n \"duticotac-setting-not-found\": \"Configuration Duticotac non trouvée\",\n \"payment-method-not-activated\": \"Méthode de paiement non activée\",\n \"no-provider-found\": \"Méthode de paiement non activée\",\n \"customer-not-found\": \"Client non trouvé\",\n \"invalid-plateform\": \"Plateforme invalide\",\n \"unknown-error\": \"Une erreur inconnue est survenue\",\n \"reference-required\": \"Référence requise\",\n \"polling-timeout\": \"Temps d'attente de la transaction expiré\",\n \"payment-cancelled\": \"Paiement annulé\",\n \"wait-before-retry\": \"Veuillez attendre avant de réessayer\",\n \"context-not-mounted\": \"Contexte non monté\",\n \"show-modal-bottom-sheet-error\":\n \"Erreur lors de l'affichage de la fenêtre modale\",\n};\n\nexport function getErrorMessage(code: string): string {\n return ERROR_MESSAGES[code] ?? ERROR_MESSAGES[\"unknown-error\"]!;\n}\n","import { getErrorMessage } from \"./utils/errors\";\n\nexport class DuticotacError extends Error {\n readonly code: string;\n\n constructor(code: string, message?: string) {\n super(message ?? getErrorMessage(code));\n this.code = code;\n this.name = \"DuticotacError\";\n }\n}\n","import { DuticotacError } from \"./errors\";\n\nexport interface HttpClientConfig {\n /**\n * Base URL used for every request.\n * Defaults to `https://api.applite.freddydro.dev`.\n */\n baseUrl?: string;\n /**\n * Optional headers that should be sent with every request.\n */\n headers?: HeadersInit;\n /**\n * Custom fetch implementation for environments where the global fetch is\n * not available or needs to be mocked during testing.\n */\n fetchFn?: typeof fetch;\n /**\n * API key injected into every request body automatically.\n */\n apiKey?: string;\n /**\n * Optional app ID injected into every request body automatically.\n */\n appId?: string | null;\n}\n\nexport interface ApiSuccessResponse<T> {\n success: true;\n data: T;\n error?: unknown;\n}\n\nexport interface ApiErrorResponse {\n success: false;\n error?: unknown;\n}\n\nexport type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;\n\nconst DEFAULT_BASE_URL = \"https://api.applite.freddydro.dev\";\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly headers: HeadersInit;\n private readonly fetchImpl: typeof fetch;\n private readonly apiKey?: string;\n private readonly appId?: string | null;\n\n constructor(config: HttpClientConfig = {}) {\n this.baseUrl = config.baseUrl?.replace(/\\/$/, \"\") ?? DEFAULT_BASE_URL;\n this.headers = config.headers ?? {};\n this.fetchImpl = config.fetchFn ?? fetch;\n this.apiKey = config.apiKey;\n this.appId = config.appId;\n }\n\n async post<T>(\n path: string,\n body: Record<string, unknown> | object,\n ): Promise<ApiSuccessResponse<T>> {\n const mergedBody: Record<string, unknown> = {\n ...(this.apiKey ? { apiKey: this.apiKey } : {}),\n ...(this.appId !== undefined ? { appId: this.appId } : {}),\n ...(body as Record<string, unknown>),\n };\n\n const url = `${this.baseUrl}${path}`;\n const response = await this.fetchImpl(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.headers,\n },\n body: JSON.stringify(mergedBody),\n });\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n const isJson = contentType.includes(\"application/json\");\n const payload: ApiResponse<T> | null = isJson\n ? await response.json()\n : null;\n\n if (!response.ok) {\n const errorCode =\n typeof payload?.error === \"string\" ? payload.error : \"unknown-error\";\n throw new DuticotacError(\n errorCode,\n `Request failed with status ${response.status}: ${payload?.error ?? response.statusText}`,\n );\n }\n\n if (!payload || payload.success !== true) {\n const errorCode =\n typeof payload?.error === \"string\" ? payload.error : \"unknown-error\";\n throw new DuticotacError(errorCode);\n }\n\n return payload;\n }\n}\n","import { HttpClient, ApiSuccessResponse } from \"../http\";\n\nexport interface GetBalanceParams {\n apiKey?: string;\n appId?: string | null;\n}\n\nexport class BalanceModule {\n constructor(private readonly http: HttpClient) {}\n\n balance(\n params: GetBalanceParams = {},\n ): Promise<ApiSuccessResponse<number | null>> {\n return this.http.post<number | null>(\"/duticotac/balance\", params);\n }\n}\n","import { HttpClient, ApiSuccessResponse } from \"../http\";\nimport type { PlatformType, DuTicOTacOfferType } from \"../models/enums\";\nimport type { OfferModel } from \"../models/offer\";\n\nexport interface CreateOfferParams {\n apiKey?: string;\n appId?: string | null;\n name: string;\n ref: string;\n price: number;\n platform: PlatformType;\n type?: DuTicOTacOfferType;\n description?: string | null;\n}\n\nexport interface ListOffersParams {\n apiKey?: string;\n appId?: string | null;\n}\n\nexport interface GetOfferByRefParams {\n apiKey?: string;\n ref: string;\n appId?: string | null;\n}\n\nexport interface UpdateOfferParams {\n apiKey?: string;\n ref: string;\n appId?: string | null;\n name?: string | null;\n price?: number | null;\n type?: DuTicOTacOfferType | null;\n description?: string | null;\n platform?: PlatformType | null;\n}\n\nexport interface DeleteOfferParams {\n apiKey?: string;\n ref: string;\n appId?: string | null;\n}\n\nexport class OfferModule {\n constructor(private readonly http: HttpClient) {}\n\n create(params: CreateOfferParams): Promise<ApiSuccessResponse<OfferModel>> {\n return this.http.post<OfferModel>(\"/duticotac/offer/create\", params);\n }\n\n list(params: ListOffersParams = {}): Promise<ApiSuccessResponse<OfferModel[]>> {\n return this.http.post<OfferModel[]>(\"/duticotac/offer/list\", params);\n }\n\n get(params: GetOfferByRefParams): Promise<ApiSuccessResponse<OfferModel>> {\n const { ref, ...body } = params;\n return this.http.post<OfferModel>(`/duticotac/offer/${ref}`, body);\n }\n\n update(params: UpdateOfferParams): Promise<ApiSuccessResponse<OfferModel>> {\n const { ref, ...body } = params;\n return this.http.post<OfferModel>(`/duticotac/offer/${ref}/edit`, body);\n }\n\n delete(params: DeleteOfferParams): Promise<ApiSuccessResponse<unknown>> {\n const { ref, ...body } = params;\n return this.http.post(`/duticotac/offer/${ref}/delete`, body);\n }\n}\n","import { HttpClient, ApiSuccessResponse } from \"../http\";\nimport { DuticotacError } from \"../errors\";\nimport type { PlatformType, PaymentProvider, CoreApp } from \"../models/enums\";\nimport type { TransactionModel } from \"../models/transaction\";\n\nexport interface CashInParams {\n apiKey?: string;\n appId?: string | null;\n amount: number;\n phone: string;\n paymentMethod: PaymentProvider;\n password: string;\n country?: string;\n currency?: string;\n}\n\nexport interface CashOutParams {\n apiKey?: string;\n appId?: string | null;\n transactionId: string;\n amount?: number | null;\n ref?: string;\n phone: string;\n name: string;\n email: string;\n otp?: string | null;\n paymentMethod: PaymentProvider;\n plateform?: PlatformType;\n customerId?: string | null;\n kolaboReference?: string | null;\n idFromClient?: string | null;\n app?: CoreApp;\n country?: string;\n currency?: string;\n}\n\nexport interface CashInWebhookParams {\n apiKey?: string;\n appId?: string | null;\n service_id: string;\n gu_transaction_id: string;\n status: \"FAILED\" | \"SUCCESSFUL\";\n partner_transaction_id: string;\n call_back_url: string;\n commission?: number | null;\n message?: string | null;\n}\n\nexport interface CashOutWebhookParams {\n apiKey?: string;\n appId?: string | null;\n service_id: string;\n gu_transaction_id: string;\n status: \"FAILED\" | \"SUCCESSFUL\";\n partner_transaction_id: string;\n call_back_url: string;\n commission?: number | null;\n message?: string | null;\n}\n\nexport class MobileMoneyModule {\n constructor(private readonly http: HttpClient) {}\n\n cashin(params: CashInParams): Promise<ApiSuccessResponse<TransactionModel>> {\n return this.http.post<TransactionModel>(\n \"/duticotac/pay/mobile-money/cashin\",\n params,\n );\n }\n\n cashout(\n params: CashOutParams,\n ): Promise<ApiSuccessResponse<TransactionModel>> {\n if (params.paymentMethod === \"OM_CI\" && !params.otp) {\n throw new DuticotacError(\"otp-required\");\n }\n if (!params.ref && !params.idFromClient) {\n throw new DuticotacError(\"ref-or-idFromClient-required\");\n }\n return this.http.post<TransactionModel>(\n \"/duticotac/pay/mobile-money/cashout\",\n params,\n );\n }\n\n handleCashinWebhook(\n params: CashInWebhookParams,\n ): Promise<ApiSuccessResponse<unknown>> {\n return this.http.post(\"/duticotac/pay/mobile-money/cashin/webhook\", params);\n }\n\n handleCashoutWebhook(\n params: CashOutWebhookParams,\n ): Promise<ApiSuccessResponse<unknown>> {\n return this.http.post(\n \"/duticotac/pay/mobile-money/cashout/webhook\",\n params,\n );\n }\n}\n","import { HttpClient, ApiSuccessResponse } from \"../http\";\nimport type { PaymentProvider } from \"../models/enums\";\n\nexport interface GetPaymentMethodsParams {\n apiKey?: string;\n appId?: string | null;\n}\n\nexport interface SetPaymentMethodsParams {\n apiKey?: string;\n appId?: string | null;\n providers: PaymentProvider[];\n}\n\nexport class PaymentMethodModule {\n constructor(private readonly http: HttpClient) {}\n\n get(\n params: GetPaymentMethodsParams = {},\n ): Promise<ApiSuccessResponse<PaymentProvider[]>> {\n return this.http.post<PaymentProvider[]>(\n \"/duticotac/payment-method\",\n params,\n );\n }\n\n set(\n params: SetPaymentMethodsParams,\n ): Promise<ApiSuccessResponse<PaymentProvider[]>> {\n return this.http.post<PaymentProvider[]>(\n \"/duticotac/payment-method/set\",\n params,\n );\n }\n}\n","import { HttpClient, ApiSuccessResponse } from \"../http\";\n\nexport interface GetWebhookParams {\n apiKey?: string;\n appId?: string | null;\n}\n\nexport interface SetWebhookParams {\n apiKey?: string;\n appId?: string | null;\n url: string;\n}\n\nexport class WebhookModule {\n constructor(private readonly http: HttpClient) {}\n\n get(params: GetWebhookParams = {}): Promise<ApiSuccessResponse<string>> {\n return this.http.post<string>(\"/duticotac/webhook\", params);\n }\n\n set(params: SetWebhookParams): Promise<ApiSuccessResponse<unknown>> {\n return this.http.post(\"/duticotac/webhook/set\", params);\n }\n}\n","import { HttpClient, ApiSuccessResponse } from \"../http\";\nimport { DuticotacError } from \"../errors\";\nimport type { TransactionModel } from \"../models/transaction\";\n\nexport interface GetTransactionParams {\n id: string;\n}\n\nexport interface PollOptions {\n /** Minimum interval between polls in ms. Default: 2000 */\n intervalMs?: number;\n /** Total timeout in ms. Default: 90000 (90s) */\n timeoutMs?: number;\n /** Called on each poll attempt */\n onPoll?: (attempt: number, elapsedMs: number) => void;\n /** AbortSignal to cancel polling externally */\n signal?: AbortSignal;\n}\n\nfunction backoff(attempt: number): number {\n switch (attempt) {\n case 1:\n return 1000;\n case 2:\n return 2000;\n case 3:\n return 3000;\n case 4:\n return 5000;\n default:\n return 8000;\n }\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport class TransactionModule {\n constructor(private readonly http: HttpClient) {}\n\n get(\n params: GetTransactionParams,\n ): Promise<ApiSuccessResponse<TransactionModel>> {\n return this.http.post<TransactionModel>(\n \"/duticotac/transaction/get\",\n params,\n );\n }\n\n async poll(\n id: string,\n options?: PollOptions,\n ): Promise<ApiSuccessResponse<TransactionModel>> {\n const intervalMs = options?.intervalMs ?? 2000;\n const timeoutMs = options?.timeoutMs ?? 90_000;\n const start = Date.now();\n let attempt = 0;\n\n while (true) {\n attempt++;\n const elapsed = Date.now() - start;\n\n if (elapsed > timeoutMs) {\n throw new DuticotacError(\"polling-timeout\");\n }\n\n if (options?.signal?.aborted) {\n throw new DuticotacError(\"payment-cancelled\");\n }\n\n options?.onPoll?.(attempt, elapsed);\n\n try {\n const result = await this.get({ id });\n const status = result.data?.status;\n\n if (status === \"CONFIRMED\") return result;\n if (status === \"CANCELLED\") throw new DuticotacError(\"payment-cancelled\");\n if (status === \"FAILED\")\n throw new DuticotacError(\"payment-failed\");\n\n const wait = Math.max(backoff(attempt), intervalMs);\n await delay(wait);\n } catch (e) {\n if (e instanceof DuticotacError) throw e;\n const wait = Math.max(backoff(attempt), intervalMs);\n await delay(wait);\n }\n }\n }\n}\n","import type { PaymentProvider } from \"../models/enums\";\n\nexport function getProviderName(provider: PaymentProvider): string {\n switch (provider) {\n case \"OM_CI\":\n return \"Orange Money\";\n case \"MTN_CI\":\n return \"MTN Momo\";\n case \"MOOV_CI\":\n return \"Moov (Flooz)\";\n case \"WAVE_CI\":\n return \"Wave\";\n case \"CREDIT_CARD\":\n return \"Carte de crédit\";\n case \"CASH\":\n return \"Espèces\";\n case \"IAP\":\n return \"Achat Intégré\";\n }\n}\n\nexport function getProviderLogo(provider: PaymentProvider): string {\n switch (provider) {\n case \"OM_CI\":\n return \"https://payto.freddydro.dev/images/OM.png\";\n case \"MTN_CI\":\n return \"https://payto.freddydro.dev/images/MTN.png\";\n case \"MOOV_CI\":\n return \"https://payto.freddydro.dev/images/MOOV.png\";\n case \"WAVE_CI\":\n return \"https://payto.freddydro.dev/images/WAVE.png\";\n case \"CREDIT_CARD\":\n return \"https://payto.freddydro.dev/images/CREDIT_CARD.png\";\n case \"CASH\":\n return \"https://payto.freddydro.dev/images/CASH.png\";\n case \"IAP\":\n return \"https://payto.freddydro.dev/images/IAP.png\";\n }\n}\n","import { HttpClient, HttpClientConfig } from \"./http\";\nimport { BalanceModule } from \"./modules/balance\";\nimport { OfferModule } from \"./modules/offer\";\nimport { MobileMoneyModule } from \"./modules/mobile-money\";\nimport { PaymentMethodModule } from \"./modules/payment-method\";\nimport { WebhookModule } from \"./modules/webhook\";\nimport { TransactionModule } from \"./modules/transaction\";\n\nexport interface DuticotacSDKConfig extends HttpClientConfig {}\n\nexport class DuticotacSDK {\n readonly http: HttpClient;\n readonly balance: BalanceModule;\n readonly offer: OfferModule;\n readonly mobileMoney: MobileMoneyModule;\n readonly paymentMethod: PaymentMethodModule;\n readonly webhook: WebhookModule;\n readonly transaction: TransactionModule;\n\n constructor(config: DuticotacSDKConfig = {}) {\n this.http = new HttpClient(config);\n\n this.balance = new BalanceModule(this.http);\n this.offer = new OfferModule(this.http);\n this.mobileMoney = new MobileMoneyModule(this.http);\n this.paymentMethod = new PaymentMethodModule(this.http);\n this.webhook = new WebhookModule(this.http);\n this.transaction = new TransactionModule(this.http);\n }\n}\n\nexport * from \"./http\";\nexport * from \"./errors\";\nexport * from \"./models\";\nexport * from \"./utils\";\nexport * from \"./modules/balance\";\nexport * from \"./modules/offer\";\nexport * from \"./modules/mobile-money\";\nexport * from \"./modules/payment-method\";\nexport * from \"./modules/webhook\";\nexport * from \"./modules/transaction\";\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@applite/duticotac",
3
+ "version": "0.0.1",
4
+ "main": "./dist/index.cjs",
5
+ "module": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "sideEffects": false,
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "test": "tsup --dts"
22
+ },
23
+ "devDependencies": {
24
+ "@applite/typescript-config": "workspace:*",
25
+ "@types/node": "^24.1.0",
26
+ "tsup": "^8.5.1",
27
+ "typescript": "^5.8.3"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
32
+ }
33
+