/**
* OnePayment - Drop-in Payment Element (Web Component)
* @element one-payment
*/
import { LitElement } from 'lit';
import type { Adapters, SDKConfig, State, PaymentMethodId, AppearanceOptions } from '@one-payments/core';
/**
* Custom events emitted by this component
*/
export interface OnePaymentEvents {
'payment-success': CustomEvent<{
paymentIntentId: string;
}>;
'payment-error': CustomEvent<{
error: string;
}>;
'state-change': CustomEvent<{
state: State;
}>;
}
/**
* Main payment component - framework-agnostic web component with EXACT original design
*
* OnePayment is a drop-in payment element that handles the complete payment flow including
* card payments, PayNow QR codes, 3D Secure authentication, and real-time status updates.
*
* @element one-payment
*
* @example
* ```typescript
* import '@one-payments/web-components';
* import { PaymentConfig } from '@one-payments/core';
* import { createWebAdapters } from '@one-payments/adapters';
*
* const config = new PaymentConfig({
* apiKey: 'pk_test_...',
* secretKey: 'sk_test_...',
* environment: 'demo'
* });
*
*
* ```
*
* @fires payment-success - Emitted when payment succeeds, contains paymentIntentId
* @fires payment-error - Emitted when payment fails, contains error message
* @fires state-change - Emitted on every state change, contains full state object
*
* @public
* @since 1.0.0
*/
export declare class OnePayment extends LitElement {
/**
* SDK configuration object
*
* **RECOMMENDED**: Use the `PaymentConfig` class to create this configuration:
* ```typescript
* import { PaymentConfig } from '@one-payments/core';
*
* const config = new PaymentConfig({
* apiKey: 'pk_test_...',
* secretKey: 'sk_test_...',
* environment: 'demo'
* });
* ```
*
* The config can also be a plain object:
* ```typescript
* const config = {
* apiKey: 'pk_test_...',
* secretKey: 'sk_test_...',
* environment: 'demo'
* };
* ```
*
* **Required fields:**
* - `apiKey` - Your One Payments public API key
* - `secretKey` - Your One Payments secret key
* - `environment` - 'prod', 'demo', or 'dev'
*
* **Optional fields:**
* - `apiBaseUrl` - Custom API endpoint (defaults based on environment)
* - `locale` - Language/locale code (e.g., 'en-US', 'zh-CN')
*
* @required
* @type {SDKConfig | PaymentConfig}
* @public
*/
config: SDKConfig;
/**
* Platform-specific adapters for HTTP and storage operations
*
* Adapters abstract platform differences (web, React Native, Node.js) so the
* core SDK can work across all environments.
*
* **For web/browser environments:**
* ```typescript
* import { createWebAdapters } from '@one-payments/adapters';
*
*
* ```
*
* **For React Native:**
* ```typescript
* import { createReactNativeAdapters } from '@one-payments/adapters';
*
*
* ```
*
* @required
* @type {Adapters}
* @public
*/
adapters: Adapters;
/**
* Payment amount in smallest currency unit (cents/pence)
*
* **IMPORTANT**: Always provide amounts in the smallest currency unit:
* - For USD/SGD/EUR: cents (e.g., 10000 = $100.00)
* - For JPY/KRW: yen/won (e.g., 1000 = ¥1000)
*
* Examples:
* - $10.00 USD = 1000 cents
* - €25.50 EUR = 2550 cents
* - ¥5000 JPY = 5000 yen
*
* The component will automatically format the display based on currency.
*
* @required
* @type {number}
* @public
*/
amount: number;
/**
* Three-letter ISO 4217 currency code
*
* Specifies the currency for the payment transaction. Must be a valid
* ISO 4217 currency code (e.g., 'USD', 'EUR', 'SGD', 'GBP').
*
* **Important currency-specific behavior:**
* - PayNow is ONLY available for SGD (Singapore Dollars)
* - Other payment methods work with most major currencies
*
* Common currency codes:
* - USD - US Dollar
* - EUR - Euro
* - GBP - British Pound
* - SGD - Singapore Dollar
* - JPY - Japanese Yen
* - AUD - Australian Dollar
* - CAD - Canadian Dollar
*
* @required
* @type {string}
* @public
*/
currency: string;
/**
* Unique order/transaction identifier
*
* A unique identifier for this payment transaction from your system.
* This ID is used to:
* - Track the payment in your backend
* - Prevent duplicate payments
* - Reference the transaction in webhooks and API calls
*
* **Best practices:**
* - Use a unique, non-sequential ID (e.g., UUID)
* - Store this ID in your database before initiating payment
* - Use the same format consistently across your system
*
* Example formats:
* - `"order_abc123xyz"`
* - `"txn_1234567890"`
* - `"550e8400-e29b-41d4-a716-446655440000"` (UUID)
*
* @required
* @type {string}
* @public
*/
orderId: string;
/**
* Customer's first name (REQUIRED)
*
* The payer's first name or given name. This field is required for all
* payment methods and is used for:
* - Payment receipt generation
* - Transaction records
* - Fraud prevention and verification
*
* **Validation:**
* - Cannot be empty or whitespace-only
* - Must be provided before payment submission
*
* @required
* @type {string}
* @public
*/
firstName: string;
/**
* Customer's last name (REQUIRED)
*
* The payer's last name or family name. This field is required for all
* payment methods and is used for:
* - Payment receipt generation
* - Transaction records
* - Fraud prevention and verification
*
* **Validation:**
* - Cannot be empty or whitespace-only
* - Must be provided before payment submission
*
* @required
* @type {string}
* @public
*/
lastName: string;
/**
* Customer's email address (REQUIRED)
*
* The payer's email address. This field is required for all payment methods
* and is used for:
* - Sending payment receipts and confirmations
* - Transaction notifications
* - Customer communication
* - Fraud prevention
*
* **Validation:**
* - Cannot be empty or whitespace-only
* - Must be provided before payment submission
* - Should be a valid email format (validated by your application)
*
* @required
* @type {string}
* @public
*/
email: string;
/**
* Optional array of payment method IDs to exclude from display
*
* Use this to hide specific payment methods that you don't want to offer
* for this transaction. The component will only show methods that are:
* 1. Available from the API
* 2. Not in this exclusion list
* 3. Compatible with the transaction currency
*
* Available payment method IDs:
* - `PAYMENT_METHODS.CARD` - Credit/debit cards
* - `PAYMENT_METHODS.PAYNOW` - PayNow QR code (SGD only)
*
* Example:
* ```typescript
* import { PAYMENT_METHODS } from '@one-payments/core';
*
* // Hide PayNow, only show cards
*
* ```
*
* @optional
* @type {PaymentMethodId[]}
* @default undefined
* @public
*/
excludePaymentMethods?: PaymentMethodId[];
/**
* Optional custom width for the payment component
*
* Sets the width of the entire payment element. Can be any valid CSS width value.
*
* **Examples:**
* - `"500px"` - Fixed pixel width
* - `"100%"` - Full width of container
* - `"50vw"` - 50% of viewport width
* - `"auto"` - Automatic width based on content
*
* **Default:** `"100%"` (full width of container)
*
* **Note:** The component has a minimum width of 320px for proper mobile display.
*
* @optional
* @type {string}
* @default "100%"
* @public
*/
width?: string;
/**
* Optional maximum width constraint for the payment component
*
* Sets the maximum width the payment element can grow to. Useful for
* preventing the component from becoming too wide on large screens.
*
* **Examples:**
* - `"600px"` - Max width of 600 pixels
* - `"90%"` - Max 90% of container width
* - `"1200px"` - Max width for large displays
*
* **Default:** `none` (no maximum width constraint)
*
* **Tip:** Combine with `width="100%"` for responsive layouts that don't
* exceed a certain size:
* ```typescript
*
* ```
*
* @optional
* @type {string}
* @default "none"
* @public
*/
maxWidth?: string;
/**
* Appearance customization options for theming and styling
*
* Allows customization of:
* - `theme`: 'light' (default), 'dark', or 'auto' (follows system preference)
* - `variables`: CSS custom property overrides for colors, fonts, spacing
*
* @example
* ```html
*
*
*
*
*
* ```
*
* @optional
* @type {AppearanceOptions}
* @public
*/
appearance?: AppearanceOptions;
private currentState;
private selectedMethod;
private cardFormData;
private formErrors;
private paymentData;
private feesExpanded;
private isInitializing;
private cardBrand;
private paymentLocked;
private show3DSModal;
private showQRModal;
private nextActionUrl;
private qrCode;
private qrCodeDataUrl;
private qrAutoResumeTimer;
private qrPollingInProgress;
private availableBanks;
private selectedBank;
private banksLoading;
private bankSearchQuery;
private phoneInputValue;
private phoneInputError;
private selectedCountry;
private sdk;
private isInitialized;
private cardNumberCleave;
private expiryCleave;
private leaveEventsCounter;
private previousState;
/**
* Check if all required props are present and valid.
* Used to determine if SDK initialization can proceed.
*
* This enables CDN/script-tag usage where props are set AFTER
* the element is already in the DOM.
*/
private hasAllRequiredProps;
/**
* Check if a payment method requires phone number
* Only these 5 methods require phone number: Boost, ShopeePay, Konbini, PayEasy, Atome
*/
private requiresPhoneNumber;
/**
* Check if phone number is available for payment
* Returns true if the user has entered a valid number in the input field
*/
private hasPhoneNumber;
/**
* Check if the pay button should be disabled for a method
*/
private isPayButtonDisabled;
/**
* Map of appearance variable names to CSS custom property names
*/
private readonly cssVariableMap;
/**
* Media query listener for auto theme
*/
private themeMediaQuery;
private themeMediaQueryHandler;
/**
* Apply appearance settings to the component
*
* This method:
* 1. Sets the data-theme attribute based on theme option
* 2. Applies CSS custom properties from variables
*
* @private
*/
private applyAppearance;
/**
* Apply CSS custom properties from variables object
*/
private applyCssVariables;
/**
* Setup listener for system theme changes (for theme: 'auto')
*/
private setupThemeMediaQueryListener;
/**
* Clean up theme media query listener
*/
private cleanupThemeMediaQueryListener;
static styles: import("lit").CSSResult;
connectedCallback(): void;
firstUpdated(): void;
/**
* Called when any reactive property changes.
*
* This enables CDN/script-tag usage pattern where:
* 1. Element is added to DOM with only HTML attributes
* 2. Later, JavaScript sets config, adapters, and other props
*
* Without this, firstUpdated() runs before props are set,
* causing permanent skeleton state.
*/
updated(changedProperties: Map): void;
disconnectedCallback(): void;
private handle3DSPostMessage;
private setupCleave;
private destroyCleave;
/**
* Get filtered payment methods
* Applies filtering:
* 1. API availability (from available-methods endpoint with currency filtering)
* 2. User exclusions (excludePaymentMethods prop)
*
* Note: Currency validation is now handled server-side by the available-methods API
*/
private getFilteredPaymentMethods;
private initializeSDK;
private handleMethodSelect;
private handleQRScanned;
private handle3DSComplete;
private handleInputChange;
private luhnCheck;
private validateExpiry;
private validateCardForm;
private handleCardPayment;
private handlePayNowPayment;
private handlePromptPayPayment;
private handleDuitNowPayment;
private handleGoPayPayment;
private handleBoostPayment;
private handleShopeePayPayment;
private handleAtomPayment;
private handleDanaPayment;
private handleTngPayment;
private handleAlipayCNPayment;
private handleAlipayHKPayment;
private handleGCashPayment;
private handleKonbiniPayment;
private handlePayEasyPayment;
private handleGrabPaySGPayment;
private handleFPXPayment;
private handleWeChatPayPayment;
/**
* Fetch available banks for a payment method
*/
private fetchBanks;
/**
* Handle bank selection
*/
private handleBankSelect;
/**
* Get filtered banks based on search query
*/
private getFilteredBanks;
/**
* Minimum phone number length (digits only)
*/
private readonly MIN_PHONE_LENGTH;
/**
* Japan-only payment methods - phone must start with +81
* These methods require the country selector to be locked to Japan
*/
private readonly JAPAN_ONLY_PHONE_METHODS;
/**
* Country options for phone number selection
* Uses ISO 3166-1 alpha-2 country codes (uppercase for libphonenumber-js)
*/
private readonly COUNTRY_OPTIONS;
/**
* Check if payment method requires Japan-only phone
*/
private isJapanOnlyPhoneMethod;
/**
* Get the full phone number with country code in international format
* For display: "+81 90 1234 5678"
* For API: depends on payment method
*/
private getFormattedPhoneWithCountryCode;
/**
* Get effective phone number for API submission
* - Japan methods (konbini, payeasy): Convert +81 to local format (0XXXXXXXXXX)
* - Other methods: Keep international format (+XX XXXX XXXX)
*/
private getEffectivePhoneNumber;
/**
* Format phone number for Japan (convert +81 to 0)
* The Airwallex API for Japanese payment methods expects local format:
* - Input: "+81 90 1234 5678" (international format)
* - Output: "09012345678" (local format, no spaces)
*/
private formatPhoneForJapan;
/**
* Format names for Pay-Easy (max 9 chars combined)
* Pay-easy has a unique requirement: combined first name + last name must be maximum 9 characters
*/
private formatNamesForPayEasy;
/**
* Format names for API submission (default: uppercase conversion)
* All payment methods require names to be UPPERCASE
*/
private formatNamesUppercase;
/**
* Validate phone number input
* Rules:
* 1. Required - phone number cannot be empty
* 2. Min 8 digits - must have at least 8 digits
* 3. Japan prefix - for konbini/payeasy, must validate as Japan number
* 4. Format - must be valid phone format
*/
private validatePhoneInput;
/**
* Handle phone input change with auto-formatting
* Uses libphonenumber-js AsYouType formatter to format as user types
*/
private handlePhoneInputChange;
/**
* Handle country change
*/
private handleCountryChange;
/**
* Get the formatted pay amount for buttons (net amount including fees)
*/
private getPayButtonAmount;
private getTransactionData;
private renderTransactionDetailsSkeleton;
private renderPaymentMethodsSkeleton;
private renderSkeletons;
private renderTransactionDetails;
private renderCardForm;
private renderPayNowContent;
private renderPromptPayContent;
private renderDuitNowContent;
private renderGoPayContent;
/**
* Render phone number input for payment methods that require it
* Matches react-phone-input-2 behavior:
* - Country dropdown with flags and dial codes
* - Auto-formatting based on country
* - Japan-only lock for konbini/payeasy
*/
private renderPhoneInput;
private renderBoostContent;
private renderShopeePayContent;
private renderAtomContent;
private renderDanaContent;
private renderTngContent;
private renderAlipayCNContent;
private renderAlipayHKContent;
private renderGCashContent;
private renderKonbiniContent;
private renderPayEasyContent;
private renderGrabPaySGContent;
private renderFPXContent;
private renderWeChatPayContent;
private render3DSModal;
private renderStatusBlock;
render(): import("lit-html").TemplateResult<1>;
}
declare global {
interface HTMLElementTagNameMap {
'one-payment': OnePayment;
}
}
//# sourceMappingURL=one-payment.d.ts.map