# Payments

Source: https://developers.swell.is/frontend-api/payments

### Payment elements

Render third-party payment elements with settings configured by your Swell store. This method dynamically loads third-party libraries such as Stripe, Braintree, and PayPal, in order to standardize the way payment details are captured.

> **Note:** When using a card element, it's necessary to tokenize card details before submitting an order.

### Stripe elements

Render Stripe elements to capture credit card information. You can choose between a unified card element or separate elements (cardNumber, cardExpiry, cardCvc).

> **Warning:** In order to render a card element, you will need to fetch or initialize a cart.

#### Render a Stripe card element

**Render a Stripe card element**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.createElements({
  card: {
    elementId: 'card-element-id', // default: card-element
    options: {
      // options are passed as a direct argument to stripe.js
      style: {
        base: {
          fontWeight: 500,
          fontSize: '16px'
        }
      }
    },
    onChange: event => {
      // optional, called when the Element value changes
    },
    onReady: event => {
      // optional, called when the Element is fully rendered
    },
    onFocus: event => {
      // optional, called when the Element gains focus
    },
    onBlur: event => {
      // optional, called when the Element loses focus
    },
    onEscape: event => {
      // optional, called when the escape key is pressed within an Element
    },
    onClick: event => {
      // optional, called when the Element is clicked
    },
    onSuccess: result => {
      // optional, called on card payment success
    },
    onError: error => {
      // optional, called on card payment error
    }
  }
})
```

#### Rendering other Stripe elements

**Separate card elements**

**Rendering separate Stripe card elements**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.createElements({
  card: {
    separateElements: true, // required for separate elements
    cardNumber: {
      elementId: 'card-number-id', // default: cardNumber-element
      options: {
        // options are passed as a direct argument to stripe.js
        style: {
          base: {
            fontWeight: 500,
            fontSize: '16px'
          }
        }
      }
    },
    cardExpiry: {
      elementId: 'card-expiry-id' // default: cardExpiry-element
    },
    cardCvc: {
      elementId: 'card-cvc-id' // default: cardCvc-element
    }
    // events: onChange, onReady, onSuccess, onError, etc...
  }
})
```

**iDeal**

**Rendering iDeal**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.createElements({
  ideal: {
    elementId: 'ideal-element-id', // default: idealBank-element
    options: {
      style: {
        base: {
          fontWeight: 500,
          fontSize: '16px'
        }
      }
    }
    // events: onChange, onReady, onSuccess, onError, etc...
  }
})
```

> **Note:** See Stripe documentation for more information on  options and customization.

### PayPal button

Render a PayPal checkout button.

**Render a Paypal checkout button**

**swell.js**

```javascript
await $swell.payment.createElements({
  paypal: {
    elementId: 'paypal-button', // default: paypal-button
    style: {
      layout: 'horizontal',
      color: 'blue',
      shape: 'rect',
      label: 'buynow',
      tagline: false,
    },
    onSuccess: () => {
      $swell.cart.submitOrder();
    },
    onError: (error) => {
      console.log('onError', error);
    },
  },
});
```

> **Note:** See PayPal documentation for details on available style parameters.

### PayPal via Braintree

Follow these steps to use Braintree as a gateway for PayPal.

Rendering the button works the same way as the direct PayPal integration above, using the same `paypal` element parameters. The difference is handled for you: when your store's PayPal method is configured to use Braintree, Swell authorizes the Braintree gateway and loads the Braintree SDK before creating the PayPal button.

### Tokenize elements

When using a payment element such as `card` with Stripe, it's necessary to tokenize card details before submitting a payment form. Some payment methods such as PayPal will auto-submit once the user completes authorization via PayPal, but tokenizing is always required for credit card elements.

If successful, `tokenize()` will automatically update the cart with relevant payment details. Otherwise, returns a validation error.

> **Warning:** To charge the card, the cart's capture total must meet Stripe's per-currency minimum (for example $0.50 USD, £0.30 GBP, or ¥50 JPY). Below that minimum, `tokenize()` still succeeds and saves the payment method to the cart, but no payment intent is created.

**Tokenize elements**

**swell.js**

```javascript
import swell from 'swell-js';

swell.init('my-store', 'pk_...');

swell.payment.createElements({
  card: {
    ...
  },
});

const form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();
  showLoading();

  await swell.payment.tokenize({
    card: {
      onError: (err) => {
        // inform the customer there was an error
      },
      onSuccess: () => {
        //finally submit the form
        form.submit();
      }
    }
    // ideal: { onError: (err) => {}, ...}
    // klarna: { onError: (err) => {}, ...}
    // bancontact: { onError: (err) => {}, ...}
  });

  hideLoading();
});
```

> **Note:** Some payment methods such as `ideal`, `klarna`, `bancontact` automatically redirect the user to the payment page to authorize the payment.

### Handling redirect actions

After the customer redirects back to your site after authorizing the payment or entering the payment information, it is necessary to configure the cart billing and then submit the order.

#### Stripe

**iDeal**

**Stripe iDeal redirect actions**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

if (redirectParams.redirect_status !== 'succeeded') {
  // inform the customer there was an error
  return
}

await swell.cart.update({
  billing: {
    method: 'ideal',
    intent: {
      stripe: { id: '<payment_intent_id>' }
    },
    ideal: {
      token: '<payment_method_id>'
    }
  }
})

await swell.cart.submitOrder()
```

**Klarna**

**Stripe Klarna redirect actions**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

if (redirectParams.redirect_status !== 'succeeded') {
  // inform the customer there was an error
  return
}

await swell.cart.update({
  billing: {
    method: 'klarna',
    intent: {
      stripe: { id: '<payment_intent_id>' }
    },
    klarna: {
      token: '<payment_method_id>'
    }
  }
})

await swell.cart.submitOrder()
```

**Bancontact**

**Stripe Bancontact redirect actions**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

if (redirectParams.redirect_status !== 'succeeded') {
  // inform the customer there was an error
  return
}

await swell.cart.update({
  billing: {
    method: 'bancontact',
    bancontact: {
      token: '<setup_intent_id>' // Stripe SetupIntent id, e.g. seti_...
    }
  }
})

await swell.cart.submitOrder()
```

### Saferpay

**Card**

**Saferpay card reditect actions**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

if (redirectParams.status !== 'succeeded') {
  // inform the customer there was an error
  return
}

const intent = await swell.payment.updateIntent({
  gateway: 'saferpay',
  intent: { token: '<saferpay_transaction_token>' }
})

if (intent.error) {
  // inform the customer there was an error
  return
}

const {
  RegistrationResult: {
    Alias: { Id: token }
  },
  PaymentMeans: {
    Card: { ExpMonth: exp_month, ExpYear: exp_year, MaskedNumber },
    Brand: { Name: brand }
  }
} = intent

const params = await swell.cart.update({
  billing: {
    card: {
      token,
      exp_month,
      exp_year,
      brand,
      last4: MaskedNumber.substring(MaskedNumber.length - 4),
      gateway: 'saferpay'
    }
  }
})

await swell.cart.submitOrder()
```

### Direct credit card tokenization

If a payment element isn't available for your credit card processor, you can tokenize credit card information directly.

#### Create a card token

Returns an object representing the card token. Pass the token ID to a cart's `billing.card.token` field to designate this card as the payment method.

**Create a card token**

**swell.js**

```javascript
const response = await swell.card.createToken({
  number: '4242 4242 4242 4242',
  exp_month: 1,
  exp_year: 2099,
  cvc: 321,
  // Note: some payment gateways may require a Swell `account_id` and `billing` for card verification (Braintree)
  account_id: '5c15505200c7d14d851e510f',
  billing: {
    address1: '1 Main Dr.',
    zip: 90210
    // Other standard billing fields optional
  }
})
```

### Success and error response for token creation

**Success and error responses for card tokenization**

**swell.js** `Successful token response`

```javascript
{
  token: 't_z71b3g34fc3',
  brand: 'Visa',
  last4: '4242',
  exp_month: 1,
  exp_year: 2029,
  cvc_check: 'pass', // fail, checked
  zip_check: 'pass', // fail, checked
  address_check: 'pass', // fail, checked
}
```

**swell.js** `Error token response`

```javascript
{
  errors: {
    gateway: {
      code: 'TOKEN_ERROR',
      message: 'Declined',
      params: {
        cvc_check: 'fail',
        zip_check: 'pass',
        address_check: 'unchecked',
      },
    },
  },
}
```

### Validate card details

#### Card number

Returns `true` if the card number is valid, otherwise `false`.

**Validate card number**

**swell.js**

```javascript
swell.card.validateNumber('4242 4242 4242 4242') // => true
swell.card.validateNumber('1111') // => false
```

#### Card expiry

Returns `true` if the card expiration date is valid, otherwise `false`.

Pass the month and the year as two separate arguments. A single combined string such as `'12/2030'` always returns `false`. Numbers and strings are both accepted, the month must be 1 to 12, and the year must be written in full, since two-digit years are not expanded to a century.

A card is treated as valid through the end of its expiry month. An expiry more than 50 years in the future is rejected, so a distant placeholder year such as 2099 returns `false`.

**Validate card expiry**

**swell.js**

```javascript
swell.card.validateExpiry(12, 2030)     // => true
swell.card.validateExpiry('06', '2030') // => true (strings are accepted)
swell.card.validateExpiry(9, 1999)      // => false (already expired)
swell.card.validateExpiry('9', '99')    // => false (two-digit years are not expanded)
swell.card.validateExpiry(13, 2030)     // => false (month must be 1-12)
swell.card.validateExpiry('12/2030')    // => false (pass month and year separately)
```

#### CVC code

Returns `true` if the card CVC code is valid, otherwise `false`.

**Validate CVC code**

**swell.js**

```javascript
swell.card.validateCVC('321') // => true
swell.card.validateCVC('1') // => false
```

### Add to cart

After generating a card token, update the cart billing details and it will be handled according to payment settings when the order is submitted.

> **Note:** When using a payment element instead of direct tokenization, the cart will be automatically updated.

**Add card token to cart**

**swell.js**

```javascript
const response = await swell.card.createToken({
  number: '4242 4242 4242 4242',
  exp_month: 1,
  exp_year: 2099,
  cvc: 321,
  // Note: some payment gateways may require a Swell `account_id` and `billing` for card verification (Braintree)
  account_id: '5c15505200c7d14d851e510f',
  billing: {
    address1: '1 Main Dr.',
    zip: 90210
    // Other standard billing fields optional
  }
})

await swell.cart.update({
  billing: {
    card: response
  }
})
```

### Manual payment integrations

If you need more flexibility in the integration process, you can use the following guides to achieve this.

#### Stripe + Klarna, iDEAL & Bancontact integration

This guide describes how to integrate Klarna, iDEAL and Bancontact with a custom checkout flow, using Stripe PaymentIntents (Klarna and iDEAL) and SetupIntents (Bancontact).

Start by connecting a Stripe account to Swell (Settings > Payments); open "Advanced options" under Stripe settings and check `Enable Klarna` / `Enable iDEAL` / `Enable Bancontact`.

### Using Stripe.js

Include Stripe.js on the payment page of your site. This can be done in two ways:

**1. Load directly from https://js.stripe.com.**

**Load Stripe.js directly**

```javascript
<script src="https://js.stripe.com/v3/"></script>
```

**2. Load and use Stripe.js as a model**

This is done through Stripe's provided npm package.

#### Initializing Stripe.js

Once loaded, initialize it with a publishable key.

If loaded from a script:

**Initializing Stripe.js from script**

```javascript
// Client side
const stripe = Stripe('pk_test_...')
```

If loaded from a JS module:

**Initializing Stripe.js from a JS module**

```javascript
// Client side
import { loadStripe } from '@stripe/stripe-js'
const stripe = await loadStripe('pk_test_...')
```

#### Install Stripe server-side library

This library will be used to access the Stripe API and create payment intents. To install the npm package:

**Install Stripe npm package**

```- Select a language -
npm i --save stripe
```

Initialize Stripe with a secret key:

**Initialize Stripe with a secret key**

**swell.js**

```javascript
// Server side
const stripe = require('stripe')('sk_test_...')
```

### iDEAL integration

Creating iDEAL elements using Stripe elements:

**Creating iDEAL elements with Stripe elements**

```javascript
// Client side
const stripe = Stripe('pk_test_...');

const elements = stripe.elements();
const ideal = elements.create('idealBank', options); // 'options' is an optional object
ideal.mount('#stripe-ideal');
```

There are several options for customization.

Important: in the above example, the element will be mounted in an HTML tag with the ID `stripe-ideal`. Make sure it exists on the page.

#### Create a payment method

​Once a customer enters all required information, it's necessary to create a payment method:

**Creating a payment method**

```javascript
// Client side
const stripe = Stripe('pk_test_...');

await stripe.createPaymentMethod({
  type: 'ideal',
  ideal: idealElement,
  billing_details: {
    name: 'Jenny Rosen',
  },
});
```

​ This call returns one of:

- `result.paymentMethod`: a PaymentMethod that was created successfully.
- `result.error`: a server or client-side validation error. Refer to the Stripe API reference for all possible errors.

#### Create a payment intent

To create a payment intent, pass the payment method created earlier, along with `amount` and `return_url` to which the customer will be redirected after authorizing payment:

**Create a payment intent**

```javascript
// Server side
const stripe = require('stripe')('sk_test_...');

await stripe.paymentIntents.create({
  payment_method: '<payment_method_id>',
  amount: '<amount in cents>',
  currency: 'eur',
  payment_method_types: 'ideal',
  confirmation_method: 'manual',
  confirm: true,
  return_url: '<return_url>',
});
```

This call returns one of:

- `result.paymentIntent`: a PaymentIntent that was created successfully.
- `result.error`: a server or client-side validation error. Refer to the Stripe API reference for all possible errors.

#### Payment authorization

​ If a payment intent was created successfully, authorize the payment:

**Payment authorization**

```javascript
// Client side
const stripe = Stripe('pk_test_...');

await stripe.handleCardAction(paymentIntent.client_secret);
```

​ This method will redirect the customer to authorize payment. After authorization, the customer will be redirected back to your site at the address specified when creating the payment intent (`return_url`).

#### Capture payment and create an order

​When redirecting to your site, the URL query will contain parameters with information about the payment: ​

- `redirect_status`: Payment authorization status (`succeeded` or `failed`)
- `payment_intent`: Unique identifier for the `PaymentIntent`
- `payment_intent_client_secret`: A client secret related to the `PaymentIntent object`

Finally, add the relevant payment details to a Swell cart or order:

**Add relevant payment details to Swell cart or oder**

**swell.js**

```javascript
const billing = {
  method: 'ideal',
  ideal: {
    token: '<payment_method_id>'
  },
  intent: {
    stripe: {
      id: '<payment_intent_id>'
    }
  }
}

// Using the Swell JS library (public key)
await swell.cart.update({ billing })

// Using the Swell Node.js library (secret key, server-side only)
await swellNode.put('/carts/<id>', { billing })
```

### Klarna integration

To make a Klarna payment, create a `PaymentIntent` with Klarna as the payment method type, then confirm it on the client. Klarna does not require using Stripe elements.

**Klarna integration with Stripe**

`Server`

```javascript
// Create a PaymentIntent for Klarna using your Stripe secret key.
const intent = await stripe.paymentIntents.create({
  payment_method_types: ['klarna'],
  amount: '<amount>',
  currency: '<iso currency code>',
  capture_method: 'manual',
});

// Send intent.client_secret to the client.
```

`Client`

```javascript
const stripe = Stripe('pk_test_...');

// Confirming the intent redirects the customer to Klarna.
await stripe.confirmKlarnaPayment(clientSecret, {
  payment_method: {
    billing_details: {
      name: '<name>',
      email: '<email>',
      address: {
        country: '<Two letter ISO country code>',
      },
    },
  },
  return_url: '<return_url>',
});
```

> **Note:** See Stripe's Klarna documentation for more details on creating and confirming a Klarna payment intent.

#### Payment authorization

Confirming the payment intent redirects the customer to Klarna to authorize the payment. After authorization, the customer is redirected back to your site at the address passed as `return_url`.

#### Capture payment

​When redirecting to your site, the URL query will contain parameters with information about the payment: ​

- `redirect_status`: Authorization status (`succeeded`, `canceled` or `failed`)
- `payment_intent`: Unique identifier for the `PaymentIntent`
- `payment_intent_client_secret`: A client secret related to the `PaymentIntent object`

Finally, add the relevant payment details to a Swell cart or order:

**Add Klarna payment details to Swell cart or order**

**swell.js**

```javascript
const billing = {
  method: 'klarna',
  klarna: {
    token: '<payment_method_id>'
  },
  intent: {
    stripe: {
      id: '<payment_intent_id>'
    }
  }
}

// Using the Swell JS library (public key)
await swell.cart.update({ billing })

// Using the Swell Node.js library (secret key, server-side only)
await swellNode.put('/carts/<id>', { billing })
```

#### Direct Klarna integration

Redirect the customer to the Klarna payment page:

**Direct user to Klarna payment page**

**swell.js**

```javascript
import swell from 'swell-js';

swell.init('my-store', 'pk_...');

const form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();
  showLoading();

  await swell.payment.tokenize({
    klarna: {
      onError: (err) => {
        // inform the customer there was an error
      },
    }
  });

  hideLoading();
});
```

Once the user enters the payment details and confirms payment, they will be redirected to the checkout page. Next, update the cart billing by calling the following:

**Update cart billing**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.handleRedirect({
  klarna: { 
    onError: (err) => {
      // inform the customer there was an error
    }, 
    onSuccess: () => {
      swell.cart.submitOrder()
    }
  }
});
```

> **Tip:** Make sure the payment page and cart billing localizations match. This is because Klarna sets the localization on the payment page based on the country in the billing.

### Bancontact integration

Redirect the customer to the Bancontact payment page:

**Direct user to Bancontact payment page**

**swell.js**

```javascript
import swell from 'swell-js';

swell.init('my-store', 'pk_...');

const form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();
  showLoading();

  await swell.payment.tokenize({
    bancontact: {
      onError: (err) => {
        // inform the customer there was an error
      },
    }
  });

  hideLoading();
});
```

Once the user enters the payment details and confirms payment, they will be redirected to the checkout page. Next, update the cart billing by calling the following:

**Update cart billing**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.handleRedirect({
  bancontact: { 
    onError: (err) => {
      // inform the customer there was an error
    }, 
    onSuccess: () => {
      swell.cart.submitOrder()
    }
  }
});
```

### Saferpay integration

Start by enabling the payment method and linking a Saferpay account to your Swell store under **Settings > Payments** in the dashboard.

#### PaymentPage Initialize

To create a transaction, it is necessary to initialize the Saferpay payment page. This can be done in the following ways:

**Tokenization method**

**Saferpay tokenization method**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

await swell.payment.tokenize({
  card: {
    intent: {
      // optional
      Payment: {
        Amount: {
          Value: '<amount>',
          CurrencyCode: '<currency>'
        },
        Description: '<description>'
      },
      PaymentMethods: ['<payment methods list>'],
      ReturnUrls: {
        Success: '<success_return_url>',
        Fail: '<fail_return_url>',
        Abort: '<abort_return_url>'
      }
    },
    onError: err => {
      // inform the customer there was an error
    }
  }
})
```

As a result of calling `tokenize()`, the Saferpay payment page will be initialized, the transaction token will be set in the cart billing (`billing.intent.saferpay`), and then the user will be automatically redirected to enter payment data.

**Intent creation method**

**Saferpay intent creation method**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

await swell.payment
  .createIntent({
    gateway: 'saferpay',
    intent: {
      Payment: {
        Amount: {
          Value: '<amount>',
          CurrencyCode: '<currency>'
        },
        Description: '<description>'
      },
      PaymentMethods: ['<payment methods list>'],
      ReturnUrls: {
        Success: '<success_return_url>',
        Fail: '<fail_return_url>',
        Abort: '<abort_return_url>'
      }
    }
  })
  .then(intent => {
    // save 'intent.token' for further processing of the transaction
    // redirect the user to 'intent.return_url' to enter payment information
  })
  .catch(err => {
    // inform the customer there was an error
  })
```

> **Note:** See Saferpay PaymentPage Initialize docs for more details on configuring a payment page.

You can independently initialize the Saferpay payment page using Saferpay API, and then redirect the user to this page to enter payment information.

#### Payment processing

After entering payment information on the payment page, the customer will be redirected back to your site at the address specified when initializing the payment page. See Handling redirect actions section for payment processing.

### Paysafecard integration

Start by enabling the payment method and linking a Paysafecard account to your Swell store under **Settings > Payments** in the dashboard.

**Direct user to Paysafecard payment page**

**swell.js**

```javascript
import swell from 'swell-js';

swell.init('my-store', 'pk_...');

const form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();
  showLoading();

  await swell.payment.tokenize({
    paysafecard: {
      onError: (err) => {
        // inform the customer there was an error
      },
    }
  });

  hideLoading();
});
```

Once the user enters the payment details and confirms payment, they will be redirected to the checkout page. Next, update the cart billing by calling the following:

**Update cart billing**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.handleRedirect({
  paysafecard: { 
    onError: (err) => {
      // inform the customer there was an error
    }, 
    onSuccess: () => {
      swell.cart.submitOrder()
    }
  }
});
```

### Quickpay integration

Start by enabling the payment method in the **Credit cards** section and linking a Quickpay account to your Swell store under **Settings > Payments** in the dashboard.

**Direct the user to QuickPay payment page**

**swell.js**

```javascript
import swell from 'swell-js';

swell.init('my-store', 'pk_...');

const form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
  event.preventDefault();
  showLoading();

  await swell.payment.tokenize({
    card: {
      onError: (err) => {
        // inform the customer there was an error
      },
    }
  });

  hideLoading();
});
```

Once the user enters the payment details and confirms payment, they will be redirected to the checkout page. Next, update the cart billing by calling the following:

**Update cart billing**

**swell.js**

```javascript
import swell from 'swell-js'

swell.init('my-store', 'pk_...')

swell.payment.handleRedirect({
  card: { 
    onError: (err) => {
      // inform the customer there was an error
    }, 
    onSuccess: () => {
      swell.cart.submitOrder()
    }
  }
});
```

### Apple Pay

You will need to enable Apple Pay with Stripe, Braintree, Authorize.net, or ConvesioPay. See this resource to [learn how to enable Apple Pay](https://www.swell.is/help/store-setup/alternative-payment-methods/apple-pay) within your Swell account.

**Apple Pay with Swell.js**

**swell.js**

```javascript
swell.payment.createElements({
	apple: {
		elementId: '<dom-element-id>', // Default: applepay-button
		style: {
			theme: '<button-theme>', // Default: dark (Stripe), black (Braintree, Authorize.net, ConvesioPay)
			type: '<button-type>', // Default: default (Stripe), plain (Braintree, Authorize.net, ConvesioPay)
			height: '<button-height>' // Default: 40px
		},
		require: {
			// Requested data in Apple Pay modal
			shipping: true, // Default: false
			name: true, // Default: false
			email: true, // Default: false
			phone: true, // Default: false
		},
		classes: {
			base: '<button-container-class>', // Optional, the base class applied to the container
			// The following classes only work with Stripe Apple Pay
			complete: '<button-complete-class>', // Optional, the class name to apply when the Element is complete
			empty: '<button-empty-class>', // Optional, the class name to apply when the Element is empty
			focus: '<button-focus-class>', // Optional, the class name to apply when the Element is focused
			invalid: '<button-invalid-class>', // Optional, the class name to apply when the Element is invalid
			webkitAutofill: '<button-webkit-autofill-class>', // Optional, the class name to apply when the Element has its value autofilled by the browser (only on Chrome and Safari)
		},
		managementUrl: '<subscription-management-url>', // Authorize.net and ConvesioPay only. Required when the cart contains a subscription item
		onSuccess: () => {}, // Optional, called on submit Apple Pay modal
		onError: (error) => {}, // Optional, called on payment error
	}
});
```

See the following documentation for more information on button options:

- Stripe Apple Pay button options.
- Braintree Apple Pay button options.
- Authorize.net and ConvesioPay Apple Pay button options.

#### Subscriptions

When the cart contains a subscription item, Apple Pay with Authorize.net or ConvesioPay adds the subscription's recurring payment details to the payment sheet. These include a description of the plan, the recurring amount and billing interval, and the trial period when the plan has trial days. This requires Swell.js 5.8.2 or later.

Set `managementUrl` to the URL of a page where the customer can manage the subscription and its payment method. Apple Pay requires this URL for recurring payments.

**Render an Apple Pay button for a subscription cart**

**swell.js**

```javascript
swell.payment.createElements({
	apple: {
		elementId: 'applepay-button',
		managementUrl: 'https://example.com/account/subscriptions',
		onSuccess: () => {},
		onError: (error) => {},
	}
});
```

Apple Pay supports one subscription per payment. If the cart contains more than one subscription item, the payment sheet shows the first one. The recurring amount shown is the item price multiplied by its quantity and doesn't include discounts, taxes, or shipping.

With Stripe and Braintree, the payment sheet doesn't show recurring payment details and `managementUrl` is ignored.

### Google Pay

You will need to enable Google Pay with Stripe, Braintree, Authorize.net, or ConvesioPay. See this resource to [learn how to enable Google Pay](https://www.swell.is/help/store-setup/alternative-payment-methods/google-pay) within your Swell account.

**Google Pay with Swell.js**

**swell.js**

```javascript
swell.payment.createElements({
	google: {
		elementId: '<dom-element-id>', // Default: googlepay-button
		locale: '<button-locale>', // Braintree only. Default: en
		style: {
			color: '<button-color>', // Braintree: black (default) or white. Stripe: default is dark
			type: '<button-type>', // Braintree: buy (default). Stripe: buy, donate or default (default: default)
			sizeMode: '<button-size-mode>', // Braintree only. Default: fill
			height: '<button-height>', // Stripe only. Default: 45px
		},
		require: {
			// Requested data in Google Pay modal
			shipping: true, // Default: false
			email: true, // Default: false
			phone: true, // Default: false
		},
		classes: {
			base: '<button-container-class>', // Optional, the base class applied to the container
		},
		onSuccess: () => {}, // Optional, called on submit Google Pay modal
		onError: (error) => {}, // Optional, called on payment error
	}
});
```

See Google documentation for more information on button options.
