import { AttributionControl } from 'maplibre-gl'; import { default as default_2 } from 'react'; import { Map as MapLibreMap } from 'maplibre-gl'; import { Marker as MapLibreMarker } from 'maplibre-gl'; import { MapMouseEvent } from 'maplibre-gl'; import { NavigationControl } from 'maplibre-gl'; import { ReactNode } from 'react'; export declare const ADDRESS_LABELS: AddressLabel[]; /** * Address components from Nominatim/OpenStreetMap (via reverse geocoding). */ export declare interface AddressComponents { house_number?: string; road?: string; neighbourhood?: string; suburb?: string; city?: string; state?: string; postcode?: string; country?: string; country_code?: string; name?: string; addr_housename?: string; addr_place?: string; building?: string; building_name?: string; [key: string]: string | undefined; } export declare type AddressConfidenceState = 'new_source_collected' | 'buyer_reconfirmed' | 'merchant_successful' | 'courier_corrected' | 'rto_associated' | 'trusted_repeat'; export declare const AddressForm: default_2.FC; /** Pre-fill manual fields when verifying an imported saved address. */ export declare interface AddressFormInitialValues { flatNumber?: string; floorNumber?: string; buildingName?: string; streetName?: string; locality?: string; label?: AddressLabel; labelText?: string; } export declare interface AddressFormProps { digipin: string; lat: number; lng: number; apiKey: string; apiBaseUrl?: string; onAddressComplete: (address: CompleteAddress) => void; onBack: () => void; onError?: (error: Error) => void; theme?: 'light' | 'dark'; /** Pre-populate manual fields from a saved address row (lazy DigiPin verify). */ initialValues?: AddressFormInitialValues; /** Override primary submit button label (default: "Save Address"). */ submitLabel?: string; /** Checkout API config for merchant serviceability checks. */ checkoutConfig?: CheckoutApiConfig; /** Buyer session token used by checkout-addresses serviceability_check. */ serviceabilitySessionToken?: string; /** When true, calls the merchant courier serviceability endpoint after pincode validation. */ enableServiceabilityCheck?: boolean; /** Shows a soft India Post home-delivery info banner when merchant check is absent/failed. */ showIndiaPostDeliveryWarning?: boolean; /** Optional client override for blocking address save when merchant says not serviceable. */ serviceabilityBlockCheckout?: boolean; /** Optional observer for the merchant serviceability result. */ onServiceabilityResult?: (result: ServiceabilityResult) => void; } export declare type AddressIntervention = 'none' | 'request_missing_details' | 'reconfirm_pin' | 'prepaid_nudge' | 'hide_cod' | 'manual_review' | 'delivery_instruction'; /** Label for a saved buyer address — stored in checkout-addresses API. */ export declare type AddressLabel = 'home' | 'work' | 'other'; export declare type AddressRiskLevel = 'low' | 'medium' | 'high'; export declare interface AddressRiskPayload { address_id?: string; digipin?: string; lat?: number; lng?: number; pincode?: string; state?: string; district?: string; locality?: string; delivery_status?: string; flat_number?: string; floor_number?: string; building_name?: string; street_name?: string; payment_method?: string; } export declare interface AddressRiskScore { level: AddressRiskLevel; score: number; reasons: string[]; interventions: AddressIntervention[]; confidence_state: AddressConfidenceState; signals: AddressRiskSignals; scored_at: string; } declare interface AddressRiskSignals { merchant_history_records: number; buyer_successful_deliveries: number; buyer_rto_orders: number; pincode_successful_deliveries: number; pincode_rto_orders: number; digipin_cell_successful_deliveries: number; digipin_cell_rto_orders: number; repeat_verified_address: boolean; imported_address_pending_digipin: boolean; cod_requested: boolean; address_edit_count: number; } export declare interface AdministrativeInfo { country?: string; state: string; division: string; locality: string; pincode: string; delivery: string; district: string; } declare type AnyStyle = any; /** * Call QuantaRoute's autocomplete API. * Minimum 3 characters required; max 10 suggestions. * * Pass userLat / userLng (the map pin's current position) to unlock: * – Location-biased results (~50 km soft radius around the pin) * – "Near me" / "nearby" keyword support with a tight ~10 km hard radius */ export declare function autocompleteAddress(query: string, apiKey: string, baseUrl?: string, limit?: number, userLat?: number, userLng?: number): Promise; export declare interface AutocompleteResponse { success: boolean; data: AutocompleteSuggestion[]; error?: string; message?: string; } /** One address suggestion from /v1/digipin/autocomplete */ export declare interface AutocompleteSuggestion { displayName: string; address: string; coordinates: { latitude: number; longitude: number; }; confidence: number; addressComponents: { house_number?: string; road?: string; neighbourhood?: string; suburb?: string; city?: string; state?: string; postcode?: string; country?: string; [key: string]: string | undefined; }; } /** Read UTM params from the current page URL (web). Returns {} on native or SSR. */ export declare function captureUtmFromUrl(href?: string): UtmParams; /** * Check COD availability for a delivery pincode (Edge: `cod_eligibility`). * Respects `checkout.merchants.enable_cod` (C4), `cod_blocked_pincodes` / `cod_max_cart_value_paise` (D1/D2). * Pass `cartTotalPaise` in paise (e.g. ₹499 → 49900) to enforce the cart cap when set. */ export declare function checkCodEligibility(config: CheckoutApiConfig, sessionToken: string, pincode: string, cartTotalPaise?: number): Promise; export declare interface CheckoutApiConfig { /** Supabase Edge Function base URL, e.g. https://.supabase.co/functions/v1 */ functionBaseUrl: string; /** UUID of the merchant from checkout.merchants */ merchantId: string; } /** * Payload delivered to `onCheckoutEvent` on every step transition. * Forward this to MoEngage, Clevertap, GTM, or your own analytics. */ export declare interface CheckoutEvent { /** The event that just occurred. */ type: CheckoutEventType; /** The step the widget moved INTO. */ step: string; /** Buyer's phone number (E.164) or email. Available after OTP sent. */ mobile?: string; /** Internal buyer UUID. Available after auth verification. */ buyerId?: string; /** Checkout session UUID. Available after auth verification. */ sessionId?: string; /** Auth channel used in this session. */ authChannel?: 'phone' | 'email' | 'none'; /** Device class: mobile | tablet | desktop */ deviceType?: 'mobile' | 'tablet' | 'desktop'; /** Platform: web | ios | android */ platform?: 'web' | 'ios' | 'android'; /** Truncated user agent (web). */ userAgent?: string; /** Payment method when selected: cod | prepaid | upi | card | … */ paymentMethod?: string; /** A/B experiment variant label from `variant` prop. */ experimentVariant?: string; /** DigiPin of the confirmed location. Available after `location_confirmed` and `address_completed`. */ digipin?: string; /** Address risk level when `address_risk_scored` fires. */ addressRiskLevel?: AddressRiskScore['level']; /** Address risk score (0-100) when address intelligence is enabled. */ addressRiskScore?: number; /** ISO timestamp of when the event fired. */ timestamp: string; } /** All step-transition event types emitted by the widget. */ export declare type CheckoutEventType = 'phone_step_viewed' | 'otp_sent' | 'phone_verified' | 'email_step_viewed' | 'email_otp_sent' | 'email_verified' | 'auth_skipped' | 'saved_addresses_viewed' | 'saved_address_selected' | 'verify_address_step_viewed' | 'map_step_viewed' | 'location_confirmed' | 'form_step_viewed' | 'address_completed' | 'address_risk_scored' | 'widget_reset' | 'payment_step_viewed' | 'payment_method_selected' | 'session_abandoned'; export declare type CheckoutMobilePresentation = 'auto' | 'sheet' | 'card'; export declare interface CheckoutMobileStepLabels { auth?: string; address?: string; payment?: string; } declare type CheckoutPlatform = 'web' | 'ios' | 'android'; /** * QuantaRoute Checkout Widget * * Default (enablePhoneAuth = false): * map → form → done * * With phone auth (enablePhoneAuth = true): * phone → otp → saved → map → form → done * (buyer can skip phone auth to go straight to map) */ declare const CheckoutWidget: default_2.FC; export { CheckoutWidget } export default CheckoutWidget; /** Imperative hooks for host pages (e.g. Shopify pre-checkout shell). */ declare interface CheckoutWidgetController { /** Navigate one step back within the widget. Returns true if handled. */ goBack: () => boolean; getStep: () => string; } export declare interface CheckoutWidgetProps { /** * Your QuantaRoute API key. * Get one free at https://quantaroute.com */ apiKey: string; /** API base URL. Defaults to https://api.quantaroute.com */ apiBaseUrl?: string; /** Callback fired when user completes the full address entry. */ onComplete: (address: CompleteAddress) => void; /** Optional error handler. */ onError?: (error: Error) => void; /** Default map latitude (center). If provided, map opens at this location. */ defaultLat?: number; /** Default map longitude (center). */ defaultLng?: number; /** Color theme. Defaults to 'light'. */ theme?: 'light' | 'dark'; /** CSS class name(s) to add to the root element (web only). */ className?: string; /** Inline styles for the root element (CSSProperties on web, StyleProp on native). */ style?: AnyStyle; /** Map area height. String on web ('380px'), number on native (380). Defaults to '380px' / 380. */ mapHeight?: string | number; /** Widget header title. Defaults to 'Add Delivery Address'. */ title?: string; /** * Mobile visual treatment. `auto` applies the improved mobile layout below 480px, * `sheet` is for storefront drawers/modals, and `card` preserves the compact card feel. */ mobilePresentation?: CheckoutMobilePresentation; /** Override the compact mobile step labels (e.g. Mobile / Address / Pay). */ mobileStepLabels?: CheckoutMobileStepLabels; /** * URL to an India boundary GeoJSON file (FeatureCollection). * When provided, a thin grey outline is drawn on the map for legal compliance. * Host the file in your app's public folder and pass its path here. * Example: indiaBoundaryUrl="/geojson/india.geojson" */ indiaBoundaryUrl?: string; /** * MapLibre style URL for the map step. Defaults to Carto Positron. * Pass `OPENFREEMAP_POSITRON_STYLE_URL` when Carto basemaps require credentials. */ mapStyle?: string; /** * How MapLibre GL JS is loaded on web. `external` waits for `window.maplibregl` * when the host loads MapLibre from a CDN (e.g. Shopify theme extensions). */ embedMode?: MapEmbedMode; /** * Show the smart search bar on the map step (default: true). * Supports address search (API) and DigiPin lookup (100% offline). * As India Post promotes DigiPin, buyers can just type their 10-char code * and the map instantly flies to their ~4m × 4m location — zero API cost. */ enableSearch?: boolean; /** * Enable phone OTP authentication for saved addresses (default: false). * When true, the widget starts with a phone entry step so returning buyers * can access their previously saved addresses — reducing re-entry friction. * Requires merchantId and supabaseFunctionBaseUrl to be set. * Takes precedence over enableEmailAuth if both are set. */ enablePhoneAuth?: boolean; /** * Enable email OTP authentication via Resend (default: false). * When true (and enablePhoneAuth is false), the widget starts with an email * entry step. Requires merchantId and supabaseFunctionBaseUrl to be set. * Needs RESEND_API_KEY + RESEND_FROM_EMAIL on the checkout-email-otp Edge Function. */ enableEmailAuth?: boolean; /** * UUID of your merchant record in checkout.merchants. * Required when enablePhoneAuth or enableEmailAuth is true. */ merchantId?: string; /** * Base URL of your Supabase Edge Functions deployment. * Example: "https://ikfiewesidedxozotmrl.supabase.co/functions/v1" * Required when enablePhoneAuth or enableEmailAuth is true. */ supabaseFunctionBaseUrl?: string; /** * When true, shows a Cash on Delivery availability strip on the success screen * (calls `cod_eligibility`). Requires `merchantId`, `supabaseFunctionBaseUrl`, and a * session token from phone auth or `codSessionToken`. On the server, set * `checkout.merchants.enable_cod` and optional D1/D2 columns. */ enableCod?: boolean; /** * Call the merchant's courier serviceability webhook for the resolved pincode. * Requires `merchantId`, `supabaseFunctionBaseUrl`, and an authenticated checkout session. */ enableServiceabilityCheck?: boolean; /** * Score address-discrepancy-led RTO risk after address completion. * Requires `merchantId`, `supabaseFunctionBaseUrl`, and phone/email auth or `codSessionToken`. */ enableAddressIntelligence?: boolean; /** * Opt-in fallback banner for India Post "Non Delivery" pincodes. * Defaults off because courier partners may still deliver. */ showIndiaPostDeliveryWarning?: boolean; /** * Client override: block address save when merchant serviceability says not deliverable. * If omitted, the server result from checkout.merchants.serviceability_block_checkout is used. */ serviceabilityBlockCheckout?: boolean; /** * Cart total in paise for the COD cart cap (D2). Omit if the cart total is unknown. */ codCartTotalPaise?: number; /** * Session token for the COD check when your app manages auth outside the widget’s phone flow. */ codSessionToken?: string; /** * Brand accent colour (hex, e.g. `#7c3aed`). On web, sets `--qr-primary` on the root; on native, passed to the map pin and header accents. */ brandColor?: string; /** * Merchant logo URL shown in the widget header (replaces default map icon when set). */ logoUrl?: string; /** * Optional slot below the header row for trust badges, free-shipping strip, or any custom JSX. */ headerBanner?: ReactNode; /** * Client-side analytics hook. Called on every step transition so you can * forward events to MoEngage, Clevertap, GTM, or your own backend. * * @example * onCheckoutEvent={(event) => { * Moengage.track_event(event.type, { step: event.step, buyerId: event.buyerId }); * }} */ onCheckoutEvent?: (event: CheckoutEvent) => void; /** * A/B experiment variant label — included on every `onCheckoutEvent` payload * and stored on the checkout session for funnel breakdowns. */ variant?: string; /** * UTM params captured from the page URL at widget mount (web). * Stored on the session when the buyer verifies OTP. */ utmParams?: UtmParams; /** * Enable Razorpay payment step after address completion (requires merchant Razorpay keys). */ enablePayment?: boolean; /** Cart total in paise for Razorpay order creation. Required when enablePayment is true. */ paymentAmountPaise?: number; /** Called when payment completes (prepaid or COD). */ onPaymentComplete?: (result: { paymentMethod: string; sessionId?: string; razorpayOrderId?: string; razorpayPaymentId?: string; }) => void; /** * URL to redirect the buyer to after successful payment. * Use `{{sessionId}}` as a placeholder — the widget replaces it before redirecting. * Example: "https://yourstore.com/order/confirm?sid={{sessionId}}" * When omitted, no redirect occurs and the host app handles navigation via onPaymentComplete. */ orderConfirmationUrl?: string; /** * Show prepaid conversion nudge when COD is eligible (merchant `prepaid_nudge_copy` or prop override). */ enablePrepaidNudge?: boolean; /** Override merchant prepaid nudge copy. */ prepaidNudgeCopy?: string; /** Override merchant prepaid nudge CTA URL. */ prepaidNudgeCtaUrl?: string; /** * Called once on mount with imperative navigation helpers for host shells * (step-aware back button, etc.). */ registerController?: (controller: CheckoutWidgetController) => void; } /** * Check merchant courier serviceability for a pincode. * Uses the merchant's configured webhook on checkout.merchants and fails open. */ export declare function checkServiceability(config: CheckoutApiConfig, sessionToken: string, pincode: string, coords?: { lat?: number; lng?: number; }): Promise; /** * Shows COD availability after checkout using `cod_eligibility` (merchant `enable_cod` + D1/D2). */ export declare const CodAvailabilityBanner: default_2.FC; declare interface CodAvailabilityBannerProps { checkoutConfig: CheckoutApiConfig; sessionToken: string; pincode: string; cartTotalPaise?: number; theme?: 'light' | 'dark'; /** Called when COD eligibility is resolved (for prepaid nudge gating). */ onCodAllowedChange?: (allowed: boolean) => void; } export declare interface CodEligibilityResult { /** Whether COD is allowed for this pincode for the session merchant. */ cod_allowed: boolean; /** Normalized 6-digit pincode when valid; otherwise the trimmed input. */ pincode: string; /** Present when COD is not allowed or the pincode could not be normalized. */ reason?: 'cod_disabled' | 'pincode_blocked' | 'invalid_pincode' | 'cart_value_exceeded'; /** Merchant COD cart cap in paise; null when unlimited. */ cod_max_cart_value_paise?: number | null; /** Echo of `cartTotalPaise` when sent. */ cart_total_paise?: number; } export declare interface CompleteAddress { /** Official India Post DigiPin code for this location (~4m x 4m precision) */ digipin: string; /** Latitude of the confirmed pin location */ lat: number; /** Longitude of the confirmed pin location */ lng: number; /** Auto-filled: State */ state: string; /** Auto-filled: District */ district: string; /** Auto-filled: Postal division */ division: string; /** Auto-filled: Locality / Post Office area */ locality: string; /** Auto-filled: 6-digit pincode */ pincode: string; /** Auto-filled: Delivery status ("Delivery" | "Non Delivery") */ delivery: string; /** Auto-filled: Country */ country: string; /** Manual: Flat / House number */ flatNumber: string; /** Manual: Floor number */ floorNumber: string; /** Manual: Building / Society name */ buildingName: string; /** Manual: Street / Area */ streetName: string; /** Combined formatted address string */ formattedAddress: string; /** Buyer-chosen label for saved-address book (defaults to home) */ label?: AddressLabel; /** Custom label text when `label` is `other` (e.g. "Friend's home") */ labelText?: string; /** Set when the buyer re-selected an existing saved row (skip createAddress). */ addressId?: string; /** Explainable checkout-time address discrepancy risk, when enabled. */ addressRisk?: AddressRiskScore; } export declare interface Coordinates { lat: number; lng: number; } /** * Returns true while the user is typing a DigiPin (compact, dashed, or spaced). * Used to suppress address autocomplete until the code is complete or abandoned. */ export declare function couldBeDigiPinInput(input: string): boolean; /** Save a new address for the authenticated buyer. */ export declare function createAddress(config: CheckoutApiConfig, sessionToken: string, address: SavedAddressPayload): Promise; export declare function createPaymentOrder(config: CheckoutApiConfig, sessionToken: string, amountPaise: number): Promise; export declare interface CreatePaymentOrderResult { razorpay_order_id: string; razorpay_key_id: string; amount_paise: number; currency: string; } /** Carto Positron — default basemap for standard web embeds. */ export declare const DEFAULT_MAP_STYLE_URL = "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json"; /** Soft-delete a saved address. */ export declare function deleteAddress(config: CheckoutApiConfig, sessionToken: string, addressId: string): Promise; /** Detect coarse device class from viewport / user agent (web only). */ export declare function detectDeviceType(userAgent?: string): DeviceType; /** Web checkout platform; native widgets pass platform explicitly. */ export declare function detectPlatform(): CheckoutPlatform; declare interface DeviceContext { deviceType: DeviceType; platform: CheckoutPlatform; userAgent?: string; } /** Device / platform metadata attached to checkout analytics events. */ declare type DeviceType = 'mobile' | 'tablet' | 'desktop'; /** Geographic bounds for India */ export declare const DIGIPIN_BOUNDS: { minLat: number; maxLat: number; minLon: number; maxLon: number; }; declare interface DigiPinCoordinates { latitude: string; longitude: string; } export declare const EmailOtpStep: default_2.FC; export declare interface EmailOtpStepProps { email: string; /** When true, no new email was sent — shopper should use their existing code. */ codeReused?: boolean; onVerified: (sessionToken: string, buyerId: string, sessionId?: string) => void; onBack: () => void; functionBaseUrl: string; merchantId: string; sessionContext?: SessionContextPayload; } export declare const EmailStep: default_2.FC; export declare interface EmailStepProps { /** Called with the normalised (lowercased) email once OTP is ready (sent or reused). */ onOtpSent: (email: string, info?: { reused?: boolean; }) => void; onSkip: () => void; functionBaseUrl: string; merchantId: string; } /** Fetch merchant prepaid nudge copy via Admin API (optional; use props to avoid). */ export declare function fetchPrepaidNudgeConfig(functionBaseUrl: string, adminApiKey: string): Promise; /** Fetch UTM-matched offer banner for the current session. */ export declare function fetchSessionOffer(config: CheckoutApiConfig, sessionToken: string): Promise; /** Canonical display format: XXX-XXX-XXXX */ export declare function formatDigiPin(input: string): string; export declare interface FunnelEventPayload { event_type: string; step?: string; session_token?: string; buyer_id?: string; auth_channel?: string; device_type?: string; platform?: string; user_agent?: string; payment_method?: string; experiment_variant?: string; } /** * Convert lat/lng coordinates to a DigiPin code. * @throws if coordinates are outside India's bounds */ export declare function getDigiPin(lat: number, lon: number): string; export declare function getExternalMapRuntime(): MapRuntime | null; /** * Decode a DigiPin code back to center-point coordinates. * @throws if the DigiPin format is invalid */ export declare function getLatLngFromDigiPin(digiPin: string): DigiPinCoordinates; /** Build device context for web embeds. */ export declare function getWebDeviceContext(): DeviceContext; /** True when at least one UTM field is set. */ export declare function hasUtmParams(utm: UtmParams): boolean; /** True when input is a complete 10-character DigiPin (any common separator style). */ export declare function isCompleteDigiPinInput(input: string): boolean; /** True when normalised input is a non-empty prefix of a DigiPin (still being typed). */ export declare function isPotentialDigiPinInput(input: string): boolean; /** * Validate a DigiPin string (format + character check). */ export declare function isValidDigiPin(digiPin: string): boolean; /** * Check if a lat/lng point is within India's DigiPin coverage area. */ export declare function isWithinIndia(lat: number, lon: number): boolean; /** Fetch all saved addresses for the authenticated buyer. */ export declare function listAddresses(config: CheckoutApiConfig, sessionToken: string): Promise; export declare interface LocationAlternative { pincode: string; name: string; branchType: string; deliveryStatus: string; district: string; state: string; } declare interface LocationLookupData { coordinates: { latitude: number; longitude: number; }; digipin: string; administrative_info: AdministrativeInfo; alternatives?: LocationAlternative[]; confidence: number; source: string; } export declare interface LocationLookupResponse { success: boolean; data: LocationLookupData; error?: string; message?: string; } /** Log a checkout funnel event to the server (fire-and-forget). */ export declare function logFunnelEvent(config: CheckoutApiConfig, payload: FunnelEventPayload, sessionToken?: string): Promise; /** * Returns true if the trimmed input looks like a complete DigiPin code. * Used to skip the API call and resolve offline instead. */ export declare function looksLikeDigiPin(input: string): boolean; /** * Call QuantaRoute's Location Lookup API. * Converts lat/lng → full Indian administrative address + DigiPin. */ export declare function lookupLocation(lat: number, lng: number, apiKey: string, baseUrl?: string): Promise; /** * How the host provides MapLibre GL JS. * - `bundled`: import from `maplibre-gl` (default — Next.js, Vite apps with the peer installed) * - `external`: read from `window.maplibregl` (CDN script loaded before the widget, e.g. Shopify) */ export declare type MapEmbedMode = 'bundled' | 'external'; export { MapLibreMap } export { MapLibreMarker } export { MapMouseEvent } export declare const MapPinSelector: default_2.FC; export declare interface MapPinSelectorProps { onLocationConfirm: (lat: number, lng: number, digipin: string) => void; defaultLat?: number; defaultLng?: number; /** Map height. String on web ('380px'), number on native (380). */ mapHeight?: string | number; theme?: 'light' | 'dark'; /** * URL to an India boundary GeoJSON file (FeatureCollection). * When provided, a thin grey outline of India's border is drawn on the map * to satisfy Indian government map policy requirements. * The file is fetched in parallel with map initialisation — no visible delay. * Example: indiaBoundaryUrl="/geojson/india.geojson" */ indiaBoundaryUrl?: string; /** * Show the search bar above the map (default: true). * Supports two modes automatically: * – Address search → calls /v1/digipin/autocomplete (debounced 400ms) * – DigiPin input → decoded offline, zero API call, instant flyTo * Pass apiKey to enable address search. DigiPin search always works offline. */ enableSearch?: boolean; /** Required when enableSearch is true — used to call the autocomplete API. */ apiKey?: string; /** API base URL for autocomplete. Defaults to https://api.quantaroute.com */ apiBaseUrl?: string; /** * Brand accent colour (hex, e.g. `#7c3aed`). Sets map pin, buttons, focus rings via `--qr-primary` on web. */ brandColor?: string; /** * MapLibre style URL for the basemap. Defaults to Carto Positron. * Use `OPENFREEMAP_POSITRON_STYLE_URL` when Carto credentials are unavailable. */ mapStyle?: string; /** * How MapLibre GL JS is loaded on web. `bundled` imports the peer dependency; * `external` waits for `window.maplibregl` (CDN script loaded by the host). */ embedMode?: MapEmbedMode; } /** Subset of maplibre-gl used by the web MapPinSelector. */ export declare interface MapRuntime { Map: new (options: ConstructorParameters[0]) => MapLibreMap; Marker: new (options?: ConstructorParameters[0]) => MapLibreMarker; AttributionControl?: new (options?: ConstructorParameters>[0]) => AttributionControl; NavigationControl?: new (options?: ConstructorParameters>[0]) => NavigationControl; } /** * Normalise user input to a 10-character DigiPin body (no separators). * Accepts dashed, spaced, or compact forms — e.g. `4P3-J68-637F`, `4P3 J68 637F`, `4P3J68637F`. */ export declare function normalizeDigiPinInput(input: string): string; /** * Notify the server that the buyer has confirmed their delivery address. * Triggers `session.address_completed` webhook on the merchant's configured URL. * Call this once `onComplete` fires in the widget (or from your own checkout page). */ export declare function notifyAddressCompleted(config: CheckoutApiConfig, sessionToken: string, address: { pincode: string; digipin: string; state: string; district: string; locality: string; }): Promise; /** Signal explicit session abandonment (page exit). */ export declare function notifySessionAbandoned(config: CheckoutApiConfig, sessionToken: string, lastStep: string): Promise; /** OpenFreeMap Positron — free, no API key (used when Carto credentials are unavailable). */ export declare const OPENFREEMAP_POSITRON_STYLE_URL = "https://tiles.openfreemap.org/styles/positron"; export declare const OtpStep: default_2.FC; export declare interface OtpStepProps { mobile: string; onVerified: (sessionToken: string, buyerId: string, sessionId?: string) => void; onBack: () => void; functionBaseUrl: string; merchantId: string; sessionContext?: SessionContextPayload; } export declare const PaymentStep: default_2.FC; export declare interface PaymentStepProps { checkoutConfig: CheckoutApiConfig; sessionToken: string; sessionId?: string; amountPaise: number; enableCod?: boolean; codAllowed?: boolean; addressRisk?: AddressRiskScore | null; theme?: 'light' | 'dark'; onComplete: (result: { paymentMethod: string; razorpayOrderId?: string; razorpayPaymentId?: string; }) => void; onBack?: () => void; onEvent?: (type: CheckoutEventType, paymentMethod?: string) => void; orderConfirmationUrl?: string; } export declare const PhoneStep: default_2.FC; export declare interface PhoneStepProps { onOtpSent: (mobile: string) => void; onSkip: () => void; functionBaseUrl: string; merchantId: string; } /** * Whether this pincode has at least one post office with India Post "Delivery" status * (vs "Non Delivery" only — e.g. remote or PO-box-only areas). */ export declare function pincodeHasDeliveryOffice(offices: PincodeOffice[]): boolean; /** One office row from /v1/pincode/validate/:pincode */ export declare interface PincodeOffice { office_name: string; delivery: string | null; district: string | null; state: string | null; circle: string | null; region: string | null; division: string | null; } export declare interface PincodeValidateData { isValid: boolean; pincode: string; count: number; offices: PincodeOffice[]; } /** * C5 prepaid nudge — shown when COD is eligible to encourage prepaid checkout. */ export declare const PrepaidNudge: default_2.FC; export declare interface PrepaidNudgeConfig { prepaid_nudge_copy: string | null; prepaid_nudge_cta_url: string | null; } export declare interface PrepaidNudgeProps { copy: string; ctaUrl?: string; theme?: 'light' | 'dark'; } export declare function recordCodPayment(config: CheckoutApiConfig, sessionToken: string): Promise<{ payment_method: string; }>; /** * Call QuantaRoute's Reverse Geocoding API. * Converts DigiPin → address components from Nominatim/OpenStreetMap. */ export declare function reverseGeocode(digipin: string, apiKey: string, baseUrl?: string): Promise; /** * Response from /v1/digipin/reverse endpoint. */ export declare interface ReverseGeocodeResponse { success: boolean; data: { digipin: string; address: string; coordinates: { latitude: number; longitude: number; }; confidence: number; displayName: string; addressComponents: AddressComponents; }; error?: string; message?: string; } export declare interface SavedAddress { id: string; /** Null for imported addresses pending lazy map verification. */ digipin: string | null; lat: number | null; lng: number | null; state: string; district: string; locality: string; pincode: string; delivery_status: string; flat_number: string; floor_number: string; building_name: string; street_name: string; label: string; /** Custom display text when label is `other` */ label_text: string | null; is_default: boolean; created_at: string; updated_at: string; /** Brand name of the merchant where this address was first saved. Null if unknown. */ saved_at_brand: string | null; } export declare interface SavedAddressPayload { digipin: string; lat: number; lng: number; state?: string; district?: string; locality?: string; pincode?: string; delivery_status?: string; flat_number?: string; floor_number?: string; building_name?: string; street_name?: string; full_address_json?: Record; label?: string; label_text?: string | null; is_default?: boolean; } export declare const SavedAddressStep: default_2.FC; export declare interface SavedAddressStepProps { sessionToken: string; functionBaseUrl: string; merchantId: string; onSelectAddress: (address: SavedAddress) => void; onAddNew: () => void; } export declare function scoreAddressRisk(config: CheckoutApiConfig, sessionToken: string, payload: AddressRiskPayload): Promise; /** Record the buyer's address choice for the current checkout session. */ export declare function selectAddress(config: CheckoutApiConfig, sessionToken: string, addressId: string): Promise; /** Send a 6-digit OTP to the given email via Resend (Edge: `checkout-email-otp`). */ export declare function sendEmailOtp(config: CheckoutApiConfig, email: string): Promise; /** Result from send email OTP — includes whether an existing code was reused (no new email). */ export declare interface SendEmailOtpResult { reused: boolean; } /** Send OTP to the given mobile number. Throws on failure. */ export declare function sendOtp(config: CheckoutApiConfig, mobile: string): Promise; export declare interface ServiceabilityResult { /** Whether a merchant serviceability endpoint was configured and enabled. */ enabled: boolean; /** Whether the merchant endpoint returned a definitive response. */ checked: boolean; /** true/false when checked, null when disabled or failed open. */ serviceable: boolean | null; /** Normalized 6-digit pincode when valid; otherwise the trimmed input. */ pincode: string; /** Buyer-facing merchant message, when supplied by the merchant endpoint. */ message?: string; /** Whether the widget should block address submission when not serviceable. */ block_checkout: boolean; /** Whether the merchant wants the soft India Post info banner as fallback. */ show_india_post_delivery_warning: boolean; /** Present when the endpoint was skipped or failed open. */ reason?: 'not_configured' | 'invalid_pincode' | 'merchant_error' | 'merchant_unreachable' | 'invalid_response'; } /** Device + UTM context sent with OTP verify to enrich checkout sessions. */ export declare interface SessionContextPayload { utm_source?: string; utm_medium?: string; utm_campaign?: string; device_type?: string; platform?: string; user_agent?: string; experiment_variant?: string; } export declare interface SessionOffer { offer_id: string; name: string; banner_copy: string; banner_cta_url: string | null; } /** Set an address as the default. */ export declare function setDefaultAddress(config: CheckoutApiConfig, sessionToken: string, addressId: string): Promise; /** * Compute a DigiPin code from lat/lng entirely offline (no API call). * Returns null if coordinates are outside India's bounds. * * The calculation is pure math (~0.1ms), so no debouncing is needed * even when called on every marker drag event. */ export declare function useDigiPin(lat: number, lng: number): string | null; /** * Hook to imperatively request the user's current GPS position. * Returns a `locate(onSuccess)` callback to trigger the permission prompt. */ export declare function useGeolocation(): { locate: (onSuccess: (lat: number, lng: number) => void) => void; clearError: () => void; loading: boolean; error: string | null; }; /** UTM parameters captured from the storefront URL at checkout start. */ export declare interface UtmParams { utm_source?: string; utm_medium?: string; utm_campaign?: string; } /** * Validate a 6-digit Indian pincode against QuantaRoute's postal database. * Rejects fake codes (e.g. 123456) that are not in India Post records. */ export declare function validatePincode(pincode: string, apiKey: string, baseUrl?: string): Promise; /** * Confirm map pin + form for an imported address missing DigiPin. * Updates buyer_addresses and marks the session address as verified. */ export declare function verifyDigipin(config: CheckoutApiConfig, sessionToken: string, addressId: string, payload: VerifyDigipinPayload): Promise; export declare interface VerifyDigipinPayload { digipin: string; lat: number; lng: number; state?: string; district?: string; locality?: string; pincode?: string; delivery_status?: string; flat_number?: string; floor_number?: string; building_name?: string; street_name?: string; } /** Verify a 6-digit email OTP. Returns a session token on success. */ export declare function verifyEmailOtp(config: CheckoutApiConfig, email: string, code: string, context?: SessionContextPayload): Promise; export declare interface VerifyEmailOtpResult { session_token: string; session_id: string; expires_at: string; buyer_id: string; } /** Verify OTP and return a session token. Throws on invalid OTP. */ export declare function verifyOtp(config: CheckoutApiConfig, mobile: string, otp: string, context?: SessionContextPayload): Promise; export declare interface VerifyOtpResult { session_token: string; session_id: string; expires_at: string; buyer_id: string; } export declare function verifyPayment(config: CheckoutApiConfig, sessionToken: string, params: { razorpay_order_id: string; razorpay_payment_id: string; razorpay_signature: string; payment_method?: string; }): Promise<{ payment_method: string; razorpay_order_id: string; razorpay_payment_id: string; }>; /** * Poll `window.maplibregl` until available or timeout (for async CDN loads). * Returns a cancel function for useEffect cleanup. */ export declare function waitForExternalMapRuntime(onReady: (runtime: MapRuntime) => void, onUnavailable: () => void, waitMs?: number, retryMs?: number): () => void; export { }