📖 Hosted Fields SDK


Secure SDK for embedding payment input fields (card number, expiry date, CVV, etc.) inside iframes. It is designed to ensure PCI‑compliance by isolating sensitive data from the merchant’s site.

🛠 Usage

  1. Include the SDK on your checkout page (currently available via CDN only):

       <!-- Sandbox URL -->
       <script src="https://engine-sandbox.pay.tech/hf/sdk/lib/umd/index.js"></script>
    
       <!-- Production URL -->
       <script src="https://engine.pay.tech/hf/sdk/lib/umd/index.js"></script>
    

  2. Initialize the SDK with your payment_id:

       const sdk = HostedFieldsSDK({ paymentId: 'payment_id_required', theme: 'dark' });
    
    Config options:
    • paymentId (string, required) — your payment session ID.
    • theme ('light' | 'dark', optional) — initial color theme for all hosted fields. Defaults to 'light'

  3. To be able to mount the card fields on your page you need to prepare containers for that matter.

            <form class="flex gap-4 flex-col" autocomplete="on">
                <div id="cardNumber" class="w-full"></div> // card number field container
                <div class="flex gap-4 w-full">
                    <div id="expiryDate" class="w-full"></div> // expiry date field container
                    <div id="cvv" class="w-full"></div> // card security code (cvv) field container
                </div>
                <div id="cardholderName" class="w-full"></div> // cardholder name field container
                <button type="button" class="submit-button" onclick="submitPayment()">Submit</button>
            </form>
    

  4. Mount the payment fields on you page:

       sdk.onReady(() => {
         sdk.mountField('#cardNumber', {
           fieldType: 'cardNumber',
           label: 'Card number',
           fieldStyles: { variant: 'outlined' }
         });
    
         sdk.mountField('#expiryDate', {
           fieldType: 'expiryDate',
           label: 'Expiry date'
         });
    
         sdk.mountField('#cvv', {
           fieldType: 'cvv',
           label: 'Card security code'
         });
    
          sdk.mountField('#cardholderName', {
           fieldType: 'cardholderName',
           label: 'Cardholder name'
         });
       });
       sdk.onError((err) => console.error('SDK Error:', err));
       sdk.onFieldValid((info) => console.log('Field valid:', info));
    

  5. Start the SDK:

       sdk.init();
    

  6. Tokenize on form submission:

         async function submitPayment(e) {
                   e?.preventDefault();
    
                   try {
                       const result = await sdk.handleSubmit();
    
                       console.log(result);
                       if(result?.redirectUrl) window.location.replace(result.redirectUrl);
    
                       document.getElementById('output').textContent = JSON.stringify(result, null, 2);
                   } catch (error) {
                       console.error('--',error);
                   }
               }
    

🔑 Available Methods

  1. new HostedFieldsSDK(config)

    Creates a new SDK instance.

    Parameters:
    • payment_id (string, required) -- paymentId you received after creating the payment.
    • Payment method must be paymentMethod: BASIC_CARD,
    • payment state state: CHECKOUT
    • and transaction must have valid amount amount: 10.
  2. .init()

    Initializes the SDK and validates your payment id. Must be called before mounting fields.

  3. .onError(callback)

    Registers a callback to handle initialization or runtime errors.

    • Callback receives: an error object with a message.
  4. .onFieldValid(callback)

    Registers a callback that is triggered when a field becomes valid (e.g., after the user corrects an invalid input).

    • Callback receives: an object with fieldType — the type of the field that became valid ('cardNumber', 'expiryDate', 'cvv', or 'cardholderName').
  5. .mountField(containerSelector, options)

    Injects a secure payment input field (inside an iframe) into the specified container on your page.

    Parameters:
    • containerSelector (string, required) - CSS selector for a container div in your HTML.
    • options (object, required):
      • fieldType- the type of payment field to render. Available:
        • cardNumber
        • expiryDate
        • cvv
        • cardholderName
      • label (string, optional) — the label text displayed above the input.
      • fieldStyles (object, optional) — customize appearance:
        • variantstandard or outlined
        • labelPositionfloating or above
        • fieldWrapper — custom CSS styles for the field wrapper
        • inputBase — custom CSS styles for the input
        • invalidInputBase — styles applied when the input is invalid
        • labelBase — custom CSS styles for the label
        • invalidLabelBase — styles applied when input is invalid
        • dark (object, optional) — override styles applied only in dark theme. Accepts the same keys: fieldWrapper, inputBase, labelBase, invalidInputBase, invalidLabelBase. When the theme is 'dark', these styles are layered on top of the base styles. If no dark overrides are provided, the base custom styles remain active in both themes.

    Example with dark overrides:

    sdk.mountField('#cardNumber', {
        fieldType: 'cardNumber',
        label: 'Card Number',
        fieldStyles: {
            inputBase: {
                backgroundColor: '#fff',
                border: '1px solid #D0D5DD',
                color: '#1D2939',
            },
            labelBase: {
                color: '#667085',
                backgroundColor: '#fff',
            },
            dark: {
                inputBase: {
                    backgroundColor: 'transparent',
                    border: '1px solid #475467',
                    color: '#F5F5F6',
                },
                labelBase: {
                    color: '#98A2B3',
                    backgroundColor: '#1D2939',
                },
            },
        },
    });
  6. .setTheme(theme)

    Dynamically switches the color theme for all mounted hosted fields.

    Parameters:
    • theme ('light' | 'dark', required) — the theme to apply.

    Example:

    sdk.setTheme('dark');

🖼 Full example form

<div class="card">
    <div class="card-header">
        <h3>Basic card</h3>
        <button id="themeToggle" onclick="toggleTheme()">Toggle theme</button>
    </div>
    <form class="card-body" autocomplete="on">
        <div id="cardNumber"></div>
        <div class="field-row">
            <div id="expiryDate"></div>
            <div id="cvv"></div>
        </div>
        <div id="cardholderName"></div>
        <button type="button" onclick="submitPayment()">Submit payment</button>
    </form>
</div>

<!-- Load the Hosted Fields SDK -->
<script src="https://your-domain.com/hf/sdk/lib/umd/index.js"></script>
<script>
    const sdk = HostedFieldsSDK({ paymentId: '<payment_id>', theme: 'dark' });

    sdk.onReady(() => {
        sdk.mountField('#cardNumber', {
            fieldType: 'cardNumber',
            label: 'Card Number',
            fieldStyles: {
                variant: 'outlined',
                labelPosition: 'floating'
            }
        });
        sdk.mountField('#expiryDate', {
            fieldType: 'expiryDate',
            label: 'Expiry Date',
            fieldStyles: {
                variant: 'outlined',
                labelPosition: 'floating'
            }
        });
        sdk.mountField('#cvv', {
            fieldType: 'cvv',
            label: 'Card Security Code',
            fieldStyles: {
                variant: 'standard',
                labelPosition: 'floating'
            }
        });
        sdk.mountField('#cardholderName', {
            fieldType: 'cardholderName',
            label: 'Cardholder Name',
            fieldStyles: {
                variant: 'outlined',
                labelPosition: 'floating'
            }
        });
    });

    // Toggle between light and dark themes
    let isDark = true;

    function toggleTheme() {
        isDark = !isDark;
        sdk.setTheme(isDark ? 'dark' : 'light');
    }

    sdk.onError((err) => console.error("SDK Error:", err));
    sdk.onFieldValid((info) => console.log("Field valid:", info));

    sdk.init();

    async function submitPayment(e) {
        e?.preventDefault();

        try {
            const result = await sdk.handleSubmit();

            console.log(result);
            if (result?.redirectUrl) window.location.replace(result.redirectUrl);
        } catch (error) {
            console.error('SDK error on submit:', error);
        }
    }
</script>