Customizing Stripe payment form for Craft Commerce 2 Where does one start with matching the style of the Stripe payment form to the rest of the site?

Using Stripe for Craft Commerce Plug-In

 {{ plan.getGateway().getPaymentFormHtml({})|raw }}


This enables the form with Card Holder info and credit card details.
The following code allows the customisation of the fields using Stripe Elements. This code will replace the payment form with gateway.getPaymentFormHtml({}).

The thing to note here is this is provided unsupported as it is custom code and does not use the payment form template or javascript file that is in the Commerce Stripe plugin. This also means that it will not benefit from any updates to the plugin that change those files.

{% set cart = craft.commerce.carts.cart %}
{% set gateway = cart.gateway %}
{% set scenario = 'payment' %}
{% set billingAddress = cart.billingAddress ?? null %}

&lt;form method="POST" id="payment-form"&gt;
  &lt;input type="hidden" name="action" value="commerce/payments/pay"/&gt;
  {{ redirectInput('/shop/customer/order?number='~cart.number) }}
  &lt;input type="hidden" name="cancelUrl" value="{{ '/shop/checkout/payment'|hash }}"/&gt;
  &lt;input type="hidden" name="orderEmail" value="{{ cart.email }}"/&gt;
  &lt;input type="hidden" name="gatewayId" value="{{ cart.gatewayId }}"/&gt;
  {{ csrfInput() }}

  &lt;div class="stripe-payment-intents-form"
    {% if clientSecret is defined %}data-client-secret="{{clientSecret}}" {% endif %}
    {% if scenario is defined %}data-scenario="{{scenario}}" {% endif %}
  &gt;
    &lt;div&gt;
      &lt;input type="text"
             name='firstName'
             maxlength="70"
             placeholder="{{'First Name'|t('commerce')}}"
             autocomplete="false"
             class="card-holder-first-name{{(paymentForm is defined and paymentForm.getErrors('firstName') ? ' error')}}"
             value="{{paymentForm is defined and paymentForm ? paymentForm.firstName : ''}}"
      &gt;
      &lt;input type="text"
             name="lastName"
             maxlength=70",
             placeholder="{{'Last Name'|t('commerce')}}"
             autocomplete="false"
             class="card-holder-last-name{{ (paymentForm is defined and paymentForm.getErrors('lastName') ? ' error') }}"
             value="{{paymentForm is defined and paymentForm ? paymentForm.lastName : ''}}"
      &gt;
    &lt;/div&gt;

    {% set errors = paymentForm is defined and paymentForm ? paymentForm.getErrors() : [] %}
    {% if errors|length %}
      &lt;ul class="errors"&gt;
        {% for error in errors %}
          &lt;li&gt;{{ error|join('&lt;br&gt;')|raw }}&lt;/li&gt;
        {% endfor %}
      &lt;/ul&gt;
    {% endif %}


    &lt;div id="card-number"&gt;&lt;/div&gt;
    &lt;div id="card-expiry"&gt;&lt;/div&gt;
    &lt;div id="card-cvc"&gt;&lt;/div&gt;

    &lt;div id="card-errors" role="alert"&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;input type="submit"&gt;
&lt;/form&gt;

{% do view.registerJsFile('https://js.stripe.com/v3/') %}
{% js %}
// Create a Stripe client.
var stripe = Stripe('{{ gateway.publishableKey ?? '' }}');

  // Create an instance of Elements.
  var elements = stripe.elements();

  // Custom styling can be passed to options when creating an Element.
  // (Note that this demo uses a wider set of styles than the guide below.)
  var style = {
    base: {
      color: '#000000',
      fontSize: '16px',
      '::placeholder': {
        color: '#CCCCCC'
      }
    },
    invalid: {
      color: '#fa755a',
      iconColor: '#fa755a'
    }
  };

  var classes = {
    base: 'StripeElement',
    complete: 'StripeElement--complete',
    empty: 'StripeElement--empty',
    focus: 'StripeElement--focus',
    invalid: 'StripeElement--invalid',
    webkitAutoFill: 'StripeElement--webkit-autofill'
  };

  var card = elements.create('cardNumber', {
    style: style,
    classes: classes
  });
  card.mount('#card-number');

  var expiry = elements.create('cardExpiry', {
    style: style,
    classes: classes
  });
  expiry.mount('#card-expiry');

  var cvc = elements.create('cardCvc', {
    style: style,
    classes: classes
  });
  cvc.mount('#card-cvc');

  // Handle real-time validation errors from the card Element.
  function cardErrors(event) {
    var displayError = document.getElementById('card-errors');
    if (event.error) {
      displayError.textContent = event.error.message;
    } else {
      displayError.textContent = '';
    }
  };

  card.addEventListener('change', cardErrors);
  expiry.addEventListener('change', cardErrors);
  cvc.addEventListener('change', cardErrors);

  // Handle form submission.
  var form = document.getElementById('payment-form');
  form.addEventListener('submit', function(event) {
    event.preventDefault();
    var firstName = document.querySelector('.card-holder-first-name');
    var lastName = document.querySelector('.card-holder-last-name');

    var paymentData = {
      billing_details: {
        name: firstName.value + ' ' + lastName.value,
        email: '{{ cart.email }}',
        address: {
          line1: '{{ billingAddress.address1 ?? '' }}',
          city: '{{ billingAddress.city ?? '' }}',
          state: '{{ billingAddress.state ?? '' }}',
          postal_code: '{{ billingAddress.zipCode ?? '' }}',
          country: '{{ billingAddress.country.iso ?? '' }}'
        }
      }
    };

    stripe.createPaymentMethod('card', card, paymentData).then(function(result) {
      if (result.error) {
      // Inform the user if there was an error.
      var errorElement = document.getElementById('card-errors');
        errorElement.textContent = result.error.message;
      } else {
          var form = document.getElementById('payment-form');
          var hiddenInput = document.createElement('input');
          hiddenInput.setAttribute('type', 'hidden');
          hiddenInput.setAttribute('name', 'paymentMethodId');
          hiddenInput.setAttribute('value', result.paymentMethod.id);
          form.appendChild(hiddenInput);

          // Submit the form
          form.submit();
      }
    });
  });

{% endjs %}