@applite/duticotac-react 0.0.5 → 0.0.7
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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +30 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { TransactionModel, DuticotacSDK, PaymentProvider, CoreApp, PlatformType } from '@applite/duticotac';
|
|
4
|
+
export * from '@applite/duticotac';
|
|
4
5
|
import { ClassValue } from 'clsx';
|
|
5
6
|
|
|
6
7
|
interface DuticotacPaymentModalProps {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { TransactionModel, DuticotacSDK, PaymentProvider, CoreApp, PlatformType } from '@applite/duticotac';
|
|
4
|
+
export * from '@applite/duticotac';
|
|
4
5
|
import { ClassValue } from 'clsx';
|
|
5
6
|
|
|
6
7
|
interface DuticotacPaymentModalProps {
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
21
21
|
}
|
|
22
22
|
return to;
|
|
23
23
|
};
|
|
24
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
24
25
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
26
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
27
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -1276,6 +1277,9 @@ function useDuticotac(config) {
|
|
|
1276
1277
|
Dialog: DialogElement
|
|
1277
1278
|
};
|
|
1278
1279
|
}
|
|
1280
|
+
|
|
1281
|
+
// src/index.ts
|
|
1282
|
+
__reExport(index_exports, __toESM(require_dist()), module.exports);
|
|
1279
1283
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1280
1284
|
0 && (module.exports = {
|
|
1281
1285
|
DuticotacPaymentModal,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/index.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/http.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/balance.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/offer.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/mobile-money.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/payment-method.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/webhook.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/transaction.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/providers.ts","../src/index.ts","../src/components/payment-modal.tsx","../src/components/provider-selector.tsx","../src/utils/cn.ts","../src/components/phone-input.tsx","../src/components/otp-input.tsx","../src/components/transaction-status.tsx","../src/utils/format.ts","../src/utils/validation.ts","../src/components/responsive-dialog.tsx","../src/hooks/use-duticotac.tsx"],"sourcesContent":["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","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","// Components\nexport { DuticotacPaymentModal } from \"./components/payment-modal\";\nexport type { DuticotacPaymentModalProps } from \"./components/payment-modal\";\n\nexport { ProviderSelector } from \"./components/provider-selector\";\nexport type { ProviderSelectorProps } from \"./components/provider-selector\";\n\nexport { PhoneInput } from \"./components/phone-input\";\nexport type { PhoneInputProps } from \"./components/phone-input\";\n\nexport { OtpInput } from \"./components/otp-input\";\nexport type { OtpInputProps } from \"./components/otp-input\";\n\nexport { TransactionStatus } from \"./components/transaction-status\";\nexport type { TransactionStatusProps } from \"./components/transaction-status\";\n\nexport { ResponsiveDialog } from \"./components/responsive-dialog\";\nexport type { ResponsiveDialogProps } from \"./components/responsive-dialog\";\n\n// Hooks\nexport { useDuticotac } from \"./hooks/use-duticotac\";\nexport type {\n UseDuticotacConfig,\n UseDuticotacReturn,\n PayOptions,\n} from \"./hooks/use-duticotac\";\n\n// Utilities\nexport { cn } from \"./utils/cn\";\nexport { formatCFA } from \"./utils/format\";\nexport {\n getPhoneRegex,\n validatePhone,\n normalizePhone,\n needsOtp,\n} from \"./utils/validation\";\n","import * as React from \"react\";\nimport {\n DuticotacSDK,\n DuticotacError,\n getErrorMessage,\n} from \"@applite/duticotac\";\nimport type {\n PaymentProvider,\n TransactionModel,\n CoreApp,\n PlatformType,\n} from \"@applite/duticotac\";\nimport { ProviderSelector } from \"./provider-selector\";\nimport { PhoneInput } from \"./phone-input\";\nimport { OtpInput } from \"./otp-input\";\nimport { TransactionStatus } from \"./transaction-status\";\nimport { cn } from \"../utils/cn\";\nimport { formatCFA } from \"../utils/format\";\nimport { validatePhone, normalizePhone, needsOtp } from \"../utils/validation\";\n\n// ─── Polling helpers ─────────────────────────────────────────────────────────\n\nfunction waitForVisibility(signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\" || document.visibilityState === \"visible\") {\n resolve();\n return;\n }\n const handler = () => {\n if (document.visibilityState === \"visible\") {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n }\n };\n document.addEventListener(\"visibilitychange\", handler);\n signal?.addEventListener(\"abort\", () => {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n });\n });\n}\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Step = \"form\" | \"confirming\" | \"success\" | \"error\";\n\nexport interface DuticotacPaymentModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** SDK instance or config to create one. */\n sdk: DuticotacSDK;\n\n /** Amount in the smallest currency unit. */\n amount: number;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Product reference for the cashout. */\n productReference?: string;\n\n /** Pre-fill phone number. */\n initialPhone?: string;\n\n /** Customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Custom title. */\n title?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Additional class names for the modal container. */\n className?: string;\n\n /**\n * Render prop for the modal wrapper. Receives children and renders them\n * inside your dialog/modal component. If not provided, a simple overlay is used.\n */\n renderModal?: (props: {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n }) => React.ReactNode;\n}\n\nconst DEFAULT_PROVIDERS: PaymentProvider[] = [\n \"OM_CI\",\n \"MTN_CI\",\n \"MOOV_CI\",\n \"WAVE_CI\",\n];\n\nexport function DuticotacPaymentModal({\n open,\n onClose,\n onSuccess,\n sdk,\n amount,\n providers = DEFAULT_PROVIDERS,\n getTransactionId,\n productReference,\n initialPhone = \"\",\n name: customerName,\n email: customerEmail,\n customerId,\n kolaboReference,\n app,\n platform,\n successMessage,\n title = \"Paiement\",\n pollTimeout = 90_000,\n className,\n renderModal,\n}: DuticotacPaymentModalProps) {\n const [step, setStep] = React.useState<Step>(\"form\");\n const [provider, setProvider] = React.useState<PaymentProvider>(providers[0]!);\n const [phone, setPhone] = React.useState(initialPhone);\n const [otp, setOtp] = React.useState(\"\");\n const [phoneError, setPhoneError] = React.useState<string | null>(null);\n const [errorMessage, setErrorMessage] = React.useState(\"\");\n const [paymentUrl, setPaymentUrl] = React.useState<string | null>(null);\n const [elapsedSeconds, setElapsedSeconds] = React.useState(0);\n const [lastTransaction, setLastTransaction] = React.useState<TransactionModel | null>(null);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const elapsedRef = React.useRef<ReturnType<typeof setInterval> | null>(null);\n\n const cleanup = React.useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = null;\n if (elapsedRef.current) {\n clearInterval(elapsedRef.current);\n elapsedRef.current = null;\n }\n }, []);\n\n React.useEffect(() => {\n if (open) {\n setStep(\"form\");\n setErrorMessage(\"\");\n setOtp(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n setPhoneError(null);\n setLastTransaction(null);\n } else {\n cleanup();\n }\n }, [open, cleanup]);\n\n React.useEffect(() => () => cleanup(), [cleanup]);\n\n const isFormValid =\n phone.replace(/\\s/g, \"\").length >= 8 &&\n (needsOtp(provider) ? otp.length === 4 : true);\n\n const handleSubmit = async () => {\n // Validate phone\n const phoneErr = validatePhone(phone, provider);\n if (phoneErr) {\n setPhoneError(phoneErr);\n return;\n }\n setPhoneError(null);\n\n setStep(\"confirming\");\n setErrorMessage(\"\");\n cleanup();\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const transactionId = await getTransactionId();\n\n const result = await sdk.mobileMoney.cashout({\n transactionId,\n ref: productReference,\n phone: normalizePhone(phone),\n name: customerName ?? \"Duticotac App\",\n email: customerEmail ?? \"\",\n paymentMethod: provider,\n amount,\n otp: needsOtp(provider) ? otp : undefined,\n customerId,\n kolaboReference,\n app,\n plateform: platform,\n });\n\n const tx = result.data;\n\n if (tx?.paymentUrl) {\n setPaymentUrl(tx.paymentUrl);\n try {\n window.open(tx.paymentUrl, \"_blank\");\n } catch {\n // Popup may be blocked\n }\n }\n\n // Start polling\n const startTime = Date.now();\n setElapsedSeconds(0);\n elapsedRef.current = setInterval(() => {\n setElapsedSeconds(Math.floor((Date.now() - startTime) / 1000));\n }, 1000);\n\n const confirmed = await sdk.transaction.poll(tx.id ?? transactionId, {\n timeoutMs: pollTimeout,\n signal: controller.signal,\n onPoll: () => {\n // Wait for visibility before each poll\n },\n });\n\n setLastTransaction(confirmed.data);\n setStep(\"success\");\n onSuccess?.(confirmed.data);\n } catch (e) {\n if (controller.signal.aborted) return;\n\n if (e instanceof DuticotacError) {\n setErrorMessage(e.message);\n } else {\n setErrorMessage(\n getErrorMessage(\"unknown-error\"),\n );\n }\n setStep(\"error\");\n }\n };\n\n const handleRetry = () => {\n setStep(\"form\");\n setErrorMessage(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n };\n\n // ─── Content ──────────────────────────────────────────────────────────────\n\n const content = (\n <div className={cn(\"space-y-5\", className)}>\n {step === \"form\" && (\n <>\n {/* Offer summary */}\n <div className=\"rounded-lg border-l-4 border-l-primary bg-muted/50 p-4\">\n <p className=\"text-xs text-muted-foreground\">Montant</p>\n <p className=\"text-xl font-bold text-primary\">\n {formatCFA(amount)} FCFA\n </p>\n </div>\n\n {/* Provider selection */}\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold text-foreground\">\n Moyen de paiement\n </p>\n <ProviderSelector\n providers={providers}\n value={provider}\n onChange={(p) => {\n setProvider(p);\n if (!needsOtp(p)) setOtp(\"\");\n }}\n />\n </div>\n\n {/* Phone input */}\n <PhoneInput\n value={phone}\n onChange={(v) => {\n setPhone(v);\n setPhoneError(null);\n }}\n error={phoneError}\n autoFocus\n />\n\n {/* OTP input (Orange Money only) */}\n {needsOtp(provider) && (\n <OtpInput value={otp} onChange={setOtp} />\n )}\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Annuler\n </button>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!isFormValid}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\"\n >\n Payer {formatCFA(amount)} FCFA\n </button>\n </div>\n </>\n )}\n\n {step === \"confirming\" && (\n <TransactionStatus\n status=\"polling\"\n elapsedSeconds={elapsedSeconds}\n paymentUrl={paymentUrl}\n onOpenPaymentUrl={() => {\n if (paymentUrl) window.open(paymentUrl, \"_blank\");\n }}\n onClose={onClose}\n />\n )}\n\n {step === \"success\" && (\n <TransactionStatus\n status=\"success\"\n message={successMessage ?? \"Le paiement a ete effectue avec succes.\"}\n onClose={onClose}\n />\n )}\n\n {step === \"error\" && (\n <TransactionStatus\n status=\"error\"\n errorMessage={errorMessage}\n onRetry={handleRetry}\n onClose={onClose}\n />\n )}\n </div>\n );\n\n // ─── Render ───────────────────────────────────────────────────────────────\n\n if (renderModal) {\n return <>{renderModal({ open, onClose, title, children: content })}</>;\n }\n\n // Default simple overlay modal\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black/50\"\n onClick={onClose}\n />\n <div className=\"relative z-10 w-full max-w-md rounded-xl border border-border bg-background p-6 shadow-xl\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-bold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {content}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport type { PaymentProvider } from \"@applite/duticotac\";\nimport { getProviderName, getProviderLogo } from \"@applite/duticotac\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ProviderSelectorProps {\n providers: PaymentProvider[];\n value: PaymentProvider;\n onChange: (provider: PaymentProvider) => void;\n disabled?: boolean;\n className?: string;\n}\n\nexport function ProviderSelector({\n providers,\n value,\n onChange,\n disabled,\n className,\n}: ProviderSelectorProps) {\n return (\n <div className={cn(\"grid gap-2\", className)} style={{\n gridTemplateColumns: `repeat(${Math.min(providers.length, 4)}, 1fr)`,\n }}>\n {providers.map((provider) => {\n const selected = value === provider;\n return (\n <button\n key={provider}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(provider)}\n className={cn(\n \"relative flex flex-col items-center gap-2 rounded-lg border-2 p-3 transition-all\",\n \"hover:scale-[1.02] disabled:pointer-events-none disabled:opacity-50\",\n selected\n ? \"border-primary bg-primary/5 shadow-sm\"\n : \"border-border bg-background hover:border-primary/40\",\n )}\n >\n {selected && (\n <div className=\"absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-primary\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n )}\n <img\n src={getProviderLogo(provider)}\n alt={getProviderName(provider)}\n width={44}\n height={44}\n className=\"rounded-lg object-contain\"\n />\n <span\n className={cn(\n \"text-center text-xs leading-tight\",\n selected\n ? \"font-semibold text-primary\"\n : \"font-medium text-muted-foreground\",\n )}\n >\n {getProviderName(provider)}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface PhoneInputProps {\n value: string;\n onChange: (value: string) => void;\n label?: string;\n placeholder?: string;\n error?: string | null;\n disabled?: boolean;\n className?: string;\n autoFocus?: boolean;\n}\n\nexport function PhoneInput({\n value,\n onChange,\n label = \"Numero de telephone\",\n placeholder = \"07 01 02 03 04\",\n error,\n disabled,\n className,\n autoFocus,\n}: PhoneInputProps) {\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {label && (\n <label className=\"block text-sm font-semibold text-foreground\">\n {label}\n </label>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-10 items-center rounded-md border border-border bg-muted px-3 text-sm font-medium text-muted-foreground\">\n +225\n </div>\n <input\n type=\"tel\"\n inputMode=\"numeric\"\n value={value}\n onChange={(e) => {\n const cleaned = e.target.value.replace(/[^\\d\\s]/g, \"\");\n onChange(cleaned);\n }}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={autoFocus}\n className={cn(\n \"h-10 w-full rounded-md border bg-background px-3 text-sm font-medium outline-none transition-colors\",\n \"placeholder:text-muted-foreground/50\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n error ? \"border-destructive\" : \"border-border\",\n )}\n />\n </div>\n {error && (\n <p className=\"text-xs font-medium text-destructive\">{error}</p>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface OtpInputProps {\n value: string;\n onChange: (value: string) => void;\n length?: number;\n disabled?: boolean;\n className?: string;\n}\n\nexport function OtpInput({\n value,\n onChange,\n length = 4,\n disabled,\n className,\n}: OtpInputProps) {\n const inputRefs = React.useRef<(HTMLInputElement | null)[]>([]);\n const digits = value.padEnd(length, \"\").slice(0, length).split(\"\");\n\n const setDigit = (index: number, char: string) => {\n const next = [...digits];\n next[index] = char;\n onChange(next.join(\"\"));\n };\n\n const handleKeyDown = (\n index: number,\n e: React.KeyboardEvent<HTMLInputElement>,\n ) => {\n if (e.key === \"Backspace\") {\n e.preventDefault();\n if (digits[index]?.trim()) {\n setDigit(index, \"\");\n } else if (index > 0) {\n setDigit(index - 1, \"\");\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === \"ArrowLeft\" && index > 0) {\n inputRefs.current[index - 1]?.focus();\n } else if (e.key === \"ArrowRight\" && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleInput = (\n index: number,\n e: React.FormEvent<HTMLInputElement>,\n ) => {\n const val = (e.target as HTMLInputElement).value;\n const char = val.replace(/\\D/g, \"\").slice(-1);\n if (!char) return;\n setDigit(index, char);\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault();\n const pasted = e.clipboardData\n .getData(\"text\")\n .replace(/\\D/g, \"\")\n .slice(0, length);\n if (!pasted) return;\n onChange(pasted.padEnd(length, \"\").slice(0, length).replace(/ /g, \"\"));\n const focusIndex = Math.min(pasted.length, length - 1);\n inputRefs.current[focusIndex]?.focus();\n };\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n <label className=\"block text-sm font-semibold text-muted-foreground\">\n Code OTP\n </label>\n <div className=\"flex justify-center gap-3\" onPaste={handlePaste}>\n {Array.from({ length }).map((_, i) => {\n const filled = !!digits[i]?.trim();\n return (\n <input\n key={i}\n ref={(el) => {\n inputRefs.current[i] = el;\n }}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={1}\n value={digits[i]?.trim() || \"\"}\n onKeyDown={(e) => handleKeyDown(i, e)}\n onInput={(e) => handleInput(i, e)}\n onFocus={(e) => e.target.select()}\n disabled={disabled}\n className={cn(\n \"h-13 w-13 rounded-md border-2 text-center text-xl font-bold outline-none transition-all\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20 focus:scale-105\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n filled ? \"border-primary/30 bg-primary/5\" : \"border-border bg-background\",\n )}\n />\n );\n })}\n </div>\n <p className=\"text-center text-xs text-muted-foreground\">\n Faites <strong className=\"text-foreground\">#144*82#</strong> pour\n recevoir le code\n </p>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface TransactionStatusProps {\n status: \"polling\" | \"success\" | \"error\";\n elapsedSeconds?: number;\n message?: string;\n errorMessage?: string;\n paymentUrl?: string | null;\n onRetry?: () => void;\n onClose?: () => void;\n onOpenPaymentUrl?: () => void;\n className?: string;\n}\n\nfunction Spinner({ className }: { className?: string }) {\n return (\n <svg\n className={cn(\"animate-spin\", className)}\n width=\"56\"\n height=\"56\"\n viewBox=\"0 0 56 56\"\n fill=\"none\"\n >\n <circle\n cx=\"28\"\n cy=\"28\"\n r=\"24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n className=\"opacity-20\"\n />\n <path\n d=\"M28 4a24 24 0 0 1 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n className=\"text-primary\"\n />\n </svg>\n );\n}\n\nexport function TransactionStatus({\n status,\n elapsedSeconds = 0,\n message,\n errorMessage,\n paymentUrl,\n onRetry,\n onClose,\n onOpenPaymentUrl,\n className,\n}: TransactionStatusProps) {\n if (status === \"polling\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <Spinner />\n <div className=\"space-y-2 text-center\">\n <p className=\"text-base font-semibold text-foreground\">\n {paymentUrl\n ? \"Finalisez le paiement dans l'onglet ouvert...\"\n : \"Confirmez le paiement sur votre telephone...\"}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {paymentUrl\n ? \"Completez le paiement dans l'onglet, puis revenez ici.\"\n : \"Veuillez valider la transaction sur votre telephone.\"}\n </p>\n {elapsedSeconds > 0 && (\n <p className=\"text-xs text-muted-foreground/70\">\n Verification en cours... {elapsedSeconds}s\n </p>\n )}\n </div>\n {paymentUrl && (\n <div className=\"flex flex-col items-center gap-3\">\n <button\n type=\"button\"\n onClick={onOpenPaymentUrl}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6M15 3h6v6M10 14L21 3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n Ouvrir Wave pour payer\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-sm text-muted-foreground underline hover:text-foreground\"\n >\n Annuler\n </button>\n </div>\n )}\n </div>\n );\n }\n\n if (status === \"success\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Paiement reussi !\n </p>\n {message && (\n <p className=\"text-sm text-muted-foreground\">{message}</p>\n )}\n </div>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Fermer\n </button>\n )}\n </div>\n );\n }\n\n // error\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-red-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Echec du paiement\n </p>\n {errorMessage && (\n <p className=\"text-sm text-muted-foreground\">{errorMessage}</p>\n )}\n </div>\n <div className=\"flex gap-3\">\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Fermer\n </button>\n )}\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Reessayer\n </button>\n )}\n </div>\n </div>\n );\n}\n","export function formatCFA(n: number): string {\n return new Intl.NumberFormat(\"fr-FR\").format(n);\n}\n","import type { PaymentProvider } from \"@applite/duticotac\";\n\nexport function getPhoneRegex(provider: PaymentProvider): RegExp {\n switch (provider) {\n case \"OM_CI\":\n return /^(\\+225)(07)[0-9]{8}$/;\n case \"MTN_CI\":\n return /^(\\+225)(05)[0-9]{8}$/;\n case \"MOOV_CI\":\n return /^(\\+225)(01)[0-9]{8}$/;\n default:\n return /^(\\+225)(07|05|01)[0-9]{8}$/;\n }\n}\n\nexport function validatePhone(\n phone: string,\n provider: PaymentProvider,\n): string | null {\n if (!phone) return \"Numéro de téléphone requis\";\n const intl = phone.startsWith(\"+225\") ? phone : `+225${phone}`;\n const cleaned = intl.replace(/\\s/g, \"\");\n if (!getPhoneRegex(provider).test(cleaned)) {\n return \"Numéro invalide pour ce provider\";\n }\n return null;\n}\n\nexport function normalizePhone(phone: string): string {\n const cleaned = phone.replace(/\\s/g, \"\");\n return cleaned.startsWith(\"+225\") ? cleaned : `+225${cleaned}`;\n}\n\nexport function needsOtp(provider: PaymentProvider): boolean {\n return provider === \"OM_CI\";\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ResponsiveDialogProps {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n className?: string;\n}\n\nconst ANIMATION_MS = 250;\n\nexport function ResponsiveDialog({\n open,\n onClose,\n title,\n children,\n className,\n}: ResponsiveDialogProps) {\n const [mounted, setMounted] = React.useState(false);\n const [visible, setVisible] = React.useState(false);\n const panelRef = React.useRef<HTMLDivElement>(null);\n\n // Mount on open, animate in, then animate out before unmount\n React.useEffect(() => {\n if (open) {\n setMounted(true);\n // Trigger enter animation next frame\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setVisible(true));\n });\n } else if (mounted) {\n setVisible(false);\n const timer = setTimeout(() => setMounted(false), ANIMATION_MS);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n // Escape key\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n // Lock body scroll\n React.useEffect(() => {\n if (!mounted) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [mounted]);\n\n if (!mounted) return null;\n\n const dialog = (\n <>\n <style>{`\n .dtc-dialog-backdrop {\n position: fixed;\n inset: 0;\n z-index: 9998;\n background: rgba(0,0,0,0);\n transition: background ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-backdrop.dtc-visible {\n background: rgba(0,0,0,0.5);\n }\n\n /* ── Desktop: centered modal ── */\n .dtc-dialog-panel {\n position: fixed;\n z-index: 9999;\n background: var(--background, #fff);\n border: 1px solid var(--border, #e5e7eb);\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n\n /* Desktop default */\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n opacity: 0;\n width: calc(100% - 32px);\n max-width: 440px;\n max-height: calc(100vh - 64px);\n border-radius: 16px;\n overflow-y: auto;\n\n transition:\n transform ${ANIMATION_MS}ms cubic-bezier(0.22, 1, 0.36, 1),\n opacity ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translate(-50%, -50%) scale(1);\n opacity: 1;\n }\n\n /* ── Mobile: bottom sheet ── */\n @media (max-width: 640px) {\n .dtc-dialog-panel {\n top: auto;\n left: 0;\n right: 0;\n bottom: 0;\n transform: translateY(100%);\n opacity: 1;\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 20px 20px 0 0;\n border-bottom: none;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translateY(0);\n }\n }\n `}</style>\n\n {/* Backdrop */}\n <div\n className={cn(\"dtc-dialog-backdrop\", visible && \"dtc-visible\")}\n onClick={onClose}\n aria-hidden\n />\n\n {/* Panel */}\n <div\n ref={panelRef}\n className={cn(\"dtc-dialog-panel\", visible && \"dtc-visible\", className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n {/* Drag handle (mobile) */}\n <div className=\"dtc-mobile-handle\" style={{\n display: \"none\",\n justifyContent: \"center\",\n paddingTop: 12,\n paddingBottom: 4,\n }}>\n <div style={{\n width: 36,\n height: 4,\n borderRadius: 2,\n background: \"var(--border, #d1d5db)\",\n }} />\n </div>\n <style>{`\n @media (max-width: 640px) {\n .dtc-mobile-handle { display: flex !important; }\n }\n `}</style>\n\n {/* Header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"16px 20px 0\",\n }}>\n <h2 style={{\n fontSize: 18,\n fontWeight: 700,\n color: \"var(--foreground, #111)\",\n margin: 0,\n }}>\n {title}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n padding: 4,\n cursor: \"pointer\",\n borderRadius: 6,\n color: \"var(--muted-foreground, #6b7280)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n {/* Content */}\n <div style={{ padding: \"16px 20px 20px\" }}>\n {children}\n </div>\n </div>\n </>\n );\n\n if (typeof document === \"undefined\") return null;\n return createPortal(dialog, document.body);\n}\n","import * as React from \"react\";\nimport type { DuticotacSDK, PaymentProvider, TransactionModel, CoreApp, PlatformType } from \"@applite/duticotac\";\nimport { DuticotacPaymentModal } from \"../components/payment-modal\";\nimport { ResponsiveDialog } from \"../components/responsive-dialog\";\n\nexport interface UseDuticotacConfig {\n /** DuticotacSDK instance. */\n sdk: DuticotacSDK;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Shared defaults — can be overridden per pay() call. */\n productReference?: string;\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n initialPhone?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Dialog title (default: \"Paiement\"). */\n title?: string;\n}\n\nexport interface PayOptions {\n /** Amount in FCFA. */\n amount: number;\n\n /** Override providers for this payment. */\n providers?: PaymentProvider[];\n\n /** Override product reference. */\n productReference?: string;\n\n /** Override customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Called when payment is confirmed. */\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** Called when the dialog closes (success or cancel). */\n onClose?: () => void;\n}\n\nexport interface UseDuticotacReturn {\n /** Open the payment dialog with the given options. */\n pay: (options: PayOptions) => void;\n\n /** Whether the dialog is currently open. */\n isOpen: boolean;\n\n /** Close the dialog programmatically. */\n close: () => void;\n\n /**\n * The dialog JSX element. Render this once somewhere in your component tree.\n * @example return <>{Dialog}</>\n */\n Dialog: React.ReactNode;\n}\n\nexport function useDuticotac(config: UseDuticotacConfig): UseDuticotacReturn {\n const [open, setOpen] = React.useState(false);\n const [payOptions, setPayOptions] = React.useState<PayOptions | null>(null);\n\n const configRef = React.useRef(config);\n configRef.current = config;\n\n const pay = React.useCallback((options: PayOptions) => {\n setPayOptions(options);\n setOpen(true);\n }, []);\n\n const close = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n payOptions?.onClose?.();\n }, [payOptions]);\n\n const handleSuccess = React.useCallback(\n (tx: TransactionModel) => {\n payOptions?.onSuccess?.(tx);\n },\n [payOptions],\n );\n\n const DialogElement = React.useMemo(() => {\n if (!payOptions) return null;\n\n const cfg = configRef.current;\n\n return (\n <DuticotacPaymentModal\n open={open}\n onClose={handleClose}\n onSuccess={handleSuccess}\n sdk={cfg.sdk}\n amount={payOptions.amount}\n providers={payOptions.providers ?? cfg.providers}\n getTransactionId={cfg.getTransactionId}\n productReference={payOptions.productReference ?? cfg.productReference}\n initialPhone={cfg.initialPhone}\n name={payOptions.name ?? cfg.name}\n email={payOptions.email ?? cfg.email}\n customerId={payOptions.customerId ?? cfg.customerId}\n kolaboReference={cfg.kolaboReference}\n app={cfg.app}\n platform={cfg.platform}\n pollTimeout={cfg.pollTimeout}\n title={cfg.title}\n successMessage={payOptions.successMessage}\n renderModal={({ open: isOpen, onClose: modalClose, title: modalTitle, children }) => (\n <ResponsiveDialog\n open={isOpen}\n onClose={modalClose}\n title={modalTitle}\n >\n {children}\n </ResponsiveDialog>\n )}\n />\n );\n }, [open, payOptions, handleClose, handleSuccess]);\n\n return {\n pay,\n isOpen: open,\n close,\n Dialog: DialogElement,\n };\n}\n"],"mappings":"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","names":["index_exports","__export","DuticotacError","DuticotacSDK","getErrorMessage","getProviderLogo","getProviderName","module","__toCommonJS","React","import_duticotac","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/index.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/http.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/balance.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/offer.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/mobile-money.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/payment-method.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/webhook.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/transaction.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/providers.ts","../src/index.ts","../src/components/payment-modal.tsx","../src/components/provider-selector.tsx","../src/utils/cn.ts","../src/components/phone-input.tsx","../src/components/otp-input.tsx","../src/components/transaction-status.tsx","../src/utils/format.ts","../src/utils/validation.ts","../src/components/responsive-dialog.tsx","../src/hooks/use-duticotac.tsx"],"sourcesContent":["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","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","// Components\nexport { DuticotacPaymentModal } from \"./components/payment-modal\";\nexport type { DuticotacPaymentModalProps } from \"./components/payment-modal\";\n\nexport { ProviderSelector } from \"./components/provider-selector\";\nexport type { ProviderSelectorProps } from \"./components/provider-selector\";\n\nexport { PhoneInput } from \"./components/phone-input\";\nexport type { PhoneInputProps } from \"./components/phone-input\";\n\nexport { OtpInput } from \"./components/otp-input\";\nexport type { OtpInputProps } from \"./components/otp-input\";\n\nexport { TransactionStatus } from \"./components/transaction-status\";\nexport type { TransactionStatusProps } from \"./components/transaction-status\";\n\nexport { ResponsiveDialog } from \"./components/responsive-dialog\";\nexport type { ResponsiveDialogProps } from \"./components/responsive-dialog\";\n\n// Hooks\nexport { useDuticotac } from \"./hooks/use-duticotac\";\nexport type {\n UseDuticotacConfig,\n UseDuticotacReturn,\n PayOptions,\n} from \"./hooks/use-duticotac\";\n\n// Re-export core SDK so consumers don't need @applite/duticotac separately\nexport * from \"@applite/duticotac\";\n\n// Utilities\nexport { cn } from \"./utils/cn\";\nexport { formatCFA } from \"./utils/format\";\nexport {\n getPhoneRegex,\n validatePhone,\n normalizePhone,\n needsOtp,\n} from \"./utils/validation\";\n","import * as React from \"react\";\nimport {\n DuticotacSDK,\n DuticotacError,\n getErrorMessage,\n} from \"@applite/duticotac\";\nimport type {\n PaymentProvider,\n TransactionModel,\n CoreApp,\n PlatformType,\n} from \"@applite/duticotac\";\nimport { ProviderSelector } from \"./provider-selector\";\nimport { PhoneInput } from \"./phone-input\";\nimport { OtpInput } from \"./otp-input\";\nimport { TransactionStatus } from \"./transaction-status\";\nimport { cn } from \"../utils/cn\";\nimport { formatCFA } from \"../utils/format\";\nimport { validatePhone, normalizePhone, needsOtp } from \"../utils/validation\";\n\n// ─── Polling helpers ─────────────────────────────────────────────────────────\n\nfunction waitForVisibility(signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\" || document.visibilityState === \"visible\") {\n resolve();\n return;\n }\n const handler = () => {\n if (document.visibilityState === \"visible\") {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n }\n };\n document.addEventListener(\"visibilitychange\", handler);\n signal?.addEventListener(\"abort\", () => {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n });\n });\n}\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Step = \"form\" | \"confirming\" | \"success\" | \"error\";\n\nexport interface DuticotacPaymentModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** SDK instance or config to create one. */\n sdk: DuticotacSDK;\n\n /** Amount in the smallest currency unit. */\n amount: number;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Product reference for the cashout. */\n productReference?: string;\n\n /** Pre-fill phone number. */\n initialPhone?: string;\n\n /** Customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Custom title. */\n title?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Additional class names for the modal container. */\n className?: string;\n\n /**\n * Render prop for the modal wrapper. Receives children and renders them\n * inside your dialog/modal component. If not provided, a simple overlay is used.\n */\n renderModal?: (props: {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n }) => React.ReactNode;\n}\n\nconst DEFAULT_PROVIDERS: PaymentProvider[] = [\n \"OM_CI\",\n \"MTN_CI\",\n \"MOOV_CI\",\n \"WAVE_CI\",\n];\n\nexport function DuticotacPaymentModal({\n open,\n onClose,\n onSuccess,\n sdk,\n amount,\n providers = DEFAULT_PROVIDERS,\n getTransactionId,\n productReference,\n initialPhone = \"\",\n name: customerName,\n email: customerEmail,\n customerId,\n kolaboReference,\n app,\n platform,\n successMessage,\n title = \"Paiement\",\n pollTimeout = 90_000,\n className,\n renderModal,\n}: DuticotacPaymentModalProps) {\n const [step, setStep] = React.useState<Step>(\"form\");\n const [provider, setProvider] = React.useState<PaymentProvider>(providers[0]!);\n const [phone, setPhone] = React.useState(initialPhone);\n const [otp, setOtp] = React.useState(\"\");\n const [phoneError, setPhoneError] = React.useState<string | null>(null);\n const [errorMessage, setErrorMessage] = React.useState(\"\");\n const [paymentUrl, setPaymentUrl] = React.useState<string | null>(null);\n const [elapsedSeconds, setElapsedSeconds] = React.useState(0);\n const [lastTransaction, setLastTransaction] = React.useState<TransactionModel | null>(null);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const elapsedRef = React.useRef<ReturnType<typeof setInterval> | null>(null);\n\n const cleanup = React.useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = null;\n if (elapsedRef.current) {\n clearInterval(elapsedRef.current);\n elapsedRef.current = null;\n }\n }, []);\n\n React.useEffect(() => {\n if (open) {\n setStep(\"form\");\n setErrorMessage(\"\");\n setOtp(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n setPhoneError(null);\n setLastTransaction(null);\n } else {\n cleanup();\n }\n }, [open, cleanup]);\n\n React.useEffect(() => () => cleanup(), [cleanup]);\n\n const isFormValid =\n phone.replace(/\\s/g, \"\").length >= 8 &&\n (needsOtp(provider) ? otp.length === 4 : true);\n\n const handleSubmit = async () => {\n // Validate phone\n const phoneErr = validatePhone(phone, provider);\n if (phoneErr) {\n setPhoneError(phoneErr);\n return;\n }\n setPhoneError(null);\n\n setStep(\"confirming\");\n setErrorMessage(\"\");\n cleanup();\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const transactionId = await getTransactionId();\n\n const result = await sdk.mobileMoney.cashout({\n transactionId,\n ref: productReference,\n phone: normalizePhone(phone),\n name: customerName ?? \"Duticotac App\",\n email: customerEmail ?? \"\",\n paymentMethod: provider,\n amount,\n otp: needsOtp(provider) ? otp : undefined,\n customerId,\n kolaboReference,\n app,\n plateform: platform,\n });\n\n const tx = result.data;\n\n if (tx?.paymentUrl) {\n setPaymentUrl(tx.paymentUrl);\n try {\n window.open(tx.paymentUrl, \"_blank\");\n } catch {\n // Popup may be blocked\n }\n }\n\n // Start polling\n const startTime = Date.now();\n setElapsedSeconds(0);\n elapsedRef.current = setInterval(() => {\n setElapsedSeconds(Math.floor((Date.now() - startTime) / 1000));\n }, 1000);\n\n const confirmed = await sdk.transaction.poll(tx.id ?? transactionId, {\n timeoutMs: pollTimeout,\n signal: controller.signal,\n onPoll: () => {\n // Wait for visibility before each poll\n },\n });\n\n setLastTransaction(confirmed.data);\n setStep(\"success\");\n onSuccess?.(confirmed.data);\n } catch (e) {\n if (controller.signal.aborted) return;\n\n if (e instanceof DuticotacError) {\n setErrorMessage(e.message);\n } else {\n setErrorMessage(\n getErrorMessage(\"unknown-error\"),\n );\n }\n setStep(\"error\");\n }\n };\n\n const handleRetry = () => {\n setStep(\"form\");\n setErrorMessage(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n };\n\n // ─── Content ──────────────────────────────────────────────────────────────\n\n const content = (\n <div className={cn(\"space-y-5\", className)}>\n {step === \"form\" && (\n <>\n {/* Offer summary */}\n <div className=\"rounded-lg border-l-4 border-l-primary bg-muted/50 p-4\">\n <p className=\"text-xs text-muted-foreground\">Montant</p>\n <p className=\"text-xl font-bold text-primary\">\n {formatCFA(amount)} FCFA\n </p>\n </div>\n\n {/* Provider selection */}\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold text-foreground\">\n Moyen de paiement\n </p>\n <ProviderSelector\n providers={providers}\n value={provider}\n onChange={(p) => {\n setProvider(p);\n if (!needsOtp(p)) setOtp(\"\");\n }}\n />\n </div>\n\n {/* Phone input */}\n <PhoneInput\n value={phone}\n onChange={(v) => {\n setPhone(v);\n setPhoneError(null);\n }}\n error={phoneError}\n autoFocus\n />\n\n {/* OTP input (Orange Money only) */}\n {needsOtp(provider) && (\n <OtpInput value={otp} onChange={setOtp} />\n )}\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Annuler\n </button>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!isFormValid}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\"\n >\n Payer {formatCFA(amount)} FCFA\n </button>\n </div>\n </>\n )}\n\n {step === \"confirming\" && (\n <TransactionStatus\n status=\"polling\"\n elapsedSeconds={elapsedSeconds}\n paymentUrl={paymentUrl}\n onOpenPaymentUrl={() => {\n if (paymentUrl) window.open(paymentUrl, \"_blank\");\n }}\n onClose={onClose}\n />\n )}\n\n {step === \"success\" && (\n <TransactionStatus\n status=\"success\"\n message={successMessage ?? \"Le paiement a ete effectue avec succes.\"}\n onClose={onClose}\n />\n )}\n\n {step === \"error\" && (\n <TransactionStatus\n status=\"error\"\n errorMessage={errorMessage}\n onRetry={handleRetry}\n onClose={onClose}\n />\n )}\n </div>\n );\n\n // ─── Render ───────────────────────────────────────────────────────────────\n\n if (renderModal) {\n return <>{renderModal({ open, onClose, title, children: content })}</>;\n }\n\n // Default simple overlay modal\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black/50\"\n onClick={onClose}\n />\n <div className=\"relative z-10 w-full max-w-md rounded-xl border border-border bg-background p-6 shadow-xl\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-bold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {content}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport type { PaymentProvider } from \"@applite/duticotac\";\nimport { getProviderName, getProviderLogo } from \"@applite/duticotac\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ProviderSelectorProps {\n providers: PaymentProvider[];\n value: PaymentProvider;\n onChange: (provider: PaymentProvider) => void;\n disabled?: boolean;\n className?: string;\n}\n\nexport function ProviderSelector({\n providers,\n value,\n onChange,\n disabled,\n className,\n}: ProviderSelectorProps) {\n return (\n <div className={cn(\"grid gap-2\", className)} style={{\n gridTemplateColumns: `repeat(${Math.min(providers.length, 4)}, 1fr)`,\n }}>\n {providers.map((provider) => {\n const selected = value === provider;\n return (\n <button\n key={provider}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(provider)}\n className={cn(\n \"relative flex flex-col items-center gap-2 rounded-lg border-2 p-3 transition-all\",\n \"hover:scale-[1.02] disabled:pointer-events-none disabled:opacity-50\",\n selected\n ? \"border-primary bg-primary/5 shadow-sm\"\n : \"border-border bg-background hover:border-primary/40\",\n )}\n >\n {selected && (\n <div className=\"absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-primary\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n )}\n <img\n src={getProviderLogo(provider)}\n alt={getProviderName(provider)}\n width={44}\n height={44}\n className=\"rounded-lg object-contain\"\n />\n <span\n className={cn(\n \"text-center text-xs leading-tight\",\n selected\n ? \"font-semibold text-primary\"\n : \"font-medium text-muted-foreground\",\n )}\n >\n {getProviderName(provider)}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface PhoneInputProps {\n value: string;\n onChange: (value: string) => void;\n label?: string;\n placeholder?: string;\n error?: string | null;\n disabled?: boolean;\n className?: string;\n autoFocus?: boolean;\n}\n\nexport function PhoneInput({\n value,\n onChange,\n label = \"Numero de telephone\",\n placeholder = \"07 01 02 03 04\",\n error,\n disabled,\n className,\n autoFocus,\n}: PhoneInputProps) {\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {label && (\n <label className=\"block text-sm font-semibold text-foreground\">\n {label}\n </label>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-10 items-center rounded-md border border-border bg-muted px-3 text-sm font-medium text-muted-foreground\">\n +225\n </div>\n <input\n type=\"tel\"\n inputMode=\"numeric\"\n value={value}\n onChange={(e) => {\n const cleaned = e.target.value.replace(/[^\\d\\s]/g, \"\");\n onChange(cleaned);\n }}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={autoFocus}\n className={cn(\n \"h-10 w-full rounded-md border bg-background px-3 text-sm font-medium outline-none transition-colors\",\n \"placeholder:text-muted-foreground/50\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n error ? \"border-destructive\" : \"border-border\",\n )}\n />\n </div>\n {error && (\n <p className=\"text-xs font-medium text-destructive\">{error}</p>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface OtpInputProps {\n value: string;\n onChange: (value: string) => void;\n length?: number;\n disabled?: boolean;\n className?: string;\n}\n\nexport function OtpInput({\n value,\n onChange,\n length = 4,\n disabled,\n className,\n}: OtpInputProps) {\n const inputRefs = React.useRef<(HTMLInputElement | null)[]>([]);\n const digits = value.padEnd(length, \"\").slice(0, length).split(\"\");\n\n const setDigit = (index: number, char: string) => {\n const next = [...digits];\n next[index] = char;\n onChange(next.join(\"\"));\n };\n\n const handleKeyDown = (\n index: number,\n e: React.KeyboardEvent<HTMLInputElement>,\n ) => {\n if (e.key === \"Backspace\") {\n e.preventDefault();\n if (digits[index]?.trim()) {\n setDigit(index, \"\");\n } else if (index > 0) {\n setDigit(index - 1, \"\");\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === \"ArrowLeft\" && index > 0) {\n inputRefs.current[index - 1]?.focus();\n } else if (e.key === \"ArrowRight\" && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleInput = (\n index: number,\n e: React.FormEvent<HTMLInputElement>,\n ) => {\n const val = (e.target as HTMLInputElement).value;\n const char = val.replace(/\\D/g, \"\").slice(-1);\n if (!char) return;\n setDigit(index, char);\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault();\n const pasted = e.clipboardData\n .getData(\"text\")\n .replace(/\\D/g, \"\")\n .slice(0, length);\n if (!pasted) return;\n onChange(pasted.padEnd(length, \"\").slice(0, length).replace(/ /g, \"\"));\n const focusIndex = Math.min(pasted.length, length - 1);\n inputRefs.current[focusIndex]?.focus();\n };\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n <label className=\"block text-sm font-semibold text-muted-foreground\">\n Code OTP\n </label>\n <div className=\"flex justify-center gap-3\" onPaste={handlePaste}>\n {Array.from({ length }).map((_, i) => {\n const filled = !!digits[i]?.trim();\n return (\n <input\n key={i}\n ref={(el) => {\n inputRefs.current[i] = el;\n }}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={1}\n value={digits[i]?.trim() || \"\"}\n onKeyDown={(e) => handleKeyDown(i, e)}\n onInput={(e) => handleInput(i, e)}\n onFocus={(e) => e.target.select()}\n disabled={disabled}\n className={cn(\n \"h-13 w-13 rounded-md border-2 text-center text-xl font-bold outline-none transition-all\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20 focus:scale-105\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n filled ? \"border-primary/30 bg-primary/5\" : \"border-border bg-background\",\n )}\n />\n );\n })}\n </div>\n <p className=\"text-center text-xs text-muted-foreground\">\n Faites <strong className=\"text-foreground\">#144*82#</strong> pour\n recevoir le code\n </p>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface TransactionStatusProps {\n status: \"polling\" | \"success\" | \"error\";\n elapsedSeconds?: number;\n message?: string;\n errorMessage?: string;\n paymentUrl?: string | null;\n onRetry?: () => void;\n onClose?: () => void;\n onOpenPaymentUrl?: () => void;\n className?: string;\n}\n\nfunction Spinner({ className }: { className?: string }) {\n return (\n <svg\n className={cn(\"animate-spin\", className)}\n width=\"56\"\n height=\"56\"\n viewBox=\"0 0 56 56\"\n fill=\"none\"\n >\n <circle\n cx=\"28\"\n cy=\"28\"\n r=\"24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n className=\"opacity-20\"\n />\n <path\n d=\"M28 4a24 24 0 0 1 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n className=\"text-primary\"\n />\n </svg>\n );\n}\n\nexport function TransactionStatus({\n status,\n elapsedSeconds = 0,\n message,\n errorMessage,\n paymentUrl,\n onRetry,\n onClose,\n onOpenPaymentUrl,\n className,\n}: TransactionStatusProps) {\n if (status === \"polling\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <Spinner />\n <div className=\"space-y-2 text-center\">\n <p className=\"text-base font-semibold text-foreground\">\n {paymentUrl\n ? \"Finalisez le paiement dans l'onglet ouvert...\"\n : \"Confirmez le paiement sur votre telephone...\"}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {paymentUrl\n ? \"Completez le paiement dans l'onglet, puis revenez ici.\"\n : \"Veuillez valider la transaction sur votre telephone.\"}\n </p>\n {elapsedSeconds > 0 && (\n <p className=\"text-xs text-muted-foreground/70\">\n Verification en cours... {elapsedSeconds}s\n </p>\n )}\n </div>\n {paymentUrl && (\n <div className=\"flex flex-col items-center gap-3\">\n <button\n type=\"button\"\n onClick={onOpenPaymentUrl}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6M15 3h6v6M10 14L21 3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n Ouvrir Wave pour payer\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-sm text-muted-foreground underline hover:text-foreground\"\n >\n Annuler\n </button>\n </div>\n )}\n </div>\n );\n }\n\n if (status === \"success\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Paiement reussi !\n </p>\n {message && (\n <p className=\"text-sm text-muted-foreground\">{message}</p>\n )}\n </div>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Fermer\n </button>\n )}\n </div>\n );\n }\n\n // error\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-red-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Echec du paiement\n </p>\n {errorMessage && (\n <p className=\"text-sm text-muted-foreground\">{errorMessage}</p>\n )}\n </div>\n <div className=\"flex gap-3\">\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Fermer\n </button>\n )}\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Reessayer\n </button>\n )}\n </div>\n </div>\n );\n}\n","export function formatCFA(n: number): string {\n return new Intl.NumberFormat(\"fr-FR\").format(n);\n}\n","import type { PaymentProvider } from \"@applite/duticotac\";\n\nexport function getPhoneRegex(provider: PaymentProvider): RegExp {\n switch (provider) {\n case \"OM_CI\":\n return /^(\\+225)(07)[0-9]{8}$/;\n case \"MTN_CI\":\n return /^(\\+225)(05)[0-9]{8}$/;\n case \"MOOV_CI\":\n return /^(\\+225)(01)[0-9]{8}$/;\n default:\n return /^(\\+225)(07|05|01)[0-9]{8}$/;\n }\n}\n\nexport function validatePhone(\n phone: string,\n provider: PaymentProvider,\n): string | null {\n if (!phone) return \"Numéro de téléphone requis\";\n const intl = phone.startsWith(\"+225\") ? phone : `+225${phone}`;\n const cleaned = intl.replace(/\\s/g, \"\");\n if (!getPhoneRegex(provider).test(cleaned)) {\n return \"Numéro invalide pour ce provider\";\n }\n return null;\n}\n\nexport function normalizePhone(phone: string): string {\n const cleaned = phone.replace(/\\s/g, \"\");\n return cleaned.startsWith(\"+225\") ? cleaned : `+225${cleaned}`;\n}\n\nexport function needsOtp(provider: PaymentProvider): boolean {\n return provider === \"OM_CI\";\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ResponsiveDialogProps {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n className?: string;\n}\n\nconst ANIMATION_MS = 250;\n\nexport function ResponsiveDialog({\n open,\n onClose,\n title,\n children,\n className,\n}: ResponsiveDialogProps) {\n const [mounted, setMounted] = React.useState(false);\n const [visible, setVisible] = React.useState(false);\n const panelRef = React.useRef<HTMLDivElement>(null);\n\n // Mount on open, animate in, then animate out before unmount\n React.useEffect(() => {\n if (open) {\n setMounted(true);\n // Trigger enter animation next frame\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setVisible(true));\n });\n } else if (mounted) {\n setVisible(false);\n const timer = setTimeout(() => setMounted(false), ANIMATION_MS);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n // Escape key\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n // Lock body scroll\n React.useEffect(() => {\n if (!mounted) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [mounted]);\n\n if (!mounted) return null;\n\n const dialog = (\n <>\n <style>{`\n .dtc-dialog-backdrop {\n position: fixed;\n inset: 0;\n z-index: 9998;\n background: rgba(0,0,0,0);\n transition: background ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-backdrop.dtc-visible {\n background: rgba(0,0,0,0.5);\n }\n\n /* ── Desktop: centered modal ── */\n .dtc-dialog-panel {\n position: fixed;\n z-index: 9999;\n background: var(--background, #fff);\n border: 1px solid var(--border, #e5e7eb);\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n\n /* Desktop default */\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n opacity: 0;\n width: calc(100% - 32px);\n max-width: 440px;\n max-height: calc(100vh - 64px);\n border-radius: 16px;\n overflow-y: auto;\n\n transition:\n transform ${ANIMATION_MS}ms cubic-bezier(0.22, 1, 0.36, 1),\n opacity ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translate(-50%, -50%) scale(1);\n opacity: 1;\n }\n\n /* ── Mobile: bottom sheet ── */\n @media (max-width: 640px) {\n .dtc-dialog-panel {\n top: auto;\n left: 0;\n right: 0;\n bottom: 0;\n transform: translateY(100%);\n opacity: 1;\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 20px 20px 0 0;\n border-bottom: none;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translateY(0);\n }\n }\n `}</style>\n\n {/* Backdrop */}\n <div\n className={cn(\"dtc-dialog-backdrop\", visible && \"dtc-visible\")}\n onClick={onClose}\n aria-hidden\n />\n\n {/* Panel */}\n <div\n ref={panelRef}\n className={cn(\"dtc-dialog-panel\", visible && \"dtc-visible\", className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n {/* Drag handle (mobile) */}\n <div className=\"dtc-mobile-handle\" style={{\n display: \"none\",\n justifyContent: \"center\",\n paddingTop: 12,\n paddingBottom: 4,\n }}>\n <div style={{\n width: 36,\n height: 4,\n borderRadius: 2,\n background: \"var(--border, #d1d5db)\",\n }} />\n </div>\n <style>{`\n @media (max-width: 640px) {\n .dtc-mobile-handle { display: flex !important; }\n }\n `}</style>\n\n {/* Header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"16px 20px 0\",\n }}>\n <h2 style={{\n fontSize: 18,\n fontWeight: 700,\n color: \"var(--foreground, #111)\",\n margin: 0,\n }}>\n {title}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n padding: 4,\n cursor: \"pointer\",\n borderRadius: 6,\n color: \"var(--muted-foreground, #6b7280)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n {/* Content */}\n <div style={{ padding: \"16px 20px 20px\" }}>\n {children}\n </div>\n </div>\n </>\n );\n\n if (typeof document === \"undefined\") return null;\n return createPortal(dialog, document.body);\n}\n","import * as React from \"react\";\nimport type { DuticotacSDK, PaymentProvider, TransactionModel, CoreApp, PlatformType } from \"@applite/duticotac\";\nimport { DuticotacPaymentModal } from \"../components/payment-modal\";\nimport { ResponsiveDialog } from \"../components/responsive-dialog\";\n\nexport interface UseDuticotacConfig {\n /** DuticotacSDK instance. */\n sdk: DuticotacSDK;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Shared defaults — can be overridden per pay() call. */\n productReference?: string;\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n initialPhone?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Dialog title (default: \"Paiement\"). */\n title?: string;\n}\n\nexport interface PayOptions {\n /** Amount in FCFA. */\n amount: number;\n\n /** Override providers for this payment. */\n providers?: PaymentProvider[];\n\n /** Override product reference. */\n productReference?: string;\n\n /** Override customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Called when payment is confirmed. */\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** Called when the dialog closes (success or cancel). */\n onClose?: () => void;\n}\n\nexport interface UseDuticotacReturn {\n /** Open the payment dialog with the given options. */\n pay: (options: PayOptions) => void;\n\n /** Whether the dialog is currently open. */\n isOpen: boolean;\n\n /** Close the dialog programmatically. */\n close: () => void;\n\n /**\n * The dialog JSX element. Render this once somewhere in your component tree.\n * @example return <>{Dialog}</>\n */\n Dialog: React.ReactNode;\n}\n\nexport function useDuticotac(config: UseDuticotacConfig): UseDuticotacReturn {\n const [open, setOpen] = React.useState(false);\n const [payOptions, setPayOptions] = React.useState<PayOptions | null>(null);\n\n const configRef = React.useRef(config);\n configRef.current = config;\n\n const pay = React.useCallback((options: PayOptions) => {\n setPayOptions(options);\n setOpen(true);\n }, []);\n\n const close = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n payOptions?.onClose?.();\n }, [payOptions]);\n\n const handleSuccess = React.useCallback(\n (tx: TransactionModel) => {\n payOptions?.onSuccess?.(tx);\n },\n [payOptions],\n );\n\n const DialogElement = React.useMemo(() => {\n if (!payOptions) return null;\n\n const cfg = configRef.current;\n\n return (\n <DuticotacPaymentModal\n open={open}\n onClose={handleClose}\n onSuccess={handleSuccess}\n sdk={cfg.sdk}\n amount={payOptions.amount}\n providers={payOptions.providers ?? cfg.providers}\n getTransactionId={cfg.getTransactionId}\n productReference={payOptions.productReference ?? cfg.productReference}\n initialPhone={cfg.initialPhone}\n name={payOptions.name ?? cfg.name}\n email={payOptions.email ?? cfg.email}\n customerId={payOptions.customerId ?? cfg.customerId}\n kolaboReference={cfg.kolaboReference}\n app={cfg.app}\n platform={cfg.platform}\n pollTimeout={cfg.pollTimeout}\n title={cfg.title}\n successMessage={payOptions.successMessage}\n renderModal={({ open: isOpen, onClose: modalClose, title: modalTitle, children }) => (\n <ResponsiveDialog\n open={isOpen}\n onClose={modalClose}\n title={modalTitle}\n >\n {children}\n </ResponsiveDialog>\n )}\n />\n );\n }, [open, payOptions, handleClose, handleSuccess]);\n\n return {\n pay,\n isOpen: open,\n close,\n Dialog: DialogElement,\n };\n}\n"],"mappings":"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","names":["index_exports","__export","DuticotacError","DuticotacSDK","getErrorMessage","getProviderLogo","getProviderName","module","__toCommonJS","React","import_duticotac","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -8,6 +8,10 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
|
8
8
|
var __commonJS = (cb, mod) => function __require() {
|
|
9
9
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
10
|
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
11
15
|
var __copyProps = (to, from, except, desc) => {
|
|
12
16
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
17
|
for (let key of __getOwnPropNames(from))
|
|
@@ -16,6 +20,7 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
20
|
}
|
|
17
21
|
return to;
|
|
18
22
|
};
|
|
23
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
19
24
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
25
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
26
|
// file that has been converted to a CommonJS file using a Babel-
|
|
@@ -33,7 +38,7 @@ var require_dist = __commonJS({
|
|
|
33
38
|
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
34
39
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
35
40
|
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
36
|
-
var
|
|
41
|
+
var __export2 = (target, all) => {
|
|
37
42
|
for (var name in all)
|
|
38
43
|
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
39
44
|
};
|
|
@@ -46,8 +51,8 @@ var require_dist = __commonJS({
|
|
|
46
51
|
return to;
|
|
47
52
|
};
|
|
48
53
|
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
49
|
-
var
|
|
50
|
-
|
|
54
|
+
var index_exports2 = {};
|
|
55
|
+
__export2(index_exports2, {
|
|
51
56
|
BalanceModule: () => BalanceModule,
|
|
52
57
|
DuticotacError: () => DuticotacError2,
|
|
53
58
|
DuticotacSDK: () => DuticotacSDK2,
|
|
@@ -62,7 +67,7 @@ var require_dist = __commonJS({
|
|
|
62
67
|
getProviderLogo: () => getProviderLogo2,
|
|
63
68
|
getProviderName: () => getProviderName2
|
|
64
69
|
});
|
|
65
|
-
module.exports = __toCommonJS(
|
|
70
|
+
module.exports = __toCommonJS(index_exports2);
|
|
66
71
|
var ERROR_MESSAGES = {
|
|
67
72
|
"payment-failed": "\xC9chec du paiement",
|
|
68
73
|
"ref-or-idFromClient-required": "R\xE9f\xE9rence ou IDFromClient requis",
|
|
@@ -337,6 +342,24 @@ var require_dist = __commonJS({
|
|
|
337
342
|
}
|
|
338
343
|
});
|
|
339
344
|
|
|
345
|
+
// src/index.ts
|
|
346
|
+
var index_exports = {};
|
|
347
|
+
__export(index_exports, {
|
|
348
|
+
DuticotacPaymentModal: () => DuticotacPaymentModal,
|
|
349
|
+
OtpInput: () => OtpInput,
|
|
350
|
+
PhoneInput: () => PhoneInput,
|
|
351
|
+
ProviderSelector: () => ProviderSelector,
|
|
352
|
+
ResponsiveDialog: () => ResponsiveDialog,
|
|
353
|
+
TransactionStatus: () => TransactionStatus,
|
|
354
|
+
cn: () => cn,
|
|
355
|
+
formatCFA: () => formatCFA,
|
|
356
|
+
getPhoneRegex: () => getPhoneRegex,
|
|
357
|
+
needsOtp: () => needsOtp,
|
|
358
|
+
normalizePhone: () => normalizePhone,
|
|
359
|
+
useDuticotac: () => useDuticotac,
|
|
360
|
+
validatePhone: () => validatePhone
|
|
361
|
+
});
|
|
362
|
+
|
|
340
363
|
// src/components/payment-modal.tsx
|
|
341
364
|
var import_duticotac2 = __toESM(require_dist());
|
|
342
365
|
import * as React2 from "react";
|
|
@@ -1251,6 +1274,9 @@ function useDuticotac(config) {
|
|
|
1251
1274
|
Dialog: DialogElement
|
|
1252
1275
|
};
|
|
1253
1276
|
}
|
|
1277
|
+
|
|
1278
|
+
// src/index.ts
|
|
1279
|
+
__reExport(index_exports, __toESM(require_dist()));
|
|
1254
1280
|
export {
|
|
1255
1281
|
DuticotacPaymentModal,
|
|
1256
1282
|
OtpInput,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/index.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/http.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/balance.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/offer.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/mobile-money.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/payment-method.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/webhook.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/transaction.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/providers.ts","../src/components/payment-modal.tsx","../src/components/provider-selector.tsx","../src/utils/cn.ts","../src/components/phone-input.tsx","../src/components/otp-input.tsx","../src/components/transaction-status.tsx","../src/utils/format.ts","../src/utils/validation.ts","../src/components/responsive-dialog.tsx","../src/hooks/use-duticotac.tsx"],"sourcesContent":["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","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 * as React from \"react\";\nimport {\n DuticotacSDK,\n DuticotacError,\n getErrorMessage,\n} from \"@applite/duticotac\";\nimport type {\n PaymentProvider,\n TransactionModel,\n CoreApp,\n PlatformType,\n} from \"@applite/duticotac\";\nimport { ProviderSelector } from \"./provider-selector\";\nimport { PhoneInput } from \"./phone-input\";\nimport { OtpInput } from \"./otp-input\";\nimport { TransactionStatus } from \"./transaction-status\";\nimport { cn } from \"../utils/cn\";\nimport { formatCFA } from \"../utils/format\";\nimport { validatePhone, normalizePhone, needsOtp } from \"../utils/validation\";\n\n// ─── Polling helpers ─────────────────────────────────────────────────────────\n\nfunction waitForVisibility(signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\" || document.visibilityState === \"visible\") {\n resolve();\n return;\n }\n const handler = () => {\n if (document.visibilityState === \"visible\") {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n }\n };\n document.addEventListener(\"visibilitychange\", handler);\n signal?.addEventListener(\"abort\", () => {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n });\n });\n}\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Step = \"form\" | \"confirming\" | \"success\" | \"error\";\n\nexport interface DuticotacPaymentModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** SDK instance or config to create one. */\n sdk: DuticotacSDK;\n\n /** Amount in the smallest currency unit. */\n amount: number;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Product reference for the cashout. */\n productReference?: string;\n\n /** Pre-fill phone number. */\n initialPhone?: string;\n\n /** Customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Custom title. */\n title?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Additional class names for the modal container. */\n className?: string;\n\n /**\n * Render prop for the modal wrapper. Receives children and renders them\n * inside your dialog/modal component. If not provided, a simple overlay is used.\n */\n renderModal?: (props: {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n }) => React.ReactNode;\n}\n\nconst DEFAULT_PROVIDERS: PaymentProvider[] = [\n \"OM_CI\",\n \"MTN_CI\",\n \"MOOV_CI\",\n \"WAVE_CI\",\n];\n\nexport function DuticotacPaymentModal({\n open,\n onClose,\n onSuccess,\n sdk,\n amount,\n providers = DEFAULT_PROVIDERS,\n getTransactionId,\n productReference,\n initialPhone = \"\",\n name: customerName,\n email: customerEmail,\n customerId,\n kolaboReference,\n app,\n platform,\n successMessage,\n title = \"Paiement\",\n pollTimeout = 90_000,\n className,\n renderModal,\n}: DuticotacPaymentModalProps) {\n const [step, setStep] = React.useState<Step>(\"form\");\n const [provider, setProvider] = React.useState<PaymentProvider>(providers[0]!);\n const [phone, setPhone] = React.useState(initialPhone);\n const [otp, setOtp] = React.useState(\"\");\n const [phoneError, setPhoneError] = React.useState<string | null>(null);\n const [errorMessage, setErrorMessage] = React.useState(\"\");\n const [paymentUrl, setPaymentUrl] = React.useState<string | null>(null);\n const [elapsedSeconds, setElapsedSeconds] = React.useState(0);\n const [lastTransaction, setLastTransaction] = React.useState<TransactionModel | null>(null);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const elapsedRef = React.useRef<ReturnType<typeof setInterval> | null>(null);\n\n const cleanup = React.useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = null;\n if (elapsedRef.current) {\n clearInterval(elapsedRef.current);\n elapsedRef.current = null;\n }\n }, []);\n\n React.useEffect(() => {\n if (open) {\n setStep(\"form\");\n setErrorMessage(\"\");\n setOtp(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n setPhoneError(null);\n setLastTransaction(null);\n } else {\n cleanup();\n }\n }, [open, cleanup]);\n\n React.useEffect(() => () => cleanup(), [cleanup]);\n\n const isFormValid =\n phone.replace(/\\s/g, \"\").length >= 8 &&\n (needsOtp(provider) ? otp.length === 4 : true);\n\n const handleSubmit = async () => {\n // Validate phone\n const phoneErr = validatePhone(phone, provider);\n if (phoneErr) {\n setPhoneError(phoneErr);\n return;\n }\n setPhoneError(null);\n\n setStep(\"confirming\");\n setErrorMessage(\"\");\n cleanup();\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const transactionId = await getTransactionId();\n\n const result = await sdk.mobileMoney.cashout({\n transactionId,\n ref: productReference,\n phone: normalizePhone(phone),\n name: customerName ?? \"Duticotac App\",\n email: customerEmail ?? \"\",\n paymentMethod: provider,\n amount,\n otp: needsOtp(provider) ? otp : undefined,\n customerId,\n kolaboReference,\n app,\n plateform: platform,\n });\n\n const tx = result.data;\n\n if (tx?.paymentUrl) {\n setPaymentUrl(tx.paymentUrl);\n try {\n window.open(tx.paymentUrl, \"_blank\");\n } catch {\n // Popup may be blocked\n }\n }\n\n // Start polling\n const startTime = Date.now();\n setElapsedSeconds(0);\n elapsedRef.current = setInterval(() => {\n setElapsedSeconds(Math.floor((Date.now() - startTime) / 1000));\n }, 1000);\n\n const confirmed = await sdk.transaction.poll(tx.id ?? transactionId, {\n timeoutMs: pollTimeout,\n signal: controller.signal,\n onPoll: () => {\n // Wait for visibility before each poll\n },\n });\n\n setLastTransaction(confirmed.data);\n setStep(\"success\");\n onSuccess?.(confirmed.data);\n } catch (e) {\n if (controller.signal.aborted) return;\n\n if (e instanceof DuticotacError) {\n setErrorMessage(e.message);\n } else {\n setErrorMessage(\n getErrorMessage(\"unknown-error\"),\n );\n }\n setStep(\"error\");\n }\n };\n\n const handleRetry = () => {\n setStep(\"form\");\n setErrorMessage(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n };\n\n // ─── Content ──────────────────────────────────────────────────────────────\n\n const content = (\n <div className={cn(\"space-y-5\", className)}>\n {step === \"form\" && (\n <>\n {/* Offer summary */}\n <div className=\"rounded-lg border-l-4 border-l-primary bg-muted/50 p-4\">\n <p className=\"text-xs text-muted-foreground\">Montant</p>\n <p className=\"text-xl font-bold text-primary\">\n {formatCFA(amount)} FCFA\n </p>\n </div>\n\n {/* Provider selection */}\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold text-foreground\">\n Moyen de paiement\n </p>\n <ProviderSelector\n providers={providers}\n value={provider}\n onChange={(p) => {\n setProvider(p);\n if (!needsOtp(p)) setOtp(\"\");\n }}\n />\n </div>\n\n {/* Phone input */}\n <PhoneInput\n value={phone}\n onChange={(v) => {\n setPhone(v);\n setPhoneError(null);\n }}\n error={phoneError}\n autoFocus\n />\n\n {/* OTP input (Orange Money only) */}\n {needsOtp(provider) && (\n <OtpInput value={otp} onChange={setOtp} />\n )}\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Annuler\n </button>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!isFormValid}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\"\n >\n Payer {formatCFA(amount)} FCFA\n </button>\n </div>\n </>\n )}\n\n {step === \"confirming\" && (\n <TransactionStatus\n status=\"polling\"\n elapsedSeconds={elapsedSeconds}\n paymentUrl={paymentUrl}\n onOpenPaymentUrl={() => {\n if (paymentUrl) window.open(paymentUrl, \"_blank\");\n }}\n onClose={onClose}\n />\n )}\n\n {step === \"success\" && (\n <TransactionStatus\n status=\"success\"\n message={successMessage ?? \"Le paiement a ete effectue avec succes.\"}\n onClose={onClose}\n />\n )}\n\n {step === \"error\" && (\n <TransactionStatus\n status=\"error\"\n errorMessage={errorMessage}\n onRetry={handleRetry}\n onClose={onClose}\n />\n )}\n </div>\n );\n\n // ─── Render ───────────────────────────────────────────────────────────────\n\n if (renderModal) {\n return <>{renderModal({ open, onClose, title, children: content })}</>;\n }\n\n // Default simple overlay modal\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black/50\"\n onClick={onClose}\n />\n <div className=\"relative z-10 w-full max-w-md rounded-xl border border-border bg-background p-6 shadow-xl\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-bold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {content}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport type { PaymentProvider } from \"@applite/duticotac\";\nimport { getProviderName, getProviderLogo } from \"@applite/duticotac\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ProviderSelectorProps {\n providers: PaymentProvider[];\n value: PaymentProvider;\n onChange: (provider: PaymentProvider) => void;\n disabled?: boolean;\n className?: string;\n}\n\nexport function ProviderSelector({\n providers,\n value,\n onChange,\n disabled,\n className,\n}: ProviderSelectorProps) {\n return (\n <div className={cn(\"grid gap-2\", className)} style={{\n gridTemplateColumns: `repeat(${Math.min(providers.length, 4)}, 1fr)`,\n }}>\n {providers.map((provider) => {\n const selected = value === provider;\n return (\n <button\n key={provider}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(provider)}\n className={cn(\n \"relative flex flex-col items-center gap-2 rounded-lg border-2 p-3 transition-all\",\n \"hover:scale-[1.02] disabled:pointer-events-none disabled:opacity-50\",\n selected\n ? \"border-primary bg-primary/5 shadow-sm\"\n : \"border-border bg-background hover:border-primary/40\",\n )}\n >\n {selected && (\n <div className=\"absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-primary\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n )}\n <img\n src={getProviderLogo(provider)}\n alt={getProviderName(provider)}\n width={44}\n height={44}\n className=\"rounded-lg object-contain\"\n />\n <span\n className={cn(\n \"text-center text-xs leading-tight\",\n selected\n ? \"font-semibold text-primary\"\n : \"font-medium text-muted-foreground\",\n )}\n >\n {getProviderName(provider)}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface PhoneInputProps {\n value: string;\n onChange: (value: string) => void;\n label?: string;\n placeholder?: string;\n error?: string | null;\n disabled?: boolean;\n className?: string;\n autoFocus?: boolean;\n}\n\nexport function PhoneInput({\n value,\n onChange,\n label = \"Numero de telephone\",\n placeholder = \"07 01 02 03 04\",\n error,\n disabled,\n className,\n autoFocus,\n}: PhoneInputProps) {\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {label && (\n <label className=\"block text-sm font-semibold text-foreground\">\n {label}\n </label>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-10 items-center rounded-md border border-border bg-muted px-3 text-sm font-medium text-muted-foreground\">\n +225\n </div>\n <input\n type=\"tel\"\n inputMode=\"numeric\"\n value={value}\n onChange={(e) => {\n const cleaned = e.target.value.replace(/[^\\d\\s]/g, \"\");\n onChange(cleaned);\n }}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={autoFocus}\n className={cn(\n \"h-10 w-full rounded-md border bg-background px-3 text-sm font-medium outline-none transition-colors\",\n \"placeholder:text-muted-foreground/50\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n error ? \"border-destructive\" : \"border-border\",\n )}\n />\n </div>\n {error && (\n <p className=\"text-xs font-medium text-destructive\">{error}</p>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface OtpInputProps {\n value: string;\n onChange: (value: string) => void;\n length?: number;\n disabled?: boolean;\n className?: string;\n}\n\nexport function OtpInput({\n value,\n onChange,\n length = 4,\n disabled,\n className,\n}: OtpInputProps) {\n const inputRefs = React.useRef<(HTMLInputElement | null)[]>([]);\n const digits = value.padEnd(length, \"\").slice(0, length).split(\"\");\n\n const setDigit = (index: number, char: string) => {\n const next = [...digits];\n next[index] = char;\n onChange(next.join(\"\"));\n };\n\n const handleKeyDown = (\n index: number,\n e: React.KeyboardEvent<HTMLInputElement>,\n ) => {\n if (e.key === \"Backspace\") {\n e.preventDefault();\n if (digits[index]?.trim()) {\n setDigit(index, \"\");\n } else if (index > 0) {\n setDigit(index - 1, \"\");\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === \"ArrowLeft\" && index > 0) {\n inputRefs.current[index - 1]?.focus();\n } else if (e.key === \"ArrowRight\" && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleInput = (\n index: number,\n e: React.FormEvent<HTMLInputElement>,\n ) => {\n const val = (e.target as HTMLInputElement).value;\n const char = val.replace(/\\D/g, \"\").slice(-1);\n if (!char) return;\n setDigit(index, char);\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault();\n const pasted = e.clipboardData\n .getData(\"text\")\n .replace(/\\D/g, \"\")\n .slice(0, length);\n if (!pasted) return;\n onChange(pasted.padEnd(length, \"\").slice(0, length).replace(/ /g, \"\"));\n const focusIndex = Math.min(pasted.length, length - 1);\n inputRefs.current[focusIndex]?.focus();\n };\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n <label className=\"block text-sm font-semibold text-muted-foreground\">\n Code OTP\n </label>\n <div className=\"flex justify-center gap-3\" onPaste={handlePaste}>\n {Array.from({ length }).map((_, i) => {\n const filled = !!digits[i]?.trim();\n return (\n <input\n key={i}\n ref={(el) => {\n inputRefs.current[i] = el;\n }}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={1}\n value={digits[i]?.trim() || \"\"}\n onKeyDown={(e) => handleKeyDown(i, e)}\n onInput={(e) => handleInput(i, e)}\n onFocus={(e) => e.target.select()}\n disabled={disabled}\n className={cn(\n \"h-13 w-13 rounded-md border-2 text-center text-xl font-bold outline-none transition-all\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20 focus:scale-105\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n filled ? \"border-primary/30 bg-primary/5\" : \"border-border bg-background\",\n )}\n />\n );\n })}\n </div>\n <p className=\"text-center text-xs text-muted-foreground\">\n Faites <strong className=\"text-foreground\">#144*82#</strong> pour\n recevoir le code\n </p>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface TransactionStatusProps {\n status: \"polling\" | \"success\" | \"error\";\n elapsedSeconds?: number;\n message?: string;\n errorMessage?: string;\n paymentUrl?: string | null;\n onRetry?: () => void;\n onClose?: () => void;\n onOpenPaymentUrl?: () => void;\n className?: string;\n}\n\nfunction Spinner({ className }: { className?: string }) {\n return (\n <svg\n className={cn(\"animate-spin\", className)}\n width=\"56\"\n height=\"56\"\n viewBox=\"0 0 56 56\"\n fill=\"none\"\n >\n <circle\n cx=\"28\"\n cy=\"28\"\n r=\"24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n className=\"opacity-20\"\n />\n <path\n d=\"M28 4a24 24 0 0 1 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n className=\"text-primary\"\n />\n </svg>\n );\n}\n\nexport function TransactionStatus({\n status,\n elapsedSeconds = 0,\n message,\n errorMessage,\n paymentUrl,\n onRetry,\n onClose,\n onOpenPaymentUrl,\n className,\n}: TransactionStatusProps) {\n if (status === \"polling\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <Spinner />\n <div className=\"space-y-2 text-center\">\n <p className=\"text-base font-semibold text-foreground\">\n {paymentUrl\n ? \"Finalisez le paiement dans l'onglet ouvert...\"\n : \"Confirmez le paiement sur votre telephone...\"}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {paymentUrl\n ? \"Completez le paiement dans l'onglet, puis revenez ici.\"\n : \"Veuillez valider la transaction sur votre telephone.\"}\n </p>\n {elapsedSeconds > 0 && (\n <p className=\"text-xs text-muted-foreground/70\">\n Verification en cours... {elapsedSeconds}s\n </p>\n )}\n </div>\n {paymentUrl && (\n <div className=\"flex flex-col items-center gap-3\">\n <button\n type=\"button\"\n onClick={onOpenPaymentUrl}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6M15 3h6v6M10 14L21 3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n Ouvrir Wave pour payer\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-sm text-muted-foreground underline hover:text-foreground\"\n >\n Annuler\n </button>\n </div>\n )}\n </div>\n );\n }\n\n if (status === \"success\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Paiement reussi !\n </p>\n {message && (\n <p className=\"text-sm text-muted-foreground\">{message}</p>\n )}\n </div>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Fermer\n </button>\n )}\n </div>\n );\n }\n\n // error\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-red-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Echec du paiement\n </p>\n {errorMessage && (\n <p className=\"text-sm text-muted-foreground\">{errorMessage}</p>\n )}\n </div>\n <div className=\"flex gap-3\">\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Fermer\n </button>\n )}\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Reessayer\n </button>\n )}\n </div>\n </div>\n );\n}\n","export function formatCFA(n: number): string {\n return new Intl.NumberFormat(\"fr-FR\").format(n);\n}\n","import type { PaymentProvider } from \"@applite/duticotac\";\n\nexport function getPhoneRegex(provider: PaymentProvider): RegExp {\n switch (provider) {\n case \"OM_CI\":\n return /^(\\+225)(07)[0-9]{8}$/;\n case \"MTN_CI\":\n return /^(\\+225)(05)[0-9]{8}$/;\n case \"MOOV_CI\":\n return /^(\\+225)(01)[0-9]{8}$/;\n default:\n return /^(\\+225)(07|05|01)[0-9]{8}$/;\n }\n}\n\nexport function validatePhone(\n phone: string,\n provider: PaymentProvider,\n): string | null {\n if (!phone) return \"Numéro de téléphone requis\";\n const intl = phone.startsWith(\"+225\") ? phone : `+225${phone}`;\n const cleaned = intl.replace(/\\s/g, \"\");\n if (!getPhoneRegex(provider).test(cleaned)) {\n return \"Numéro invalide pour ce provider\";\n }\n return null;\n}\n\nexport function normalizePhone(phone: string): string {\n const cleaned = phone.replace(/\\s/g, \"\");\n return cleaned.startsWith(\"+225\") ? cleaned : `+225${cleaned}`;\n}\n\nexport function needsOtp(provider: PaymentProvider): boolean {\n return provider === \"OM_CI\";\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ResponsiveDialogProps {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n className?: string;\n}\n\nconst ANIMATION_MS = 250;\n\nexport function ResponsiveDialog({\n open,\n onClose,\n title,\n children,\n className,\n}: ResponsiveDialogProps) {\n const [mounted, setMounted] = React.useState(false);\n const [visible, setVisible] = React.useState(false);\n const panelRef = React.useRef<HTMLDivElement>(null);\n\n // Mount on open, animate in, then animate out before unmount\n React.useEffect(() => {\n if (open) {\n setMounted(true);\n // Trigger enter animation next frame\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setVisible(true));\n });\n } else if (mounted) {\n setVisible(false);\n const timer = setTimeout(() => setMounted(false), ANIMATION_MS);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n // Escape key\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n // Lock body scroll\n React.useEffect(() => {\n if (!mounted) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [mounted]);\n\n if (!mounted) return null;\n\n const dialog = (\n <>\n <style>{`\n .dtc-dialog-backdrop {\n position: fixed;\n inset: 0;\n z-index: 9998;\n background: rgba(0,0,0,0);\n transition: background ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-backdrop.dtc-visible {\n background: rgba(0,0,0,0.5);\n }\n\n /* ── Desktop: centered modal ── */\n .dtc-dialog-panel {\n position: fixed;\n z-index: 9999;\n background: var(--background, #fff);\n border: 1px solid var(--border, #e5e7eb);\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n\n /* Desktop default */\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n opacity: 0;\n width: calc(100% - 32px);\n max-width: 440px;\n max-height: calc(100vh - 64px);\n border-radius: 16px;\n overflow-y: auto;\n\n transition:\n transform ${ANIMATION_MS}ms cubic-bezier(0.22, 1, 0.36, 1),\n opacity ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translate(-50%, -50%) scale(1);\n opacity: 1;\n }\n\n /* ── Mobile: bottom sheet ── */\n @media (max-width: 640px) {\n .dtc-dialog-panel {\n top: auto;\n left: 0;\n right: 0;\n bottom: 0;\n transform: translateY(100%);\n opacity: 1;\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 20px 20px 0 0;\n border-bottom: none;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translateY(0);\n }\n }\n `}</style>\n\n {/* Backdrop */}\n <div\n className={cn(\"dtc-dialog-backdrop\", visible && \"dtc-visible\")}\n onClick={onClose}\n aria-hidden\n />\n\n {/* Panel */}\n <div\n ref={panelRef}\n className={cn(\"dtc-dialog-panel\", visible && \"dtc-visible\", className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n {/* Drag handle (mobile) */}\n <div className=\"dtc-mobile-handle\" style={{\n display: \"none\",\n justifyContent: \"center\",\n paddingTop: 12,\n paddingBottom: 4,\n }}>\n <div style={{\n width: 36,\n height: 4,\n borderRadius: 2,\n background: \"var(--border, #d1d5db)\",\n }} />\n </div>\n <style>{`\n @media (max-width: 640px) {\n .dtc-mobile-handle { display: flex !important; }\n }\n `}</style>\n\n {/* Header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"16px 20px 0\",\n }}>\n <h2 style={{\n fontSize: 18,\n fontWeight: 700,\n color: \"var(--foreground, #111)\",\n margin: 0,\n }}>\n {title}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n padding: 4,\n cursor: \"pointer\",\n borderRadius: 6,\n color: \"var(--muted-foreground, #6b7280)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n {/* Content */}\n <div style={{ padding: \"16px 20px 20px\" }}>\n {children}\n </div>\n </div>\n </>\n );\n\n if (typeof document === \"undefined\") return null;\n return createPortal(dialog, document.body);\n}\n","import * as React from \"react\";\nimport type { DuticotacSDK, PaymentProvider, TransactionModel, CoreApp, PlatformType } from \"@applite/duticotac\";\nimport { DuticotacPaymentModal } from \"../components/payment-modal\";\nimport { ResponsiveDialog } from \"../components/responsive-dialog\";\n\nexport interface UseDuticotacConfig {\n /** DuticotacSDK instance. */\n sdk: DuticotacSDK;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Shared defaults — can be overridden per pay() call. */\n productReference?: string;\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n initialPhone?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Dialog title (default: \"Paiement\"). */\n title?: string;\n}\n\nexport interface PayOptions {\n /** Amount in FCFA. */\n amount: number;\n\n /** Override providers for this payment. */\n providers?: PaymentProvider[];\n\n /** Override product reference. */\n productReference?: string;\n\n /** Override customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Called when payment is confirmed. */\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** Called when the dialog closes (success or cancel). */\n onClose?: () => void;\n}\n\nexport interface UseDuticotacReturn {\n /** Open the payment dialog with the given options. */\n pay: (options: PayOptions) => void;\n\n /** Whether the dialog is currently open. */\n isOpen: boolean;\n\n /** Close the dialog programmatically. */\n close: () => void;\n\n /**\n * The dialog JSX element. Render this once somewhere in your component tree.\n * @example return <>{Dialog}</>\n */\n Dialog: React.ReactNode;\n}\n\nexport function useDuticotac(config: UseDuticotacConfig): UseDuticotacReturn {\n const [open, setOpen] = React.useState(false);\n const [payOptions, setPayOptions] = React.useState<PayOptions | null>(null);\n\n const configRef = React.useRef(config);\n configRef.current = config;\n\n const pay = React.useCallback((options: PayOptions) => {\n setPayOptions(options);\n setOpen(true);\n }, []);\n\n const close = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n payOptions?.onClose?.();\n }, [payOptions]);\n\n const handleSuccess = React.useCallback(\n (tx: TransactionModel) => {\n payOptions?.onSuccess?.(tx);\n },\n [payOptions],\n );\n\n const DialogElement = React.useMemo(() => {\n if (!payOptions) return null;\n\n const cfg = configRef.current;\n\n return (\n <DuticotacPaymentModal\n open={open}\n onClose={handleClose}\n onSuccess={handleSuccess}\n sdk={cfg.sdk}\n amount={payOptions.amount}\n providers={payOptions.providers ?? cfg.providers}\n getTransactionId={cfg.getTransactionId}\n productReference={payOptions.productReference ?? cfg.productReference}\n initialPhone={cfg.initialPhone}\n name={payOptions.name ?? cfg.name}\n email={payOptions.email ?? cfg.email}\n customerId={payOptions.customerId ?? cfg.customerId}\n kolaboReference={cfg.kolaboReference}\n app={cfg.app}\n platform={cfg.platform}\n pollTimeout={cfg.pollTimeout}\n title={cfg.title}\n successMessage={payOptions.successMessage}\n renderModal={({ open: isOpen, onClose: modalClose, title: modalTitle, children }) => (\n <ResponsiveDialog\n open={isOpen}\n onClose={modalClose}\n title={modalTitle}\n >\n {children}\n </ResponsiveDialog>\n )}\n />\n );\n }, [open, payOptions, handleClose, handleSuccess]);\n\n return {\n pay,\n isOpen: open,\n close,\n Dialog: DialogElement,\n };\n}\n"],"mappings":"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","names":["DuticotacError","DuticotacSDK","getErrorMessage","getProviderLogo","getProviderName","import_duticotac","React","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsxs","jsx","React","Fragment","jsx","jsxs","React","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/index.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/errors.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/http.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/balance.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/offer.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/mobile-money.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/payment-method.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/webhook.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/modules/transaction.ts","../../../node_modules/.pnpm/@applite+duticotac@0.0.3/node_modules/@applite/duticotac/src/utils/providers.ts","../src/index.ts","../src/components/payment-modal.tsx","../src/components/provider-selector.tsx","../src/utils/cn.ts","../src/components/phone-input.tsx","../src/components/otp-input.tsx","../src/components/transaction-status.tsx","../src/utils/format.ts","../src/utils/validation.ts","../src/components/responsive-dialog.tsx","../src/hooks/use-duticotac.tsx"],"sourcesContent":["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","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","// Components\nexport { DuticotacPaymentModal } from \"./components/payment-modal\";\nexport type { DuticotacPaymentModalProps } from \"./components/payment-modal\";\n\nexport { ProviderSelector } from \"./components/provider-selector\";\nexport type { ProviderSelectorProps } from \"./components/provider-selector\";\n\nexport { PhoneInput } from \"./components/phone-input\";\nexport type { PhoneInputProps } from \"./components/phone-input\";\n\nexport { OtpInput } from \"./components/otp-input\";\nexport type { OtpInputProps } from \"./components/otp-input\";\n\nexport { TransactionStatus } from \"./components/transaction-status\";\nexport type { TransactionStatusProps } from \"./components/transaction-status\";\n\nexport { ResponsiveDialog } from \"./components/responsive-dialog\";\nexport type { ResponsiveDialogProps } from \"./components/responsive-dialog\";\n\n// Hooks\nexport { useDuticotac } from \"./hooks/use-duticotac\";\nexport type {\n UseDuticotacConfig,\n UseDuticotacReturn,\n PayOptions,\n} from \"./hooks/use-duticotac\";\n\n// Re-export core SDK so consumers don't need @applite/duticotac separately\nexport * from \"@applite/duticotac\";\n\n// Utilities\nexport { cn } from \"./utils/cn\";\nexport { formatCFA } from \"./utils/format\";\nexport {\n getPhoneRegex,\n validatePhone,\n normalizePhone,\n needsOtp,\n} from \"./utils/validation\";\n","import * as React from \"react\";\nimport {\n DuticotacSDK,\n DuticotacError,\n getErrorMessage,\n} from \"@applite/duticotac\";\nimport type {\n PaymentProvider,\n TransactionModel,\n CoreApp,\n PlatformType,\n} from \"@applite/duticotac\";\nimport { ProviderSelector } from \"./provider-selector\";\nimport { PhoneInput } from \"./phone-input\";\nimport { OtpInput } from \"./otp-input\";\nimport { TransactionStatus } from \"./transaction-status\";\nimport { cn } from \"../utils/cn\";\nimport { formatCFA } from \"../utils/format\";\nimport { validatePhone, normalizePhone, needsOtp } from \"../utils/validation\";\n\n// ─── Polling helpers ─────────────────────────────────────────────────────────\n\nfunction waitForVisibility(signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (typeof document === \"undefined\" || document.visibilityState === \"visible\") {\n resolve();\n return;\n }\n const handler = () => {\n if (document.visibilityState === \"visible\") {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n }\n };\n document.addEventListener(\"visibilitychange\", handler);\n signal?.addEventListener(\"abort\", () => {\n document.removeEventListener(\"visibilitychange\", handler);\n resolve();\n });\n });\n}\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\ntype Step = \"form\" | \"confirming\" | \"success\" | \"error\";\n\nexport interface DuticotacPaymentModalProps {\n open: boolean;\n onClose: () => void;\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** SDK instance or config to create one. */\n sdk: DuticotacSDK;\n\n /** Amount in the smallest currency unit. */\n amount: number;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Product reference for the cashout. */\n productReference?: string;\n\n /** Pre-fill phone number. */\n initialPhone?: string;\n\n /** Customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Custom title. */\n title?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Additional class names for the modal container. */\n className?: string;\n\n /**\n * Render prop for the modal wrapper. Receives children and renders them\n * inside your dialog/modal component. If not provided, a simple overlay is used.\n */\n renderModal?: (props: {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n }) => React.ReactNode;\n}\n\nconst DEFAULT_PROVIDERS: PaymentProvider[] = [\n \"OM_CI\",\n \"MTN_CI\",\n \"MOOV_CI\",\n \"WAVE_CI\",\n];\n\nexport function DuticotacPaymentModal({\n open,\n onClose,\n onSuccess,\n sdk,\n amount,\n providers = DEFAULT_PROVIDERS,\n getTransactionId,\n productReference,\n initialPhone = \"\",\n name: customerName,\n email: customerEmail,\n customerId,\n kolaboReference,\n app,\n platform,\n successMessage,\n title = \"Paiement\",\n pollTimeout = 90_000,\n className,\n renderModal,\n}: DuticotacPaymentModalProps) {\n const [step, setStep] = React.useState<Step>(\"form\");\n const [provider, setProvider] = React.useState<PaymentProvider>(providers[0]!);\n const [phone, setPhone] = React.useState(initialPhone);\n const [otp, setOtp] = React.useState(\"\");\n const [phoneError, setPhoneError] = React.useState<string | null>(null);\n const [errorMessage, setErrorMessage] = React.useState(\"\");\n const [paymentUrl, setPaymentUrl] = React.useState<string | null>(null);\n const [elapsedSeconds, setElapsedSeconds] = React.useState(0);\n const [lastTransaction, setLastTransaction] = React.useState<TransactionModel | null>(null);\n\n const abortRef = React.useRef<AbortController | null>(null);\n const elapsedRef = React.useRef<ReturnType<typeof setInterval> | null>(null);\n\n const cleanup = React.useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = null;\n if (elapsedRef.current) {\n clearInterval(elapsedRef.current);\n elapsedRef.current = null;\n }\n }, []);\n\n React.useEffect(() => {\n if (open) {\n setStep(\"form\");\n setErrorMessage(\"\");\n setOtp(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n setPhoneError(null);\n setLastTransaction(null);\n } else {\n cleanup();\n }\n }, [open, cleanup]);\n\n React.useEffect(() => () => cleanup(), [cleanup]);\n\n const isFormValid =\n phone.replace(/\\s/g, \"\").length >= 8 &&\n (needsOtp(provider) ? otp.length === 4 : true);\n\n const handleSubmit = async () => {\n // Validate phone\n const phoneErr = validatePhone(phone, provider);\n if (phoneErr) {\n setPhoneError(phoneErr);\n return;\n }\n setPhoneError(null);\n\n setStep(\"confirming\");\n setErrorMessage(\"\");\n cleanup();\n\n const controller = new AbortController();\n abortRef.current = controller;\n\n try {\n const transactionId = await getTransactionId();\n\n const result = await sdk.mobileMoney.cashout({\n transactionId,\n ref: productReference,\n phone: normalizePhone(phone),\n name: customerName ?? \"Duticotac App\",\n email: customerEmail ?? \"\",\n paymentMethod: provider,\n amount,\n otp: needsOtp(provider) ? otp : undefined,\n customerId,\n kolaboReference,\n app,\n plateform: platform,\n });\n\n const tx = result.data;\n\n if (tx?.paymentUrl) {\n setPaymentUrl(tx.paymentUrl);\n try {\n window.open(tx.paymentUrl, \"_blank\");\n } catch {\n // Popup may be blocked\n }\n }\n\n // Start polling\n const startTime = Date.now();\n setElapsedSeconds(0);\n elapsedRef.current = setInterval(() => {\n setElapsedSeconds(Math.floor((Date.now() - startTime) / 1000));\n }, 1000);\n\n const confirmed = await sdk.transaction.poll(tx.id ?? transactionId, {\n timeoutMs: pollTimeout,\n signal: controller.signal,\n onPoll: () => {\n // Wait for visibility before each poll\n },\n });\n\n setLastTransaction(confirmed.data);\n setStep(\"success\");\n onSuccess?.(confirmed.data);\n } catch (e) {\n if (controller.signal.aborted) return;\n\n if (e instanceof DuticotacError) {\n setErrorMessage(e.message);\n } else {\n setErrorMessage(\n getErrorMessage(\"unknown-error\"),\n );\n }\n setStep(\"error\");\n }\n };\n\n const handleRetry = () => {\n setStep(\"form\");\n setErrorMessage(\"\");\n setPaymentUrl(null);\n setElapsedSeconds(0);\n };\n\n // ─── Content ──────────────────────────────────────────────────────────────\n\n const content = (\n <div className={cn(\"space-y-5\", className)}>\n {step === \"form\" && (\n <>\n {/* Offer summary */}\n <div className=\"rounded-lg border-l-4 border-l-primary bg-muted/50 p-4\">\n <p className=\"text-xs text-muted-foreground\">Montant</p>\n <p className=\"text-xl font-bold text-primary\">\n {formatCFA(amount)} FCFA\n </p>\n </div>\n\n {/* Provider selection */}\n <div className=\"space-y-2\">\n <p className=\"text-sm font-semibold text-foreground\">\n Moyen de paiement\n </p>\n <ProviderSelector\n providers={providers}\n value={provider}\n onChange={(p) => {\n setProvider(p);\n if (!needsOtp(p)) setOtp(\"\");\n }}\n />\n </div>\n\n {/* Phone input */}\n <PhoneInput\n value={phone}\n onChange={(v) => {\n setPhone(v);\n setPhoneError(null);\n }}\n error={phoneError}\n autoFocus\n />\n\n {/* OTP input (Orange Money only) */}\n {needsOtp(provider) && (\n <OtpInput value={otp} onChange={setOtp} />\n )}\n\n {/* Actions */}\n <div className=\"flex justify-end gap-3 pt-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Annuler\n </button>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={!isFormValid}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\"\n >\n Payer {formatCFA(amount)} FCFA\n </button>\n </div>\n </>\n )}\n\n {step === \"confirming\" && (\n <TransactionStatus\n status=\"polling\"\n elapsedSeconds={elapsedSeconds}\n paymentUrl={paymentUrl}\n onOpenPaymentUrl={() => {\n if (paymentUrl) window.open(paymentUrl, \"_blank\");\n }}\n onClose={onClose}\n />\n )}\n\n {step === \"success\" && (\n <TransactionStatus\n status=\"success\"\n message={successMessage ?? \"Le paiement a ete effectue avec succes.\"}\n onClose={onClose}\n />\n )}\n\n {step === \"error\" && (\n <TransactionStatus\n status=\"error\"\n errorMessage={errorMessage}\n onRetry={handleRetry}\n onClose={onClose}\n />\n )}\n </div>\n );\n\n // ─── Render ───────────────────────────────────────────────────────────────\n\n if (renderModal) {\n return <>{renderModal({ open, onClose, title, children: content })}</>;\n }\n\n // Default simple overlay modal\n if (!open) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div\n className=\"absolute inset-0 bg-black/50\"\n onClick={onClose}\n />\n <div className=\"relative z-10 w-full max-w-md rounded-xl border border-border bg-background p-6 shadow-xl\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-bold text-foreground\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n {content}\n </div>\n </div>\n );\n}\n","import * as React from \"react\";\nimport type { PaymentProvider } from \"@applite/duticotac\";\nimport { getProviderName, getProviderLogo } from \"@applite/duticotac\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ProviderSelectorProps {\n providers: PaymentProvider[];\n value: PaymentProvider;\n onChange: (provider: PaymentProvider) => void;\n disabled?: boolean;\n className?: string;\n}\n\nexport function ProviderSelector({\n providers,\n value,\n onChange,\n disabled,\n className,\n}: ProviderSelectorProps) {\n return (\n <div className={cn(\"grid gap-2\", className)} style={{\n gridTemplateColumns: `repeat(${Math.min(providers.length, 4)}, 1fr)`,\n }}>\n {providers.map((provider) => {\n const selected = value === provider;\n return (\n <button\n key={provider}\n type=\"button\"\n disabled={disabled}\n onClick={() => onChange(provider)}\n className={cn(\n \"relative flex flex-col items-center gap-2 rounded-lg border-2 p-3 transition-all\",\n \"hover:scale-[1.02] disabled:pointer-events-none disabled:opacity-50\",\n selected\n ? \"border-primary bg-primary/5 shadow-sm\"\n : \"border-border bg-background hover:border-primary/40\",\n )}\n >\n {selected && (\n <div className=\"absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-primary\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n )}\n <img\n src={getProviderLogo(provider)}\n alt={getProviderName(provider)}\n width={44}\n height={44}\n className=\"rounded-lg object-contain\"\n />\n <span\n className={cn(\n \"text-center text-xs leading-tight\",\n selected\n ? \"font-semibold text-primary\"\n : \"font-medium text-muted-foreground\",\n )}\n >\n {getProviderName(provider)}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface PhoneInputProps {\n value: string;\n onChange: (value: string) => void;\n label?: string;\n placeholder?: string;\n error?: string | null;\n disabled?: boolean;\n className?: string;\n autoFocus?: boolean;\n}\n\nexport function PhoneInput({\n value,\n onChange,\n label = \"Numero de telephone\",\n placeholder = \"07 01 02 03 04\",\n error,\n disabled,\n className,\n autoFocus,\n}: PhoneInputProps) {\n return (\n <div className={cn(\"space-y-1.5\", className)}>\n {label && (\n <label className=\"block text-sm font-semibold text-foreground\">\n {label}\n </label>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"flex h-10 items-center rounded-md border border-border bg-muted px-3 text-sm font-medium text-muted-foreground\">\n +225\n </div>\n <input\n type=\"tel\"\n inputMode=\"numeric\"\n value={value}\n onChange={(e) => {\n const cleaned = e.target.value.replace(/[^\\d\\s]/g, \"\");\n onChange(cleaned);\n }}\n placeholder={placeholder}\n disabled={disabled}\n autoFocus={autoFocus}\n className={cn(\n \"h-10 w-full rounded-md border bg-background px-3 text-sm font-medium outline-none transition-colors\",\n \"placeholder:text-muted-foreground/50\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n error ? \"border-destructive\" : \"border-border\",\n )}\n />\n </div>\n {error && (\n <p className=\"text-xs font-medium text-destructive\">{error}</p>\n )}\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface OtpInputProps {\n value: string;\n onChange: (value: string) => void;\n length?: number;\n disabled?: boolean;\n className?: string;\n}\n\nexport function OtpInput({\n value,\n onChange,\n length = 4,\n disabled,\n className,\n}: OtpInputProps) {\n const inputRefs = React.useRef<(HTMLInputElement | null)[]>([]);\n const digits = value.padEnd(length, \"\").slice(0, length).split(\"\");\n\n const setDigit = (index: number, char: string) => {\n const next = [...digits];\n next[index] = char;\n onChange(next.join(\"\"));\n };\n\n const handleKeyDown = (\n index: number,\n e: React.KeyboardEvent<HTMLInputElement>,\n ) => {\n if (e.key === \"Backspace\") {\n e.preventDefault();\n if (digits[index]?.trim()) {\n setDigit(index, \"\");\n } else if (index > 0) {\n setDigit(index - 1, \"\");\n inputRefs.current[index - 1]?.focus();\n }\n } else if (e.key === \"ArrowLeft\" && index > 0) {\n inputRefs.current[index - 1]?.focus();\n } else if (e.key === \"ArrowRight\" && index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handleInput = (\n index: number,\n e: React.FormEvent<HTMLInputElement>,\n ) => {\n const val = (e.target as HTMLInputElement).value;\n const char = val.replace(/\\D/g, \"\").slice(-1);\n if (!char) return;\n setDigit(index, char);\n if (index < length - 1) {\n inputRefs.current[index + 1]?.focus();\n }\n };\n\n const handlePaste = (e: React.ClipboardEvent) => {\n e.preventDefault();\n const pasted = e.clipboardData\n .getData(\"text\")\n .replace(/\\D/g, \"\")\n .slice(0, length);\n if (!pasted) return;\n onChange(pasted.padEnd(length, \"\").slice(0, length).replace(/ /g, \"\"));\n const focusIndex = Math.min(pasted.length, length - 1);\n inputRefs.current[focusIndex]?.focus();\n };\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n <label className=\"block text-sm font-semibold text-muted-foreground\">\n Code OTP\n </label>\n <div className=\"flex justify-center gap-3\" onPaste={handlePaste}>\n {Array.from({ length }).map((_, i) => {\n const filled = !!digits[i]?.trim();\n return (\n <input\n key={i}\n ref={(el) => {\n inputRefs.current[i] = el;\n }}\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={1}\n value={digits[i]?.trim() || \"\"}\n onKeyDown={(e) => handleKeyDown(i, e)}\n onInput={(e) => handleInput(i, e)}\n onFocus={(e) => e.target.select()}\n disabled={disabled}\n className={cn(\n \"h-13 w-13 rounded-md border-2 text-center text-xl font-bold outline-none transition-all\",\n \"focus:border-primary focus:ring-2 focus:ring-primary/20 focus:scale-105\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n filled ? \"border-primary/30 bg-primary/5\" : \"border-border bg-background\",\n )}\n />\n );\n })}\n </div>\n <p className=\"text-center text-xs text-muted-foreground\">\n Faites <strong className=\"text-foreground\">#144*82#</strong> pour\n recevoir le code\n </p>\n </div>\n );\n}\n","import * as React from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport interface TransactionStatusProps {\n status: \"polling\" | \"success\" | \"error\";\n elapsedSeconds?: number;\n message?: string;\n errorMessage?: string;\n paymentUrl?: string | null;\n onRetry?: () => void;\n onClose?: () => void;\n onOpenPaymentUrl?: () => void;\n className?: string;\n}\n\nfunction Spinner({ className }: { className?: string }) {\n return (\n <svg\n className={cn(\"animate-spin\", className)}\n width=\"56\"\n height=\"56\"\n viewBox=\"0 0 56 56\"\n fill=\"none\"\n >\n <circle\n cx=\"28\"\n cy=\"28\"\n r=\"24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n className=\"opacity-20\"\n />\n <path\n d=\"M28 4a24 24 0 0 1 24 24\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n className=\"text-primary\"\n />\n </svg>\n );\n}\n\nexport function TransactionStatus({\n status,\n elapsedSeconds = 0,\n message,\n errorMessage,\n paymentUrl,\n onRetry,\n onClose,\n onOpenPaymentUrl,\n className,\n}: TransactionStatusProps) {\n if (status === \"polling\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <Spinner />\n <div className=\"space-y-2 text-center\">\n <p className=\"text-base font-semibold text-foreground\">\n {paymentUrl\n ? \"Finalisez le paiement dans l'onglet ouvert...\"\n : \"Confirmez le paiement sur votre telephone...\"}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {paymentUrl\n ? \"Completez le paiement dans l'onglet, puis revenez ici.\"\n : \"Veuillez valider la transaction sur votre telephone.\"}\n </p>\n {elapsedSeconds > 0 && (\n <p className=\"text-xs text-muted-foreground/70\">\n Verification en cours... {elapsedSeconds}s\n </p>\n )}\n </div>\n {paymentUrl && (\n <div className=\"flex flex-col items-center gap-3\">\n <button\n type=\"button\"\n onClick={onOpenPaymentUrl}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6M15 3h6v6M10 14L21 3\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n Ouvrir Wave pour payer\n </button>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-sm text-muted-foreground underline hover:text-foreground\"\n >\n Annuler\n </button>\n </div>\n )}\n </div>\n );\n }\n\n if (status === \"success\") {\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-emerald-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M5 12l5 5L20 7\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Paiement reussi !\n </p>\n {message && (\n <p className=\"text-sm text-muted-foreground\">{message}</p>\n )}\n </div>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md bg-primary px-6 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Fermer\n </button>\n )}\n </div>\n );\n }\n\n // error\n return (\n <div className={cn(\"flex flex-col items-center gap-4 py-8\", className)}>\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full bg-red-500 animate-in zoom-in duration-500\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"#fff\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n />\n </svg>\n </div>\n <div className=\"space-y-2 text-center animate-in fade-in slide-in-from-bottom-4 duration-400 delay-150\">\n <p className=\"text-lg font-bold text-foreground\">\n Echec du paiement\n </p>\n {errorMessage && (\n <p className=\"text-sm text-muted-foreground\">{errorMessage}</p>\n )}\n </div>\n <div className=\"flex gap-3\">\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border bg-background px-5 py-2.5 text-sm font-semibold text-foreground transition-colors hover:bg-muted\"\n >\n Fermer\n </button>\n )}\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"rounded-md bg-primary px-5 py-2.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90\"\n >\n Reessayer\n </button>\n )}\n </div>\n </div>\n );\n}\n","export function formatCFA(n: number): string {\n return new Intl.NumberFormat(\"fr-FR\").format(n);\n}\n","import type { PaymentProvider } from \"@applite/duticotac\";\n\nexport function getPhoneRegex(provider: PaymentProvider): RegExp {\n switch (provider) {\n case \"OM_CI\":\n return /^(\\+225)(07)[0-9]{8}$/;\n case \"MTN_CI\":\n return /^(\\+225)(05)[0-9]{8}$/;\n case \"MOOV_CI\":\n return /^(\\+225)(01)[0-9]{8}$/;\n default:\n return /^(\\+225)(07|05|01)[0-9]{8}$/;\n }\n}\n\nexport function validatePhone(\n phone: string,\n provider: PaymentProvider,\n): string | null {\n if (!phone) return \"Numéro de téléphone requis\";\n const intl = phone.startsWith(\"+225\") ? phone : `+225${phone}`;\n const cleaned = intl.replace(/\\s/g, \"\");\n if (!getPhoneRegex(provider).test(cleaned)) {\n return \"Numéro invalide pour ce provider\";\n }\n return null;\n}\n\nexport function normalizePhone(phone: string): string {\n const cleaned = phone.replace(/\\s/g, \"\");\n return cleaned.startsWith(\"+225\") ? cleaned : `+225${cleaned}`;\n}\n\nexport function needsOtp(provider: PaymentProvider): boolean {\n return provider === \"OM_CI\";\n}\n","import * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ResponsiveDialogProps {\n open: boolean;\n onClose: () => void;\n title: string;\n children: React.ReactNode;\n className?: string;\n}\n\nconst ANIMATION_MS = 250;\n\nexport function ResponsiveDialog({\n open,\n onClose,\n title,\n children,\n className,\n}: ResponsiveDialogProps) {\n const [mounted, setMounted] = React.useState(false);\n const [visible, setVisible] = React.useState(false);\n const panelRef = React.useRef<HTMLDivElement>(null);\n\n // Mount on open, animate in, then animate out before unmount\n React.useEffect(() => {\n if (open) {\n setMounted(true);\n // Trigger enter animation next frame\n requestAnimationFrame(() => {\n requestAnimationFrame(() => setVisible(true));\n });\n } else if (mounted) {\n setVisible(false);\n const timer = setTimeout(() => setMounted(false), ANIMATION_MS);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n // Escape key\n React.useEffect(() => {\n if (!open) return;\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", handler);\n return () => document.removeEventListener(\"keydown\", handler);\n }, [open, onClose]);\n\n // Lock body scroll\n React.useEffect(() => {\n if (!mounted) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [mounted]);\n\n if (!mounted) return null;\n\n const dialog = (\n <>\n <style>{`\n .dtc-dialog-backdrop {\n position: fixed;\n inset: 0;\n z-index: 9998;\n background: rgba(0,0,0,0);\n transition: background ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-backdrop.dtc-visible {\n background: rgba(0,0,0,0.5);\n }\n\n /* ── Desktop: centered modal ── */\n .dtc-dialog-panel {\n position: fixed;\n z-index: 9999;\n background: var(--background, #fff);\n border: 1px solid var(--border, #e5e7eb);\n box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);\n\n /* Desktop default */\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%) scale(0.95);\n opacity: 0;\n width: calc(100% - 32px);\n max-width: 440px;\n max-height: calc(100vh - 64px);\n border-radius: 16px;\n overflow-y: auto;\n\n transition:\n transform ${ANIMATION_MS}ms cubic-bezier(0.22, 1, 0.36, 1),\n opacity ${ANIMATION_MS}ms ease;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translate(-50%, -50%) scale(1);\n opacity: 1;\n }\n\n /* ── Mobile: bottom sheet ── */\n @media (max-width: 640px) {\n .dtc-dialog-panel {\n top: auto;\n left: 0;\n right: 0;\n bottom: 0;\n transform: translateY(100%);\n opacity: 1;\n width: 100%;\n max-width: 100%;\n max-height: 90vh;\n border-radius: 20px 20px 0 0;\n border-bottom: none;\n }\n .dtc-dialog-panel.dtc-visible {\n transform: translateY(0);\n }\n }\n `}</style>\n\n {/* Backdrop */}\n <div\n className={cn(\"dtc-dialog-backdrop\", visible && \"dtc-visible\")}\n onClick={onClose}\n aria-hidden\n />\n\n {/* Panel */}\n <div\n ref={panelRef}\n className={cn(\"dtc-dialog-panel\", visible && \"dtc-visible\", className)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n {/* Drag handle (mobile) */}\n <div className=\"dtc-mobile-handle\" style={{\n display: \"none\",\n justifyContent: \"center\",\n paddingTop: 12,\n paddingBottom: 4,\n }}>\n <div style={{\n width: 36,\n height: 4,\n borderRadius: 2,\n background: \"var(--border, #d1d5db)\",\n }} />\n </div>\n <style>{`\n @media (max-width: 640px) {\n .dtc-mobile-handle { display: flex !important; }\n }\n `}</style>\n\n {/* Header */}\n <div style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"16px 20px 0\",\n }}>\n <h2 style={{\n fontSize: 18,\n fontWeight: 700,\n color: \"var(--foreground, #111)\",\n margin: 0,\n }}>\n {title}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n padding: 4,\n cursor: \"pointer\",\n borderRadius: 6,\n color: \"var(--muted-foreground, #6b7280)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M6 18L18 6M6 6l12 12\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n {/* Content */}\n <div style={{ padding: \"16px 20px 20px\" }}>\n {children}\n </div>\n </div>\n </>\n );\n\n if (typeof document === \"undefined\") return null;\n return createPortal(dialog, document.body);\n}\n","import * as React from \"react\";\nimport type { DuticotacSDK, PaymentProvider, TransactionModel, CoreApp, PlatformType } from \"@applite/duticotac\";\nimport { DuticotacPaymentModal } from \"../components/payment-modal\";\nimport { ResponsiveDialog } from \"../components/responsive-dialog\";\n\nexport interface UseDuticotacConfig {\n /** DuticotacSDK instance. */\n sdk: DuticotacSDK;\n\n /** Available payment providers. */\n providers?: PaymentProvider[];\n\n /** Called to get a unique transaction ID before cashout. */\n getTransactionId: () => Promise<string>;\n\n /** Shared defaults — can be overridden per pay() call. */\n productReference?: string;\n name?: string;\n email?: string;\n customerId?: string;\n kolaboReference?: string;\n app?: CoreApp;\n platform?: PlatformType;\n initialPhone?: string;\n\n /** Polling timeout in ms (default: 90000). */\n pollTimeout?: number;\n\n /** Dialog title (default: \"Paiement\"). */\n title?: string;\n}\n\nexport interface PayOptions {\n /** Amount in FCFA. */\n amount: number;\n\n /** Override providers for this payment. */\n providers?: PaymentProvider[];\n\n /** Override product reference. */\n productReference?: string;\n\n /** Override customer details. */\n name?: string;\n email?: string;\n customerId?: string;\n\n /** Custom success message. */\n successMessage?: string;\n\n /** Called when payment is confirmed. */\n onSuccess?: (transaction: TransactionModel) => void;\n\n /** Called when the dialog closes (success or cancel). */\n onClose?: () => void;\n}\n\nexport interface UseDuticotacReturn {\n /** Open the payment dialog with the given options. */\n pay: (options: PayOptions) => void;\n\n /** Whether the dialog is currently open. */\n isOpen: boolean;\n\n /** Close the dialog programmatically. */\n close: () => void;\n\n /**\n * The dialog JSX element. Render this once somewhere in your component tree.\n * @example return <>{Dialog}</>\n */\n Dialog: React.ReactNode;\n}\n\nexport function useDuticotac(config: UseDuticotacConfig): UseDuticotacReturn {\n const [open, setOpen] = React.useState(false);\n const [payOptions, setPayOptions] = React.useState<PayOptions | null>(null);\n\n const configRef = React.useRef(config);\n configRef.current = config;\n\n const pay = React.useCallback((options: PayOptions) => {\n setPayOptions(options);\n setOpen(true);\n }, []);\n\n const close = React.useCallback(() => {\n setOpen(false);\n }, []);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n payOptions?.onClose?.();\n }, [payOptions]);\n\n const handleSuccess = React.useCallback(\n (tx: TransactionModel) => {\n payOptions?.onSuccess?.(tx);\n },\n [payOptions],\n );\n\n const DialogElement = React.useMemo(() => {\n if (!payOptions) return null;\n\n const cfg = configRef.current;\n\n return (\n <DuticotacPaymentModal\n open={open}\n onClose={handleClose}\n onSuccess={handleSuccess}\n sdk={cfg.sdk}\n amount={payOptions.amount}\n providers={payOptions.providers ?? cfg.providers}\n getTransactionId={cfg.getTransactionId}\n productReference={payOptions.productReference ?? cfg.productReference}\n initialPhone={cfg.initialPhone}\n name={payOptions.name ?? cfg.name}\n email={payOptions.email ?? cfg.email}\n customerId={payOptions.customerId ?? cfg.customerId}\n kolaboReference={cfg.kolaboReference}\n app={cfg.app}\n platform={cfg.platform}\n pollTimeout={cfg.pollTimeout}\n title={cfg.title}\n successMessage={payOptions.successMessage}\n renderModal={({ open: isOpen, onClose: modalClose, title: modalTitle, children }) => (\n <ResponsiveDialog\n open={isOpen}\n onClose={modalClose}\n title={modalTitle}\n >\n {children}\n </ResponsiveDialog>\n )}\n />\n );\n }, [open, payOptions, handleClose, handleSuccess]);\n\n return {\n pay,\n isOpen: open,\n close,\n Dialog: DialogElement,\n };\n}\n"],"mappings":"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","names":["index_exports","__export","DuticotacError","DuticotacSDK","getErrorMessage","getProviderLogo","getProviderName","import_duticotac","React","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsxs","jsx","React","Fragment","jsx","jsxs","React","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applite/duticotac-react",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "React UI components for Duticotac payments (Shadcn-based)",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"main": "./dist/index.
|
|
7
|
-
"module": "./dist/index.
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
|
-
"import": "./dist/index.
|
|
17
|
-
"require": "./dist/index.
|
|
16
|
+
"import": "./dist/index.mjs",
|
|
17
|
+
"require": "./dist/index.js"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"react-dom": ">=18"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applite/duticotac": "^0.0.
|
|
31
|
+
"@applite/duticotac": "^0.0.4",
|
|
32
32
|
"class-variance-authority": "^0.7.1",
|
|
33
33
|
"clsx": "^2.1.1",
|
|
34
34
|
"tailwind-merge": "^3.0.2"
|