# Creating custom payment component

The integration gives you a raw version of the PaymentStripeProvider.vue component. You can use it as a base and customize it for your needs.

<template>
  <div class="payment-container">
    <slot name="loader" v-if="isLoadingStripeSdk">
      <PaymentStripeLoader />
    </slot>
    <div>
      <form id="payment-form" @submit.prevent="handleSubmit">
        <transition name="fade">
          <slot name="payment-error" :errors="errors">
            <div class="payment-error-container" v-if="errors">
              {{ errors }}
            </div>
          </slot>
          <slot name="payment-succeed">
            <div class="payment-succeed-container" v-if="succeed">
              Payment succeed
            </div>
          </slot>
        </transition>
        <div v-if="!retryImpossible">
          <div id="payment-element">
            <!--Stripe.js injects the Payment Element-->
          </div>
          <button id="submit" :disabled="loading">
            <div class="spinner hidden" id="spinner"></div>
            <span id="button-text">Pay now</span>
          </button>
        </div>
      </form>
    </div>
  </div>
</template>

<script>
import PaymentStripeLoader from '@vsf-enterprise/stripe-epcc/src/components/PaymentStripeLoader.vue';
import { onMounted, ref } from '@vue/composition-api';
import { 
  useStripeUi
} from '@vsf-enterprise/stripe-epcc';

export default {
  name: 'PaymentStripeProvider',
  components: {
    PaymentStripeLoader
  },
  setup () {
    const isLoadingStripeSdk = ref(true);

    const { 
      mountStripeUi,
      requires3ds,
      initPayment,
      handle3ds,
      setSucceed,

      createStripePaymentMethod,
      createEpccPayment,
      invokeStripe3dsAuth,
      updateEpccPayment,

      loading,
      retryImpossible,
      errors,
      succeed
    } = useStripeUi();

    const handleSubmit = async () => {
      const epccPayment = await initPayment(createStripePaymentMethod, createEpccPayment);
      if (!epccPayment) {
        return;
      }

      if (requires3ds(epccPayment)) {
        return await handle3ds(epccPayment, invokeStripe3dsAuth, updateEpccPayment);
      } else {
        return setSucceed();
      }
    };

    onMounted(async () => {
      await mountStripeUi();
      isLoadingStripeSdk.value = false;
    });

    return {
      isLoadingStripeSdk,
      errors,

      handleSubmit,
      loading,
      retryImpossible,
      succeed
    };
  }
};

</script>

<style lang="scss" scoped>
  .fade-enter-active, .fade-leave-active {
    transition: opacity .7s;
  }
  .fade-enter, .fade-leave-to {
    opacity: 0;
  }

  .payment-container {
    margin-top: 40px;
  }

  .payment-error-container {
    background: #d12727;
    border-radius: 5px;
    color: #fff;
    padding: 10px;
    margin-bottom: 10px;
  }

  .payment-succeed-container {
    background: #0f8500;
    border-radius: 5px;
    color: #fff;
    padding: 10px;
    margin-bottom: 10px;
  }
</style>