diff --git a/resources/js/clients/payment_methods/authorize-checkout-card.js b/resources/js/clients/payment_methods/authorize-checkout-card.js
new file mode 100644
index 000000000..4fdcc926c
--- /dev/null
+++ b/resources/js/clients/payment_methods/authorize-checkout-card.js
@@ -0,0 +1,51 @@
+/**
+ * Invoice Ninja (https://invoiceninja.com).
+ *
+ * @link https://github.com/invoiceninja/invoiceninja source repository
+ *
+ * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
+ *
+ * @license https://opensource.org/licenses/AAL
+ */
+
+class CheckoutCreditCardAuthorization {
+ constructor() {
+ this.button = document.querySelector('#pay-button');
+ }
+
+ init() {
+ this.frames = Frames.init(
+ document.querySelector('meta[name=public-key]').content
+ );
+ }
+
+ handle() {
+ this.init();
+
+ Frames.addEventHandler(
+ Frames.Events.CARD_VALIDATION_CHANGED,
+ (event) => {
+ this.button.disabled = !Frames.isCardValid();
+ }
+ );
+
+ Frames.addEventHandler(Frames.Events.CARD_TOKENIZED, (event) => {
+ document.querySelector(
+ 'input[name="gateway_response"]'
+ ).value = JSON.stringify(event);
+
+ document.getElementById('server_response').submit();
+ });
+
+ document
+ .querySelector('#authorization-form')
+ .addEventListener('submit', (event) => {
+ this.button.disabled = true;
+
+ event.preventDefault();
+ Frames.submitCard();
+ });
+ }
+}
+
+new CheckoutCreditCardAuthorization().handle();
diff --git a/resources/views/portal/ninja2020/gateways/checkout/credit_card/authorize.blade.php b/resources/views/portal/ninja2020/gateways/checkout/credit_card/authorize.blade.php
index 327ab1fba..eb0f26e4d 100644
--- a/resources/views/portal/ninja2020/gateways/checkout/credit_card/authorize.blade.php
+++ b/resources/views/portal/ninja2020/gateways/checkout/credit_card/authorize.blade.php
@@ -40,44 +40,5 @@
@endsection
@section('gateway_footer')
-
+
@endsection
diff --git a/webpack.mix.js b/webpack.mix.js
index 391a15100..34b60abfe 100644
--- a/webpack.mix.js
+++ b/webpack.mix.js
@@ -114,6 +114,10 @@ mix.js("resources/js/app.js", "public/js")
"resources/js/clients/payments/stripe-sepa.js",
"public/js/clients/payments/stripe-sepa.js"
)
+ .js(
+ "resources/js/clients/payment_methods/authorize-checkout-card.js",
+ "public/js/clients/payment_methods/authorize-checkout-card.js"
+ )
mix.copyDirectory('node_modules/card-js/card-js.min.css', 'public/css/card-js.min.css');