diff --git a/app/PaymentDrivers/Square/CreditCard.php b/app/PaymentDrivers/Square/CreditCard.php index a8b75426caf4..923d47eb4483 100644 --- a/app/PaymentDrivers/Square/CreditCard.php +++ b/app/PaymentDrivers/Square/CreditCard.php @@ -12,6 +12,7 @@ namespace App\PaymentDrivers\Square; +use App\Exceptions\PaymentFailed; use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Models\ClientGatewayToken; use App\Models\GatewayType; @@ -113,18 +114,23 @@ class CreditCard implements MethodInterface $body->setLocationId($this->square_driver->company_gateway->getConfigField('locationId')); $body->setReferenceId(Str::random(16)); - if ($request->has('verificationToken') && $request->input('verificationToken')) { - $body->setVerificationToken($request->input('verificationToken')); - } - if ($request->shouldUseToken()) { $body->setCustomerId($cgt->gateway_customer_reference); + }elseif ($request->has('verificationToken') && $request->input('verificationToken')) { + $body->setVerificationToken($request->input('verificationToken')); } /** @var ApiResponse */ $response = $this->square_driver->square->getPaymentsApi()->createPayment($body); if ($response->isSuccess()) { + + $body = json_decode($response->getBody()); + + if($request->store_card){ + $this->createCard($body->payment->id); + } + return $this->processSuccessfulPayment($response); } @@ -161,6 +167,52 @@ class CreditCard implements MethodInterface return $this->square_driver->processUnsuccessfulTransaction($data); } + private function createCard($source_id) + { + + $square_card = new \Square\Models\Card(); + $square_card->setCustomerId($this->findOrCreateClient()); + + $body = new \Square\Models\CreateCardRequest(uniqid("st", true), $source_id, $square_card); + + $api_response = $this->square_driver + ->init() + ->square + ->getCardsApi() + ->createCard($body); + + $body = json_decode($api_response->getBody()); + + if ($api_response->isSuccess()) { + + try { + $payment_meta = new \stdClass; + $payment_meta->exp_month = (string) $body->card->exp_month; + $payment_meta->exp_year = (string) $body->card->exp_year; + $payment_meta->brand = (string) $body->card->card_brand; + $payment_meta->last4 = (string) $body->card->last_4; + $payment_meta->type = GatewayType::CREDIT_CARD; + + $data = [ + 'payment_meta' => $payment_meta, + 'token' => $body->card->id, + 'payment_method_id' => GatewayType::CREDIT_CARD, + ]; + + $this->square_driver->storeGatewayToken($data, ['gateway_customer_reference' => $body->card->customer_id]); + + } catch (\Exception $e) { + return $this->square_driver->processInternallyFailedPayment($this->square_driver, $e); + } + + } + else { + throw new PaymentFailed($body->errors[0]->detail, 500); + } + + return false; + } + private function findOrCreateClient() { $email_address = new \Square\Models\CustomerTextFilter(); diff --git a/public/js/clients/payments/square-credit-card.js b/public/js/clients/payments/square-credit-card.js index 55bdaf667762..e03b80cd2965 100644 --- a/public/js/clients/payments/square-credit-card.js +++ b/public/js/clients/payments/square-credit-card.js @@ -176,62 +176,79 @@ var SquareCreditCard = /*#__PURE__*/function () { }, { key: "handle", value: function () { - var _handle = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() { - var _document$getElementB, - _this = this, - _document$getElementB2, - _document$getElementB3; - var toggleWithToken, _document$getElementB4; - return _regeneratorRuntime().wrap(function _callee6$(_context6) { - while (1) switch (_context6.prev = _context6.next) { + var _handle = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() { + var _this = this; + return _regeneratorRuntime().wrap(function _callee7$(_context7) { + while (1) switch (_context7.prev = _context7.next) { case 0: - _context6.next = 2; - return this.init(); - case 2: - (_document$getElementB = document.getElementById('authorize-card')) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.addEventListener('click', function (e) { - return _this.completePaymentWithoutToken(e); - }); - (_document$getElementB2 = document.getElementById('pay-now')) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.addEventListener('click', function (e) { - var tokenInput = document.querySelector('input[name=token]'); - if (tokenInput.value) { - return _this.completePaymentUsingToken(e); - } - return _this.completePaymentWithoutToken(e); - }); - Array.from(document.getElementsByClassName('toggle-payment-with-token')).forEach(function (element) { - return element.addEventListener('click', function (element) { - document.getElementById('card-container').classList.add('hidden'); - document.getElementById('save-card--container').style.display = 'none'; - document.querySelector('input[name=token]').value = element.target.dataset.token; + document.getElementById('payment-list').classList.add('hidden'); + _context7.next = 3; + return this.init().then(function () { + var _document$getElementB, _document$getElementB2, _document$getElementB3, _document$getElementB4; + (_document$getElementB = document.getElementById('authorize-card')) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.addEventListener('click', function (e) { + return _this.completePaymentWithoutToken(e); }); - }); - (_document$getElementB3 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB3 === void 0 ? void 0 : _document$getElementB3.addEventListener('click', /*#__PURE__*/function () { - var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(element) { - return _regeneratorRuntime().wrap(function _callee5$(_context5) { - while (1) switch (_context5.prev = _context5.next) { - case 0: - document.getElementById('card-container').classList.remove('hidden'); - document.getElementById('save-card--container').style.display = 'grid'; - document.querySelector('input[name=token]').value = ''; - case 3: - case "end": - return _context5.stop(); - } - }, _callee5); - })); - return function (_x4) { - return _ref.apply(this, arguments); - }; - }()); - toggleWithToken = document.querySelector('.toggle-payment-with-token'); - if (!toggleWithToken) { + (_document$getElementB2 = document.getElementById('pay-now')) === null || _document$getElementB2 === void 0 ? void 0 : _document$getElementB2.addEventListener('click', function (e) { + var tokenInput = document.querySelector('input[name=token]'); + if (tokenInput.value) { + return _this.completePaymentUsingToken(e); + } + return _this.completePaymentWithoutToken(e); + }); + Array.from(document.getElementsByClassName('toggle-payment-with-token')).forEach(function (element) { + return element.addEventListener('click', /*#__PURE__*/function () { + var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(element) { + return _regeneratorRuntime().wrap(function _callee5$(_context5) { + while (1) switch (_context5.prev = _context5.next) { + case 0: + document.getElementById('card-container').classList.add('hidden'); + document.getElementById('save-card--container').style.display = 'none'; + document.querySelector('input[name=token]').value = element.target.dataset.token; + case 3: + case "end": + return _context5.stop(); + } + }, _callee5); + })); + return function (_x4) { + return _ref.apply(this, arguments); + }; + }()); + }); + (_document$getElementB3 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB3 === void 0 ? void 0 : _document$getElementB3.addEventListener('click', /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(element) { + return _regeneratorRuntime().wrap(function _callee6$(_context6) { + while (1) switch (_context6.prev = _context6.next) { + case 0: + document.getElementById('card-container').classList.remove('hidden'); + document.getElementById('save-card--container').style.display = 'grid'; + document.querySelector('input[name=token]').value = ''; + case 3: + case "end": + return _context6.stop(); + } + }, _callee6); + })); + return function (_x5) { + return _ref2.apply(this, arguments); + }; + }()); + + // let toggleWithToken = document.querySelector( + // '.toggle-payment-with-token' + // ); + + // if (!toggleWithToken) { + document.getElementById('loader').classList.add('hidden'); + document.getElementById('payment-list').classList.remove('hidden'); (_document$getElementB4 = document.getElementById('toggle-payment-with-credit-card')) === null || _document$getElementB4 === void 0 ? void 0 : _document$getElementB4.click(); - } - case 8: + // } + }); + case 3: case "end": - return _context6.stop(); + return _context7.stop(); } - }, _callee6, this); + }, _callee7, this); })); function handle() { return _handle.apply(this, arguments); diff --git a/public/js/clients/payments/stripe-credit-card.js b/public/js/clients/payments/stripe-credit-card.js index b5587ade882b..2488cd580aa5 100644 --- a/public/js/clients/payments/stripe-credit-card.js +++ b/public/js/clients/payments/stripe-credit-card.js @@ -31,8 +31,6 @@ var StripeCreditCard = /*#__PURE__*/function () { key: "setupStripe", value: function setupStripe() { if (this.stripeConnect) { - // this.stripe.stripeAccount = this.stripeConnect; - this.stripe = Stripe(this.key, { stripeAccount: this.stripeConnect }); diff --git a/public/mix-manifest.json b/public/mix-manifest.json index b5975fbf8977..5d7f7371c1b5 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -16,7 +16,7 @@ "/js/clients/payments/checkout-credit-card.js": "/js/clients/payments/checkout-credit-card.js?id=a2168c43060a7de40da20b5fc599bcab", "/js/clients/quotes/action-selectors.js": "/js/clients/quotes/action-selectors.js?id=4158693089b29ee8e13cb7d9ce4480a9", "/js/clients/quotes/approve.js": "/js/clients/quotes/approve.js?id=4e596cec23cdd6487534e6ed5499d791", - "/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=b483e14d15000c04edfe4c9c80fb97c9", + "/js/clients/payments/stripe-credit-card.js": "/js/clients/payments/stripe-credit-card.js?id=bfa116c1df42c641bc7a3ff4fa8d50dd", "/js/setup/setup.js": "/js/setup/setup.js?id=086b9e114b0b9ee01f909d686f489162", "/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=c9593b44d66f89874d13f99bc3e6ff33", @@ -30,7 +30,7 @@ "/js/clients/payments/mollie-credit-card.js": "/js/clients/payments/mollie-credit-card.js?id=2f72b969507e6135b5c52a65522ab3ae", "/js/clients/payments/eway-credit-card.js": "/js/clients/payments/eway-credit-card.js?id=0d1c8957b02c5601b7d57c39740bff75", "/js/clients/payment_methods/braintree-ach.js": "/js/clients/payment_methods/braintree-ach.js?id=2f8e5af9ba5ce266d2ee49b084fbe291", - "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=dbd7a15777def575562153c984dee08a", + "/js/clients/payments/square-credit-card.js": "/js/clients/payments/square-credit-card.js?id=a5e1407a161c3c72545d125dd1100571", "/js/clients/statements/view.js": "/js/clients/statements/view.js?id=bd92ab50acabf1cc5232912d53edc5e1", "/js/clients/payments/razorpay-aio.js": "/js/clients/payments/razorpay-aio.js?id=46e14d31acaf3adf58444a5de4b4122c", "/js/clients/payments/stripe-sepa.js": "/js/clients/payments/stripe-sepa.js?id=ef15c0865a29c3c17f2ad185cad0d28e", diff --git a/resources/js/clients/payments/square-credit-card.js b/resources/js/clients/payments/square-credit-card.js index cceaacc5a7f3..ca8a153e9359 100644 --- a/resources/js/clients/payments/square-credit-card.js +++ b/resources/js/clients/payments/square-credit-card.js @@ -125,7 +125,10 @@ class SquareCreditCard { } async handle() { - await this.init(); + + document.getElementById('payment-list').classList.add('hidden'); + + await this.init().then(() => { document .getElementById('authorize-card') @@ -146,7 +149,7 @@ class SquareCreditCard { Array.from( document.getElementsByClassName('toggle-payment-with-token') ).forEach((element) => - element.addEventListener('click', (element) => { + element.addEventListener('click', async (element) => { document .getElementById('card-container') .classList.add('hidden'); @@ -168,13 +171,17 @@ class SquareCreditCard { document.querySelector('input[name=token]').value = ''; }); - let toggleWithToken = document.querySelector( - '.toggle-payment-with-token' - ); + // let toggleWithToken = document.querySelector( + // '.toggle-payment-with-token' + // ); - if (!toggleWithToken) { + // if (!toggleWithToken) { + document.getElementById('loader').classList.add('hidden'); + document.getElementById('payment-list').classList.remove('hidden'); document.getElementById('toggle-payment-with-credit-card')?.click(); - } + // } + }); + } } diff --git a/resources/js/clients/payments/stripe-credit-card.js b/resources/js/clients/payments/stripe-credit-card.js index 93001723a4a0..30cbfe13bd5c 100644 --- a/resources/js/clients/payments/stripe-credit-card.js +++ b/resources/js/clients/payments/stripe-credit-card.js @@ -19,7 +19,6 @@ class StripeCreditCard { setupStripe() { if (this.stripeConnect){ - // this.stripe.stripeAccount = this.stripeConnect; this.stripe = Stripe(this.key, { stripeAccount: this.stripeConnect, diff --git a/resources/views/portal/ninja2020/gateways/square/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/square/credit_card/pay.blade.php index 79b2627db1ea..5c9e852cdcac 100644 --- a/resources/views/portal/ninja2020/gateways/square/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/square/credit_card/pay.blade.php @@ -7,7 +7,32 @@ + @endsection @section('gateway_content') @@ -33,23 +58,41 @@ @include('portal.ninja2020.gateways.includes.payment_details') - @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.pay_with')]) +
+
+
+ + + @endcomponent @include('portal.ninja2020.gateways.includes.save_card') diff --git a/routes/api.php b/routes/api.php index 42fdfb810966..86b3d0e7962e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -141,7 +141,6 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::get('activities', [ActivityController::class, 'index']); Route::get('activities/download_entity/{activity}', [ActivityController::class, 'downloadHistoricalEntity']); - Route::post('charts/totals', [ChartController::class, 'totals'])->name('chart.totals'); Route::post('charts/chart_summary', [ChartController::class, 'chart_summary'])->name('chart.chart_summary');