> ## Documentation Index
> Fetch the complete documentation index at: https://docs.withacclaim.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Embedded Elements

> Acclaim.js is a comprehensive payment processing SDK that handles credit cards, digital wallets, and alternative payment methods with built-in PCI compliance and 3D Secure support.

## Quick Start

### Installation

```html theme={null}
<!-- CDN (Recommended) -->
<script src="https://cdn.withacclaim.com/v1/acclaim.js"></script>
```

### Basic Setup

```javascript theme={null}
const acclaim = new Acclaim({
    publishableKey: 'pk_live_your_api_key_here',
});
```

## Core Concepts

### Requests vs Elements

Acclaim uses two main concepts:

* **Requests**: Server-side objects that define what you want to do (payment or setup)
* **Elements**: Client-side UI components that collect payment information

### Payment Request

1. Create a **Payment Request** for immediate processing
2. Create an **Element** to collect payment info
3. Mount the element to your page
4. Submit the element when the user clicks the pay button

### Setup Request

1. Create a **Setup Request** to save payment methods
2. Create an **Element** to collect payment info
3. Mount the element to your page
4. Submit the element when the user clicks the submit button

## Payment Processing

### Creating Payment Requests

See the [Payment Requests](/api/payment-requests/create-a-payment-request) documentation for more information on how to create a payment request.

### Creating and Mounting Elements

```javascript theme={null}
// Create payment element
const element = await acclaim.createElement(paymentRequest.session_identifier, {
    theme: 'clean',       // 'clean', 'material', 'minimal'
    locale: 'en',          // Language code
    appearance: {
        primaryColor: '#007bff',
        borderRadius: '8px',
        fontFamily: 'Inter, sans-serif'
    }
});

// Mount to DOM
await element.mount('#payment-container');
```

### Element Options

| Parameter    | Type   | Description                                        |
| ------------ | ------ | -------------------------------------------------- |
| `theme`      | string | Visual theme: `'clean'`, `'material'`, `'minimal'` |
| `locale`     | string | Language code (e.g., `'en'`, `'fr'`, `'es'`)       |
| `appearance` | object | Custom styling options                             |

### Appearance Customization

```javascript theme={null}
const element = await acclaim.createElement(sessionId, {
    appearance: {
        primaryColor: '#6366f1',        // Brand color
        backgroundColor: '#ffffff',     // Background color
        textColor: '#1f2937',          // Text color
        borderColor: '#d1d5db',        // Border color
        borderRadius: '8px',           // Border radius
        fontFamily: 'Inter, sans-serif', // Font family
        fontSize: '16px',              // Base font size
        padding: '12px',               // Input padding
        focusColor: '#3b82f6'          // Focus highlight color
    }
});
```

### Handling Payment Completion

```javascript theme={null}
try {
    // Submit the payment
    const result = await element.submit();

    if (result.status === 'succeeded') {
        // Payment successful
        window.location.href = '/success';
    } else if (result.status === 'requires_action') {
        // 3D Secure or additional authentication required
        console.log('Additional authentication in progress...');
    }
} catch (error) {
    console.error(error.message);
}
```

### Complete Payment Example

```javascript theme={null}
async function setupPayment() {
    // Initialize Acclaim
    const acclaim = new Acclaim({
        publishableKey: 'pk_test_your_api_key',
    });

    // Create and mount element
    const element = await acclaim.createElement(paymentRequest.session_identifier);
    await element.mount('#payment-container');

    // Handle the submission of the form the Payment Element is embedded within
    const theForm = document.getElementById('payment-form');
    theForm.addEventListener('submit', async (e) => {
        e.preventDefault();

        // Hide any previous error messages
        hideError();

        const submitButton = document.querySelector('#submit-button');
        submitButton.disabled = true;
        submitButton.textContent = 'Processing...';

        try {
            const result = await element.submit();

            if (result.status === 'succeeded') {
                window.location.href = '/success';
            } else {
                throw new Error(result.error?.message || 'Payment failed');
            }
        } catch (error) {
            showError(error.message);
            submitButton.disabled = false;
            submitButton.textContent = 'Pay Now';
        }

        return false;
    });
}

function showError(message) {
    const errorElement = document.querySelector('#error-message');
    errorElement.textContent = message;
    errorElement.style.display = 'block';
}

function hideError() {
    const errorElement = document.querySelector('#error-message');
    errorElement.style.display = 'none';
}
```

## Setup (Saving Payment Methods)

### Creating a Setup Request

See the [Setup Requests](/api/setup-requests/create-a-setup-request) documentation for more information on how to create a setup request.

### Creating and Mounting Elements

```javascript theme={null}
// Create payment element
const element = await acclaim.createElement(setupRequest.session_identifier, {
    theme: 'clean',       // 'clean', 'material', 'minimal'
    locale: 'en',          // Language code
    appearance: {
        primaryColor: '#007bff',
        borderRadius: '8px',
        fontFamily: 'Inter, sans-serif'
    }
});

// Mount to DOM
await element.mount('#save-card-container');
```

### Handling Setup

```javascript theme={null}
try {
    // Save the payment method
    const result = await setupRequest.submit();

    if (result.status === 'succeeded') {
        // Payment successful
        window.location.href = '/success';
    } else if (result.status === 'requires_action') {
        // 3D Secure or additional authentication required
        console.log('Additional authentication in progress...');
    }
} catch (error) {
    console.error(error.message);
}
```

## 3D Secure Authentication

Acclaim automatically handles 3D Secure authentication when required. The process is transparent to your integration.

### Manual 3DS Handling

```javascript theme={null}
// If you need manual control over 3DS
try {
    const result = await paymentRequest.submit();
    
    if (result.status === 'requires_action') {
        // Handle 3DS authentication
        const authResult = await acclaim.handle3DSecure();
        
        if (authResult.status === 'succeeded') {
            // Authentication successful
            console.log('Payment completed after 3DS');
        }
    }
} catch (error) {
    console.error('3DS authentication failed:', error);
}
```

## Digital Wallets

### Apple Pay

Apple Pay is automatically detected on supported devices and browsers. No additional setup required.

**Requirements:**

* Safari browser
* macOS with Touch ID or iPhone/iPad with Face ID/Touch ID
* Valid Apple Pay merchant certificate (handled by Acclaim)

### Google Pay

Google Pay is automatically detected when the Google Pay API is available.

**Requirements:**

* Supported browser (Chrome, Edge, etc.)
* Valid Google Pay merchant configuration

### PayPal

In order to use the PayPal payment method, you must supply a `return_url` and `cancel_url` in your payment request.

## Event Handling

### Element Events

```javascript theme={null}
element.on('ready', () => {
    console.log('Element is ready');
});

element.on('change', (state) => {
    console.log('Element state changed:', state);
    // Update submit button based on validation
    document.querySelector('#submit-btn').disabled = !state.complete;
});

element.on('success', (result) => {
    console.log('Payment element completed:', result);
});

element.on('error', (error) => {
    console.error('Element error:', error);
});
```

### Available Events

| Event     | Description                            | Payload                        |
| --------- | -------------------------------------- | ------------------------------ |
| `ready`   | Element is mounted and ready           | -                              |
| `change`  | Form validation state changed          | `{ complete, empty, invalid }` |
| `success` | Payment element completed successfully | `{ id, ... }`                  |
| `error`   | An error occurred                      | `{ code, message, ... }`       |

## Error Handling

### Common Error Types

```javascript theme={null}
element.on('error', (error) => {
    switch (error.code) {
        case 'validation_error':
            // Invalid card number, expired card, etc.
            showFieldError(error.field, error.message);
            break;
            
        case 'card_declined':
            // Card was declined by issuer
            showError('Your card was declined. Please try a different payment method.');
            break;
            
        case 'network_error':
            // Network connectivity issues
            showError('Network error. Please check your connection and try again.');
            break;
            
        case 'api_error':
            // Server-side error
            showError('Something went wrong. Please try again.');
            break;
            
        default:
            showError(error.message);
    }
});
```

### Error Object Structure

```javascript theme={null}
{
    code: 'validation_error',
    message: 'Your card number is invalid.',
    details: [
        {
            message: 'Your card number is invalid.',
            field: 'cardNumber',
            code: 'invalid_number'
        }
    ]
}
```

## Styling and Themes

### Built-in Themes

```javascript theme={null}
// Default theme
const element = await acclaim.createElement(sessionId, {
    theme: 'clean'
});

// Material theme
const element = await acclaim.createElement(sessionId, {
    theme: 'material'
});

// Minimal theme
const element = await acclaim.createElement(sessionId, {
    theme: 'minimal'
});
```

### Custom Styling

```javascript theme={null}
const element = await acclaim.createElement(sessionId, {
    appearance: {
        // Colors
        primaryColor: '#6366f1',
        backgroundColor: '#ffffff',
        textColor: '#1f2937',
        placeholderColor: '#9ca3af',
        borderColor: '#d1d5db',
        focusColor: '#3b82f6',
        errorColor: '#ef4444',
        
        // Typography
        fontFamily: 'Inter, -apple-system, sans-serif',
        fontSize: '16px',
        fontWeight: '400',
        
        // Layout
        borderRadius: '8px',
        borderWidth: '1px',
        padding: '12px 16px',
        
        // States
        ':hover': {
            borderColor: '#9ca3af'
        },
        ':focus': {
            borderColor: '#3b82f6',
            boxShadow: '0 0 0 3px rgba(59, 130, 246, 0.1)'
        },
        '.invalid': {
            borderColor: '#ef4444'
        }
    }
});
```

## Testing

### Test Cards

Use these test card numbers in sandbox mode:

| Card Type        | Number             | CVC          | Expiry          |
| ---------------- | ------------------ | ------------ | --------------- |
| Visa             | `4242424242424242` | Any 3 digits | Any future date |
| Visa (debit)     | `4000056655665556` | Any 3 digits | Any future date |
| Mastercard       | `5555555555554444` | Any 3 digits | Any future date |
| American Express | `378282246310005`  | Any 4 digits | Any future date |
| Declined         | `4000000000000002` | Any 3 digits | Any future date |
| 3D Secure        | `4000000000003220` | Any 3 digits | Any future date |

### Test Environment

```javascript theme={null}
const acclaim = new Acclaim({
    publishableKey: 'pk_test_your_test_key',
});
```

### Webhook Testing

Use tools like ngrok to test webhooks locally:

```bash theme={null}
# Install ngrok
npm install -g ngrok

# Expose local server
ngrok http 3000

# Use the HTTPS URL for webhook endpoint
```

## API Reference

### Acclaim Constructor

```javascript theme={null}
new Acclaim(options)
```

**Options:**

* `publishableKey` (string, required): Your Acclaim publishable API key

### Methods

#### `createPaymentElement(sessionId, container)`

Creates a payment element for the given request.

**Returns:** `Promise<PaymentElement>`

### PaymentElement Methods

#### `mount(container)`

Mount the element to a DOM container.

**Parameters:**

* `container` (string|Element): CSS selector or DOM element

**Returns:** `Promise<PaymentElement>`

#### `unmount()`

Remove the element from the DOM.

#### `on(event, callback)`

Listen for element events.

**Parameters:**

* `event` (string): Event name
* `callback` (function): Event handler

#### `update(options)`

Update element appearance or configuration.

**Parameters:**

* `options` (object): New options to apply

#### `submit()`

Confirm and process the payment or setup.

**Returns:** `Promise<PaymentResult>`

#### `handle3DSecure(options)`

Manually handle 3D Secure authentication.

**Returns:** `Promise<AuthenticationResult>`
