diff --git a/app/Models/Gateway.php b/app/Models/Gateway.php index 2ee165a9b3b0..49b36fe1da92 100644 --- a/app/Models/Gateway.php +++ b/app/Models/Gateway.php @@ -144,7 +144,7 @@ class Gateway extends StaticModel GatewayType::DIRECT_DEBIT => ['refund' => false, 'token_billing' => false, 'webhooks' => ['payment_intent.processing','payment_intent.succeeded','payment_intent.partially_funded']], GatewayType::ALIPAY => ['refund' => false, 'token_billing' => false], GatewayType::APPLE_PAY => ['refund' => false, 'token_billing' => false], - GatewayType::BACS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], + GatewayType::BACS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded', 'mandate.updated']], GatewayType::SOFORT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], GatewayType::KLARNA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], GatewayType::SEPA => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], @@ -191,7 +191,7 @@ class Gateway extends StaticModel GatewayType::EPS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], GatewayType::BANCONTACT => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], GatewayType::BECS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], - GatewayType::BACS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], + GatewayType::BACS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded', 'mandate.updated']], GatewayType::IDEAL => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], GatewayType::ACSS => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded', 'payment_intent.succeeded']], GatewayType::FPX => ['refund' => true, 'token_billing' => true, 'webhooks' => ['source.chargeable', 'charge.succeeded']], diff --git a/app/PaymentDrivers/Stripe/BACS.php b/app/PaymentDrivers/Stripe/BACS.php index e772bd6e13f9..b7fde1e47b30 100644 --- a/app/PaymentDrivers/Stripe/BACS.php +++ b/app/PaymentDrivers/Stripe/BACS.php @@ -82,7 +82,9 @@ class BACS { $this->stripe->init(); $invoice_numbers = collect($this->stripe->payment_hash->invoices())->pluck('invoice_number')->implode(','); - $description = ctrans('texts.stripe_payment_text', ['invoicenumber' => $invoice_numbers, 'amount' => Number::formatMoney($request->amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]); + // $description = ctrans('texts.stripe_payment_text', ['invoicenumber' => $invoice_numbers, 'amount' => Number::formatMoney($request->amount, $this->stripe->client), 'client' => $this->stripe->client->present()->name()]); + $description = $this->stripe->getDescription(false); + $payment_intent_data = [ 'amount' => $this->stripe->convertToStripeAmount($request->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()), 'currency' => $this->stripe->client->getCurrencyCode(), @@ -130,14 +132,14 @@ class BACS $payment = $this->stripe->createPayment($data, Payment::STATUS_PENDING); - SystemLogger::dispatch( + (new SystemLogger( ['response' => $payment_intent, 'data' => $data], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->stripe->client, $this->stripe->client->company, - ); + ))->handle(); return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]); @@ -152,14 +154,14 @@ class BACS 'data' => $this->stripe->payment_hash->data, ]; - SystemLogger::dispatch( + (new SystemLogger( $message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_STRIPE, $this->stripe->client, $this->stripe->client->company, - ); + ))->handle(); throw new PaymentFailed('Failed to process the payment.', 500); } diff --git a/app/PaymentDrivers/StripePaymentDriver.php b/app/PaymentDrivers/StripePaymentDriver.php index 9038b366e868..ee187536c11b 100644 --- a/app/PaymentDrivers/StripePaymentDriver.php +++ b/app/PaymentDrivers/StripePaymentDriver.php @@ -35,12 +35,10 @@ use App\PaymentDrivers\Stripe\EPS; use App\PaymentDrivers\Stripe\FPX; use App\PaymentDrivers\Stripe\ACSS; use App\PaymentDrivers\Stripe\Alipay; -use App\PaymentDrivers\Stripe\ApplePay; use App\PaymentDrivers\Stripe\BACS; use App\PaymentDrivers\Stripe\BECS; use App\PaymentDrivers\Stripe\SEPA; use App\PaymentDrivers\Stripe\iDeal; -use App\PaymentDrivers\Stripe\Alipay; use App\PaymentDrivers\Stripe\Charge; use App\PaymentDrivers\Stripe\Klarna; use App\PaymentDrivers\Stripe\SOFORT; @@ -244,7 +242,6 @@ class StripePaymentDriver extends BaseDriver && $this->client->currency() && in_array($this->client->currency()->code, ['GBP']) && isset($this->client->country) - && in_array($this->client->company->country()->getID(), ['826']) && in_array($this->client->country->iso_3166_3, ['GBR'])) { $types[] = GatewayType::BACS; } @@ -259,7 +256,6 @@ class StripePaymentDriver extends BaseDriver && $this->client->currency() && in_array($this->client->currency()->code, ['EUR', 'DKK', 'GBP', 'NOK', 'SEK', 'AUD', 'NZD', 'CAD', 'PLN', 'CHF', 'USD']) && isset($this->client->country) - && in_array($this->client->company->country()->id, ['840']) && in_array($this->client->country->iso_3166_3, ['AUT','BEL','DNK','FIN','FRA','DEU','IRL','ITA','NLD','NOR','ESP','SWE','GBR','USA'])) { $types[] = GatewayType::KLARNA; } @@ -292,30 +288,22 @@ class StripePaymentDriver extends BaseDriver switch ($gateway_type_id) { case GatewayType::CREDIT_CARD: return 'gateways.stripe.credit_card'; - break; case GatewayType::SOFORT: return 'gateways.stripe.sofort'; - break; case GatewayType::BANK_TRANSFER: return 'gateways.stripe.ach'; - break; case GatewayType::SEPA: return 'gateways.stripe.sepa'; - break; case GatewayType::PRZELEWY24: return 'gateways.stripe.przelewy24'; - break; case GatewayType::CRYPTO: case GatewayType::ALIPAY: case GatewayType::APPLE_PAY: return 'gateways.stripe.other'; - break; case GatewayType::GIROPAY: return 'gateways.stripe.giropay'; - break; case GatewayType::KLARNA: return 'gateways.stripe.klarna'; - break; case GatewayType::IDEAL: return 'gateways.stripe.ideal'; case GatewayType::EPS: @@ -769,58 +757,38 @@ class StripePaymentDriver extends BaseDriver } elseif ($request->type === "payment_method.automatically_updated"){ // Will notify customer on updated information return response()->json([], 200); - } elseif ($request->type === "checkout.session.completed"){ - // Store payment token for Stripe BACS - $this->init(); - $setup_intent = $this->stripe->setupIntents->retrieve($request->data['object']['setup_intent'], []); - $clientpayment_token = ClientGatewayToken::where('gateway_customer_reference', $request->data['object']['customer'])->first(); - if ($clientpayment_token){ - $this->client = Client::where('id', $clientpayment_token->client_id)->first(); - $customer = $this->findOrCreateCustomer(); - $this->attach($setup_intent->payment_method, $customer); - $payment_method = $this->getStripePaymentMethod($setup_intent->payment_method); - $payment_meta = new \stdClass; - $payment_meta->brand = (string) $payment_method->bacs_debit->sort_code; - $payment_meta->last4 = (string) $payment_method->bacs_debit->last4; - $payment_meta->state = 'unauthorized'; - $payment_meta->type = GatewayType::BACS; - - $data = [ - 'payment_meta' => $payment_meta, - 'token' => $payment_method->id, - 'payment_method_id' => GatewayType::BACS, - ]; - $clientgateway = ClientGatewayToken::query() - ->where('token', $payment_method) - ->first(); - if (!$clientgateway){ - $this->storeGatewayToken($data, ['gateway_customer_reference' => $customer->id]); - } - } - return response()->json([], 200); } elseif ($request->type === "mandate.updated"){ - // Check if payment method BACS is still valid - if ($request->data['object']['status'] === "active"){ - // Check if payment method exists + + if ($request->data['object']['status'] == "active"){ + // Check if payment method existsn $payment_method = (string) $request->data['object']['payment_method']; + $clientgateway = ClientGatewayToken::query() ->where('token', $payment_method) ->first(); + if ($clientgateway){ - $clientgateway->meta->state = 'authorized'; - $clientgateway->update(); - }; + + $meta = $clientgateway->meta; + $meta->state = 'authorized'; + $clientgateway->meta = $meta; + $clientgateway->save(); + + } + return response()->json([], 200); } - elseif ($request->data['object']['status'] === "inactive" && $request->data['object']['payment_method']){ + elseif ($request->data['object']['status'] == "inactive" && $request->data['object']['payment_method']){ // Delete payment method $clientgateway = ClientGatewayToken::query() ->where('token', $request->data['object']['payment_method']) ->first(); + $clientgateway->delete(); + return response()->json([], 200); } - elseif ($request->data['object']['status'] === "pending"){ + elseif ($request->data['object']['status'] == "pending"){ return response()->json([], 200); } } diff --git a/public/js/clients/payments/stripe-bacs.js b/public/js/clients/payments/stripe-bacs.js index 91b29fd0c177..aa862e186294 100644 --- a/public/js/clients/payments/stripe-bacs.js +++ b/public/js/clients/payments/stripe-bacs.js @@ -1,2 +1,95 @@ -/*! For license information please see stripe-bacs.js.LICENSE.txt */ -(()=>{var e,t,n,o,r,a;function i(e,t){for(var n=0;n svg").classList.remove("hidden"),document.querySelector("#authorize-bacs > span").classList.add("hidden"),location.href=document.querySelector("meta[name=stripe-redirect-url]").content})):(o.payNowButton=document.getElementById("pay-now"),document.getElementById("pay-now").addEventListener("click",(function(e){o.payNowButton.disabled=!0,o.payNowButton.querySelector("svg").classList.remove("hidden"),o.payNowButton.querySelector("span").classList.add("hidden"),document.getElementById("server-response").submit()})),o.payment_data=Array.from(document.getElementsByClassName("toggle-payment-with-token")),o.payment_data.length>0?o.payment_data.forEach((function(e){return e.addEventListener("click",(function(e){document.querySelector("input[name=token]").value=e.target.dataset.token}))})):(o.errors.textContent=document.querySelector("meta[name=translation-payment-method-required]").content,o.errors.hidden=!1,o.payNowButton.disabled=!0,o.payNowButton.querySelector("span").classList.remove("hidden"),o.payNowButton.querySelector("svg").classList.add("hidden")))})),this.key=t,this.errors=document.getElementById("errors"),this.stripeConnect=n,this.onlyAuthorization=m})),s=null!==(e=null===(t=document.querySelector('meta[name="stripe-publishable-key"]'))||void 0===t?void 0:t.content)&&void 0!==e?e:"",l=null!==(n=null===(o=document.querySelector('meta[name="stripe-account-id"]'))||void 0===o?void 0:o.content)&&void 0!==n?n:"",m=null!==(r=null===(a=document.querySelector('meta[name="only-authorization"]'))||void 0===a?void 0:a.content)&&void 0!==r?r:"";new d(s,l).setupStripe().handle()})(); \ No newline at end of file +/******/ (() => { // webpackBootstrap +var __webpack_exports__ = {}; +/*!******************************************************!*\ + !*** ./resources/js/clients/payments/stripe-bacs.js ***! + \******************************************************/ +var _document$querySelect, _document$querySelect2, _document$querySelect3, _document$querySelect4, _document$querySelect5, _document$querySelect6; + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +/** + * 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://www.elastic.co/licensing/elastic-license + */ +var ProcessBACS = /*#__PURE__*/_createClass(function ProcessBACS(key, stripeConnect) { + var _this = this; + + _classCallCheck(this, ProcessBACS); + + _defineProperty(this, "setupStripe", function () { + if (_this.stripeConnect) { + // this.stripe.stripeAccount = this.stripeConnect; + _this.stripe = Stripe(_this.key, { + stripeAccount: _this.stripeConnect + }); + } else { + _this.stripe = Stripe(_this.key); + } + + return _this; + }); + + _defineProperty(this, "payment_data", void 0); + + _defineProperty(this, "handle", function () { + if (_this.onlyAuthorization) { + document.getElementById('authorize-bacs').addEventListener('click', function (e) { + document.getElementById('authorize-bacs').disabled = true; + document.querySelector('#authorize-bacs > svg').classList.remove('hidden'); + document.querySelector('#authorize-bacs > span').classList.add('hidden'); + location.href = document.querySelector('meta[name=stripe-redirect-url]').content; + }); + } else { + _this.payNowButton = document.getElementById('pay-now'); + document.getElementById('pay-now').addEventListener('click', function (e) { + _this.payNowButton.disabled = true; + + _this.payNowButton.querySelector('svg').classList.remove('hidden'); + + _this.payNowButton.querySelector('span').classList.add('hidden'); + + document.getElementById('server-response').submit(); + }); + _this.payment_data = Array.from(document.getElementsByClassName('toggle-payment-with-token')); + + if (_this.payment_data.length > 0) { + _this.payment_data.forEach(function (element) { + return element.addEventListener('click', function (element) { + document.querySelector('input[name=token]').value = element.target.dataset.token; + }); + }); + } else { + _this.errors.textContent = document.querySelector('meta[name=translation-payment-method-required]').content; + _this.errors.hidden = false; + _this.payNowButton.disabled = true; + + _this.payNowButton.querySelector('span').classList.remove('hidden'); + + _this.payNowButton.querySelector('svg').classList.add('hidden'); + } + } + }); + + this.key = key; + this.errors = document.getElementById('errors'); + this.stripeConnect = stripeConnect; + this.onlyAuthorization = onlyAuthorization; +}); + +var publishableKey = (_document$querySelect = (_document$querySelect2 = document.querySelector('meta[name="stripe-publishable-key"]')) === null || _document$querySelect2 === void 0 ? void 0 : _document$querySelect2.content) !== null && _document$querySelect !== void 0 ? _document$querySelect : ''; +var stripeConnect = (_document$querySelect3 = (_document$querySelect4 = document.querySelector('meta[name="stripe-account-id"]')) === null || _document$querySelect4 === void 0 ? void 0 : _document$querySelect4.content) !== null && _document$querySelect3 !== void 0 ? _document$querySelect3 : ''; +var onlyAuthorization = (_document$querySelect5 = (_document$querySelect6 = document.querySelector('meta[name="only-authorization"]')) === null || _document$querySelect6 === void 0 ? void 0 : _document$querySelect6.content) !== null && _document$querySelect5 !== void 0 ? _document$querySelect5 : ''; +new ProcessBACS(publishableKey, stripeConnect).setupStripe().handle(); +/******/ })() +; \ No newline at end of file diff --git a/public/js/clients/payments/stripe-sepa.js b/public/js/clients/payments/stripe-sepa.js index 18a09e4ee072..4ba7accb951c 100644 --- a/public/js/clients/payments/stripe-sepa.js +++ b/public/js/clients/payments/stripe-sepa.js @@ -20,7 +20,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope * * @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com) * - * @license https://www.elastic.co/licensing/elastic-license + * @license https://www.elastic.co/licensing/elastic-license */ var ProcessSEPA = /*#__PURE__*/function () { function ProcessSEPA(key, stripeConnect) { @@ -165,10 +165,6 @@ var ProcessSEPA = /*#__PURE__*/function () { document.querySelector('input[name="store_card"]').value = tokenBillingCheckbox.value; } - if (document.querySelector('input[name=token]').value.length > 2) { - document.querySelector('input[name="store_card"]').value = false; - } - document.getElementById('server-response').submit(); } }, { diff --git a/public/mix-manifest.json b/public/mix-manifest.json index c63784ebb642..4cd34a3a1158 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,50 +1,50 @@ { - "/js/app.js": "/js/app.js?id=19300612c6880925e8043b61e8d49632", - "/js/clients/payment_methods/authorize-authorize-card.js": "/js/clients/payment_methods/authorize-authorize-card.js?id=9fb77e87fe0f85a367050e08f79ec9df", - "/js/clients/payments/authorize-credit-card-payment.js": "/js/clients/payments/authorize-credit-card-payment.js?id=803182f668c39d631ca5c55437876da4", - "/js/clients/payments/forte-credit-card-payment.js": "/js/clients/payments/forte-credit-card-payment.js?id=6e9f466c5504d3753f9b4ffc6f947095", - "/js/clients/payments/forte-ach-payment.js": "/js/clients/payments/forte-ach-payment.js?id=1d10fcc52a1f15858e5da216f1df45ec", - "/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=7bed15f51bca764378d9a3aa605b8664", - "/js/clients/payments/stripe-klarna.js": "/js/clients/payments/stripe-klarna.js?id=5770e0d82d3843c68903744530f5ae73", - "/js/clients/payments/stripe-bacs.js": "/js/clients/payments/stripe-bacs.js?id=5739aad61ac7bbb20f2149d203849ff7", - "/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=d4f86ddee4e8a1d6e9719010aa0fe62b", - "/js/clients/purchase_orders/action-selectors.js": "/js/clients/purchase_orders/action-selectors.js?id=160b8161599fc2429b449b0970d3ba6c", - "/js/clients/purchase_orders/accept.js": "/js/clients/purchase_orders/accept.js?id=ddd4aa4069ea79411eeec367b7d5986d", - "/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=28221de8f1cb37f845ba4ec59bcd8867", - "/js/clients/payments/stripe-sofort.js": "/js/clients/payments/stripe-sofort.js?id=1c5493a4c53a5b862d07ee1818179ea9", - "/js/clients/payments/stripe-alipay.js": "/js/clients/payments/stripe-alipay.js?id=0274ab4f8d2b411f2a2fe5142301e7af", - "/js/clients/payments/checkout-credit-card.js": "/js/clients/payments/checkout-credit-card.js?id=4bd34a0b160f6f29b3096d870ac4d308", - "/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=6fb63bae43d077b5061f4dadfe8dffc8", - "/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=61a346e1977d3a1fec3634b234baa25c", - "/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=809de47258a681f0ffebe787dd6a9a93", - "/js/setup/setup.js": "/js/setup/setup.js?id=27560b012f166f8b9417ced2188aab70", - "/js/clients/payments/card-js.min.js": "/js/clients/payments/card-js.min.js?id=8ce33c3deae058ad314fb8357e5be63b", - "/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=be5307abc990bb44f2f92628103b1d98", - "/js/clients/shared/multiple-downloads.js": "/js/clients/shared/multiple-downloads.js?id=c2caa29f753ad1f3a12ca45acddacd72", - "/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=2b2fe55f926789abc52f19111006e1ec", - "/js/clients/payments/braintree-credit-card.js": "/js/clients/payments/braintree-credit-card.js?id=8e3b1c4c78c976ff0c43cb739c26b1f3", - "/js/clients/payments/braintree-paypal.js": "/js/clients/payments/braintree-paypal.js?id=5764a8d406c1eda848d073f10d178626", - "/js/clients/payments/wepay-credit-card.js": "/js/clients/payments/wepay-credit-card.js?id=dbba20d70fbebb326ddbc46115af9771", - "/js/clients/payment_methods/wepay-bank-account.js": "/js/clients/payment_methods/wepay-bank-account.js?id=b8706d7de6127f184ad19b2a810880be", - "/js/clients/payments/paytrace-credit-card.js": "/js/clients/payments/paytrace-credit-card.js?id=e0b1231a7bf6252672836222285c0f52", - "/js/clients/payments/mollie-credit-card.js": "/js/clients/payments/mollie-credit-card.js?id=bbab588ed009a93345bec520cbe66869", - "/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=31d068e55757636f34834bc2494250df", - "/js/clients/payment_methods/braintree-ach.js": "/js/clients/payment_methods/braintree-ach.js?id=6d8c7fd66d911b20cdc4248e33db1b3a", - "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=b180fd6378d3723d3e9133e0b1943ac6", - "/js/clients/statements/view.js": "/js/clients/statements/view.js?id=7971b212e8a849fe36bfe915f81023bd", - "/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=c36ab5621413ef1de7c864bc8eb7439e", - "/js/clients/payments/stripe-sepa.js": "/js/clients/payments/stripe-sepa.js?id=b258636d8bae366e9d8f54274f437181", - "/js/clients/payment_methods/authorize-checkout-card.js": "/js/clients/payment_methods/authorize-checkout-card.js?id=e43f862d70d8710761f0856e528ec3d1", - "/js/clients/payments/stripe-giropay.js": "/js/clients/payments/stripe-giropay.js?id=72ad4ad19297f211c2e6d0fa1fa1f76d", - "/js/clients/payments/stripe-acss.js": "/js/clients/payments/stripe-acss.js?id=90b1805b1ca0264474b38054a2664c5b", - "/js/clients/payments/stripe-bancontact.js": "/js/clients/payments/stripe-bancontact.js?id=03e5d7ee187e76b0b7c16bfa91804a8a", - "/js/clients/payments/stripe-becs.js": "/js/clients/payments/stripe-becs.js?id=de2bd0ef2859e19e4f98ea9d6d11cb54", - "/js/clients/payments/stripe-eps.js": "/js/clients/payments/stripe-eps.js?id=213d9ad34a79144a0d3345cb6a262e95", - "/js/clients/payments/stripe-ideal.js": "/js/clients/payments/stripe-ideal.js?id=0a6b434e3849db26c35a143e0347e914", - "/js/clients/payments/stripe-przelewy24.js": "/js/clients/payments/stripe-przelewy24.js?id=3d53d2f7d0291d9f92cf7414dd2d351c", - "/js/clients/payments/stripe-browserpay.js": "/js/clients/payments/stripe-browserpay.js?id=db71055862995fd6ae21becfc587a3de", - "/js/clients/payments/stripe-fpx.js": "/js/clients/payments/stripe-fpx.js?id=914a6846ad1e5584635e7430fef76875", - "/css/app.css": "/css/app.css?id=aeba2a01bf369ac522071ab602096c66", + "/js/app.js": "/js/app.js?id=7b6124b74168ccb1cc7da22f7a2bc9ed", + "/js/clients/payment_methods/authorize-authorize-card.js": "/js/clients/payment_methods/authorize-authorize-card.js?id=b6723e0b8ea33f1f50617fa5f289a9d3", + "/js/clients/payments/authorize-credit-card-payment.js": "/js/clients/payments/authorize-credit-card-payment.js?id=faf4828cc6b3b73b69c53d3046661884", + "/js/clients/payments/forte-credit-card-payment.js": "/js/clients/payments/forte-credit-card-payment.js?id=f42dd0caddb3603e71db061924c4b172", + "/js/clients/payments/forte-ach-payment.js": "/js/clients/payments/forte-ach-payment.js?id=b8173c7c0dee76bf9ae6312a963ae0e4", + "/js/clients/payments/stripe-ach.js": "/js/clients/payments/stripe-ach.js?id=207f218c44553470287f35f33a7eb154", + "/js/clients/payments/stripe-klarna.js": "/js/clients/payments/stripe-klarna.js?id=7268f9282c6bb3b04d19d11a7b0c1681", + "/js/clients/payments/stripe-bacs.js": "/js/clients/payments/stripe-bacs.js?id=7dbb7d052a04c0537f873a5a9e599802", + "/js/clients/invoices/action-selectors.js": "/js/clients/invoices/action-selectors.js?id=404b7ee18e420de0e73f5402b7e39122", + "/js/clients/purchase_orders/action-selectors.js": "/js/clients/purchase_orders/action-selectors.js?id=2f0c4e3bab30a98e33ac768255113174", + "/js/clients/purchase_orders/accept.js": "/js/clients/purchase_orders/accept.js?id=9bb483a89a887f753e49c0b635d6276a", + "/js/clients/invoices/payment.js": "/js/clients/invoices/payment.js?id=752e2bb6390f1a422e31868cf2a2bf67", + "/js/clients/payments/stripe-sofort.js": "/js/clients/payments/stripe-sofort.js?id=4fc5dec1bc4fc21b9e32b1b490c3e7ae", + "/js/clients/payments/stripe-alipay.js": "/js/clients/payments/stripe-alipay.js?id=0a4361f9c468fa087ff543f1793adc7d", + "/js/clients/payments/checkout-credit-card.js": "/js/clients/payments/checkout-credit-card.js?id=7cb96275b3eb4901054564c654fb60e3", + "/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=3a4c5cfac7dd4c9218be55945c3c8e85", + "/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=00615ec62b99e3245769d4603e6053ce", + "/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=6e7c8ab039a239727317ae8622de10db", + "/js/setup/setup.js": "/js/setup/setup.js?id=8cab3339ef48418e1fb2e7a9259d51ca", + "/js/clients/payments/card-js.min.js": "/js/clients/payments/card-js.min.js?id=cf50b5ba1fcd1d184bf0c10d710672c8", + "/js/clients/shared/pdf.js": "/js/clients/shared/pdf.js?id=682de6347049b32c9488f39c78a68ace", + "/js/clients/shared/multiple-downloads.js": "/js/clients/shared/multiple-downloads.js?id=d3c404bb646f1aeaf2382a8c57ab8e1a", + "/js/clients/linkify-urls.js": "/js/clients/linkify-urls.js?id=e1c0599d6f7dc163b549a6df0b3490b4", + "/js/clients/payments/braintree-credit-card.js": "/js/clients/payments/braintree-credit-card.js?id=8b036822abaa4ceb379008fc14208dc2", + "/js/clients/payments/braintree-paypal.js": "/js/clients/payments/braintree-paypal.js?id=de0b1d0c6da7ff509bef3aee8d09e7f8", + "/js/clients/payments/wepay-credit-card.js": "/js/clients/payments/wepay-credit-card.js?id=92ef8632637d335cd0e4bc29a05b7df8", + "/js/clients/payment_methods/wepay-bank-account.js": "/js/clients/payment_methods/wepay-bank-account.js?id=af85b3f6d53c55b5d0e3a80ef58ce0de", + "/js/clients/payments/paytrace-credit-card.js": "/js/clients/payments/paytrace-credit-card.js?id=3869bc6d80acc83f81d9afe8efaae728", + "/js/clients/payments/mollie-credit-card.js": "/js/clients/payments/mollie-credit-card.js?id=7cd5a1d95d33ada211ce185ad6e4bb33", + "/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=27274d334aed0824ce4654fa22132f7f", + "/js/clients/payment_methods/braintree-ach.js": "/js/clients/payment_methods/braintree-ach.js?id=f85ebb6a77002afd350086d1274b6af5", + "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=238e7001420a22b001856193689a1e70", + "/js/clients/statements/view.js": "/js/clients/statements/view.js?id=13e043123f1e58409394458a70461d63", + "/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=494f58d2fd8984792833ba7d3055de08", + "/js/clients/payments/stripe-sepa.js": "/js/clients/payments/stripe-sepa.js?id=381fa89af62cf30c3daeb54ef65b9bb6", + "/js/clients/payment_methods/authorize-checkout-card.js": "/js/clients/payment_methods/authorize-checkout-card.js?id=659c4287fb8ef1c458071c206c4d965d", + "/js/clients/payments/stripe-giropay.js": "/js/clients/payments/stripe-giropay.js?id=852a9abf5f3a29f5d7d2f989cbeab374", + "/js/clients/payments/stripe-acss.js": "/js/clients/payments/stripe-acss.js?id=447c587a5eeb0c1de3091c8358db7ad7", + "/js/clients/payments/stripe-bancontact.js": "/js/clients/payments/stripe-bancontact.js?id=f694d3f9f01e4550cb5a3eb6cb43c12d", + "/js/clients/payments/stripe-becs.js": "/js/clients/payments/stripe-becs.js?id=97ea3555a8504662eda5fce9c9115e5a", + "/js/clients/payments/stripe-eps.js": "/js/clients/payments/stripe-eps.js?id=146d48d03f5fc4b1cf122189119e2877", + "/js/clients/payments/stripe-ideal.js": "/js/clients/payments/stripe-ideal.js?id=34cf4ee3f189427fb69d0df8f5a4b766", + "/js/clients/payments/stripe-przelewy24.js": "/js/clients/payments/stripe-przelewy24.js?id=cfdcc5bf20d6bfa09700708dfdd943e2", + "/js/clients/payments/stripe-browserpay.js": "/js/clients/payments/stripe-browserpay.js?id=7015e43eb5f9f9f2f45f54b41b5780a0", + "/js/clients/payments/stripe-fpx.js": "/js/clients/payments/stripe-fpx.js?id=243c2929386b10c6a0c49ca3bcabfb2d", + "/css/app.css": "/css/app.css?id=d3b1387842383d1983c767978d20ec86", "/css/card-js.min.css": "/css/card-js.min.css?id=62afeb675235451543ada60afcedcb7c", "/vendor/clipboard.min.js": "/vendor/clipboard.min.js?id=15f52a1ee547f2bdd46e56747332ca2d" }