diff --git a/app/Http/Controllers/ClientPortal/PaymentController.php b/app/Http/Controllers/ClientPortal/PaymentController.php index 6d17c3daff54..0cd74d6d63bf 100644 --- a/app/Http/Controllers/ClientPortal/PaymentController.php +++ b/app/Http/Controllers/ClientPortal/PaymentController.php @@ -299,24 +299,12 @@ class PaymentController extends Controller $payment_hash = PaymentHash::whereRaw('BINARY `hash`= ?', [$request->payment_hash])->first(); - try { return $gateway ->driver(auth()->user()->client) ->setPaymentMethod($request->input('payment_method_id')) ->setPaymentHash($payment_hash) ->checkRequirements() ->processPaymentResponse($request); - } catch (\Exception $e) { - SystemLogger::dispatch( - $e->getMessage(), - SystemLog::CATEGORY_GATEWAY_RESPONSE, - SystemLog::EVENT_GATEWAY_FAILURE, - SystemLog::TYPE_FAILURE, - auth('contact')->user()->client - ); - - throw new PaymentFailed($e->getMessage()); - } } /** diff --git a/app/PaymentDrivers/Braintree/CreditCard.php b/app/PaymentDrivers/Braintree/CreditCard.php index 8ffb51bc812f..faebb85885e6 100644 --- a/app/PaymentDrivers/Braintree/CreditCard.php +++ b/app/PaymentDrivers/Braintree/CreditCard.php @@ -13,6 +13,15 @@ namespace App\PaymentDrivers\Braintree; +use App\Exceptions\PaymentFailed; +use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; +use App\Http\Requests\Request; +use App\Jobs\Mail\PaymentFailureMailer; +use App\Jobs\Util\SystemLogger; +use App\Models\GatewayType; +use App\Models\Payment; +use App\Models\PaymentType; +use App\Models\SystemLog; use App\PaymentDrivers\BraintreePaymentDriver; class CreditCard @@ -25,6 +34,8 @@ class CreditCard public function __construct(BraintreePaymentDriver $braintree) { $this->braintree = $braintree; + + $this->braintree->init(); } /** @@ -36,8 +47,95 @@ class CreditCard public function paymentView(array $data) { $data['gateway'] = $this->braintree; - $data['client_token'] = + $data['client_token'] = $this->braintree->gateway->clientToken()->generate(); return render('gateways.braintree.credit_card.pay', $data); } + + public function paymentResponse(PaymentResponseRequest $request) + { + $state = [ + 'server_response' => json_decode($request->gateway_response), + 'payment_hash' => $request->payment_hash, + ]; + + $state = array_merge($state, $request->all()); + $state['store_card'] = boolval($state['store_card']); + + $this->braintree->payment_hash->data = array_merge((array)$this->braintree->payment_hash->data, $state); + $this->braintree->payment_hash->save(); + + $result = $this->braintree->gateway->transaction()->sale([ + 'amount' => '2000.50', + 'paymentMethodNonce' => $state['token'], + 'deviceData' => $state['client-data'], + 'options' => [ + 'submitForSettlement' => true + ], + ]); + + if ($result->success) { + $this->braintree->logSuccessfulGatewayResponse(['response' => $request->server_response, 'data' => $this->braintree->payment_hash], SystemLog::TYPE_BRAINTREE); + + return $this->processSuccessfulPayment($result); + } + + return $this->processUnsuccessfulPayment($result); + } + + private function processSuccessfulPayment($response) + { + $state = $this->braintree->payment_hash->data; + + $data = [ + 'payment_type' => PaymentType::parseCardType(strtolower($state->server_response->details->cardType)), + 'amount' => 10, + 'transaction_reference' => $response->transaction->id, + 'gateway_type_id' => GatewayType::CREDIT_CARD, + ]; + + // Store card if checkbox selected. + + $payment = $this->braintree->createPayment($data, Payment::STATUS_COMPLETED); + + SystemLogger::dispatch( + ['response' => $response, 'data' => $data], + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_SUCCESS, + SystemLog::TYPE_BRAINTREE, + $this->braintree->client + ); + + return redirect()->route('client.payments.show', ['payment' => $this->braintree->encodePrimaryKey($payment->id)]); + } + + /** + * @throws PaymentFailed + */ + private function processUnsuccessfulPayment($response) + { + PaymentFailureMailer::dispatch($this->braintree->client, $response->transaction->additionalProcessorResponse, $this->braintree->client->company, 10); + + PaymentFailureMailer::dispatch( + $this->braintree->client, + $response, + $this->braintree->client->company, + 10, + ); + + $message = [ + 'server_response' => $response, + 'data' => $this->braintree->payment_hash->data, + ]; + + SystemLogger::dispatch( + $message, + SystemLog::CATEGORY_GATEWAY_RESPONSE, + SystemLog::EVENT_GATEWAY_FAILURE, + SystemLog::TYPE_BRAINTREE, + $this->braintree->client + ); + + throw new PaymentFailed($response->transaction->additionalProcessorResponse, $response->transaction->processorResponseCode); + } } diff --git a/app/PaymentDrivers/BraintreePaymentDriver.php b/app/PaymentDrivers/BraintreePaymentDriver.php index 198fc72a2b0b..cdcf693a2ab0 100644 --- a/app/PaymentDrivers/BraintreePaymentDriver.php +++ b/app/PaymentDrivers/BraintreePaymentDriver.php @@ -13,9 +13,11 @@ namespace App\PaymentDrivers; +use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest; use App\Models\GatewayType; use App\Models\SystemLog; use App\PaymentDrivers\Braintree\CreditCard; +use Illuminate\Http\Request; class BraintreePaymentDriver extends BaseDriver { @@ -25,6 +27,9 @@ class BraintreePaymentDriver extends BaseDriver public $can_authorise_credit_card = true; + /** + * @var \Braintree\Gateway; + */ public $gateway; public static $methods = [ @@ -34,9 +39,14 @@ class BraintreePaymentDriver extends BaseDriver const SYSTEM_LOG_TYPE = SystemLog::TYPE_BRAINTREE; - public function init() + public function init(): void { - + $this->gateway = new \Braintree\Gateway([ + 'environment' => $this->company_gateway->getConfigField('testMode') ? 'sandbox' : 'production', + 'merchantId' => $this->company_gateway->getConfigField('merchantId'), + 'publicKey' => $this->company_gateway->getConfigField('publicKey'), + 'privateKey' => $this->company_gateway->getConfigField('privateKey'), + ]); } public function setPaymentMethod($payment_method_id) @@ -60,4 +70,9 @@ class BraintreePaymentDriver extends BaseDriver { return $this->payment_method->paymentView($data); } + + public function processPaymentResponse($request) + { + return $this->payment_method->paymentResponse($request); + } } diff --git a/composer.json b/composer.json index 12254fd48628..41737065c251 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "authorizenet/authorizenet": "^2.0", "bacon/bacon-qr-code": "^2.0", "beganovich/snappdf": "^1.0", + "braintree/braintree_php": "^6.0", "checkout/checkout-sdk-php": "^1.0", "cleverit/ubl_invoice": "^1.3", "coconutcraig/laravel-postmark": "^2.10", diff --git a/composer.lock b/composer.lock index 66898315b8b0..a87e22a543d4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f01381d3d00f0bd84acbda078ad1b99e", + "content-hash": "7ded6dd53f8327fdf7bbcfd4e77a5080", "packages": [ { "name": "authorizenet/authorizenet", @@ -245,6 +245,54 @@ }, "time": "2021-03-19T21:20:07+00:00" }, + { + "name": "braintree/braintree_php", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/braintree/braintree_php.git", + "reference": "e22dc11e5e92182999288d914d14640a3f50cd85" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/braintree/braintree_php/zipball/e22dc11e5e92182999288d914d14640a3f50cd85", + "reference": "e22dc11e5e92182999288d914d14640a3f50cd85", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-dom": "*", + "ext-hash": "*", + "ext-openssl": "*", + "ext-xmlwriter": "*", + "php": ">=7.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Braintree\\": "lib/Braintree" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Braintree", + "homepage": "https://www.braintreepayments.com" + } + ], + "description": "Braintree PHP Client Library", + "support": { + "issues": "https://github.com/braintree/braintree_php/issues", + "source": "https://github.com/braintree/braintree_php/tree/6.0.0" + }, + "time": "2021-04-06T21:27:03+00:00" + }, { "name": "brick/math", "version": "0.9.2", diff --git a/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php b/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php index 984dfd1d7878..25c109c6972f 100644 --- a/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php +++ b/resources/views/portal/ninja2020/gateways/braintree/credit_card/pay.blade.php @@ -4,6 +4,8 @@ + + @endsection @section('gateway_content') @@ -17,6 +19,7 @@ + @component('portal.ninja2020.components.general.card-element', ['title' => ctrans('texts.payment_type')]) @@ -57,12 +60,43 @@ @include('portal.ninja2020.gateways.includes.pay_now') @endsection -@push('gateway_footer') +@section('gateway_footer') -@endpush +@endsection