This commit is contained in:
Benjamin Beganović 2021-04-28 14:54:50 +02:00
parent e77c3492ed
commit 9c97421a55
6 changed files with 202 additions and 18 deletions

View File

@ -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());
}
}
/**

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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",

50
composer.lock generated
View File

@ -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",

View File

@ -4,6 +4,8 @@
<meta name="client-token" content="{{ $client_token ?? '' }}"/>
<script src="https://js.braintreegateway.com/web/dropin/1.27.0/js/dropin.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.76.2/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.76.2/js/data-collector.min.js"></script>
@endsection
@section('gateway_content')
@ -17,6 +19,7 @@
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
<input type="hidden" name="token">
<input type="hidden" name="client-data">
</form>
@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')
<script type="text/javascript">
let payNow = document.getElementById('pay-now');
braintree.client.create({
authorization: document.querySelector('meta[name=client-token]').content
}, function (err, clientInstance) {
braintree.dataCollector.create({
client: clientInstance,
paypal: true
}, function (err, dataCollectorInstance) {
if (err) {
return;
}
document.querySelector('input[name=client-data]').value = dataCollectorInstance.deviceData;
});
});
braintree.dropin.create({
authorization: document.querySelector('meta[name=client-token]').content,
container: '#dropin-container'
}, (error, dropinInstance) => {
if (error) console.error(error);
payNow.addEventListener('click', () => {
dropinInstance.requestPaymentMethod((error, payload) => {
if (error) {
return console.error(error);
}
document.querySelector('input[name=token]').value = payload.nonce;
document.querySelector('input[name=gateway_response]').value = JSON.stringify(payload);
document.getElementById('server-response').submit();
});
});
});
</script>
@endpush
@endsection