mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 17:04:45 -04:00
Ability to pay with token
This commit is contained in:
parent
77733ffd0a
commit
2ab65b12fa
@ -86,17 +86,9 @@ class CreditCard
|
||||
|
||||
$customer = $this->braintree->findOrCreateCustomer();
|
||||
|
||||
$payment_method = $this->braintree->gateway->paymentMethod()->create([
|
||||
'customerId' => $customer->id,
|
||||
'paymentMethodNonce' => $state['token'],
|
||||
'options' => [
|
||||
'verifyCard' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
$result = $this->braintree->gateway->transaction()->sale([
|
||||
'amount' => $this->braintree->payment_hash->data->amount_with_fee,
|
||||
'paymentMethodToken' => $payment_method->paymentMethod->token,
|
||||
'paymentMethodToken' => $this->getPaymentToken($request->all(), $customer->id),
|
||||
'deviceData' => $state['client-data'],
|
||||
'options' => [
|
||||
'submitForSettlement' => true
|
||||
@ -106,7 +98,7 @@ class CreditCard
|
||||
if ($result->success) {
|
||||
$this->braintree->logSuccessfulGatewayResponse(['response' => $request->server_response, 'data' => $this->braintree->payment_hash], SystemLog::TYPE_BRAINTREE);
|
||||
|
||||
if ($request->store_card) {
|
||||
if ($request->store_card && is_null($request->token)) {
|
||||
$this->storePaymentMethod($payment_method, $customer->id);
|
||||
}
|
||||
|
||||
@ -116,12 +108,31 @@ class CreditCard
|
||||
return $this->processUnsuccessfulPayment($result);
|
||||
}
|
||||
|
||||
private function getPaymentToken(array $data, $customerId): ?string
|
||||
{
|
||||
if (array_key_exists('token', $data) && !is_null($data['token'])) {
|
||||
return $data['token'];
|
||||
}
|
||||
|
||||
$gateway_response = json_decode($data['gateway_response']);
|
||||
|
||||
$payment_method = $this->braintree->gateway->paymentMethod()->create([
|
||||
'customerId' => $customerId,
|
||||
'paymentMethodNonce' => $gateway_response->nonce,
|
||||
'options' => [
|
||||
'verifyCard' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
return $payment_method->paymentMethod->token;
|
||||
}
|
||||
|
||||
private function processSuccessfulPayment($response)
|
||||
{
|
||||
$state = $this->braintree->payment_hash->data;
|
||||
|
||||
$data = [
|
||||
'payment_type' => PaymentType::parseCardType(strtolower($state->server_response->details->cardType)),
|
||||
'payment_type' => PaymentType::parseCardType(strtolower($response->transaction->creditCard['cardType'])),
|
||||
'amount' => $this->braintree->payment_hash->data->amount_with_fee,
|
||||
'transaction_reference' => $response->transaction->id,
|
||||
'gateway_type_id' => GatewayType::CREDIT_CARD,
|
||||
|
@ -66,54 +66,111 @@
|
||||
@endcomponent
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.pay_now')
|
||||
@include('portal.ninja2020.gateways.includes.pay_now', ['id' => 'pay-now-with-token', 'class' => 'hidden'])
|
||||
@endsection
|
||||
|
||||
@section('gateway_footer')
|
||||
<script type="text/javascript">
|
||||
let payNow = document.getElementById('pay-now');
|
||||
class BraintreeCreditCard {
|
||||
initBraintreeDataCollector() {
|
||||
window.braintree.client.create({
|
||||
authorization: document.querySelector('meta[name=client-token]').content
|
||||
}, function (err, clientInstance) {
|
||||
window.braintree.dataCollector.create({
|
||||
client: clientInstance,
|
||||
paypal: true
|
||||
}, function (err, dataCollectorInstance) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelector('input[name=client-data]').value = dataCollectorInstance.deviceData;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
mountBraintreePaymentWidget() {
|
||||
window.braintree.dropin.create({
|
||||
authorization: document.querySelector('meta[name=client-token]').content,
|
||||
container: '#dropin-container'
|
||||
}, this.handleCallback);
|
||||
}
|
||||
|
||||
handleCallback(error, dropinInstance) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
|
||||
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;
|
||||
});
|
||||
});
|
||||
let payNow = document.getElementById('pay-now');
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
payNow.addEventListener('click', () => {
|
||||
dropinInstance.requestPaymentMethod((error, payload) => {
|
||||
if (error) {
|
||||
return console.error(error);
|
||||
}
|
||||
payNow.disabled = true;
|
||||
|
||||
document.querySelector('input[name=token]').value = payload.nonce;
|
||||
document.querySelector('input[name=gateway_response]').value = JSON.stringify(payload);
|
||||
payNow.querySelector('svg').classList.remove('hidden');
|
||||
payNow.querySelector('span').classList.add('hidden');
|
||||
|
||||
let tokenBillingCheckbox = document.querySelector(
|
||||
'input[name="token-billing-checkbox"]:checked'
|
||||
);
|
||||
document.querySelector('input[name=gateway_response]').value = JSON.stringify(payload);
|
||||
|
||||
if (tokenBillingCheckbox) {
|
||||
document.querySelector('input[name="store_card"]').value =
|
||||
tokenBillingCheckbox.value;
|
||||
}
|
||||
let tokenBillingCheckbox = document.querySelector(
|
||||
'input[name="token-billing-checkbox"]:checked'
|
||||
);
|
||||
|
||||
document.getElementById('server-response').submit();
|
||||
if (tokenBillingCheckbox) {
|
||||
document.querySelector('input[name="store_card"]').value =
|
||||
tokenBillingCheckbox.value;
|
||||
}
|
||||
|
||||
document.getElementById('server-response').submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
handle() {
|
||||
this.initBraintreeDataCollector();
|
||||
this.mountBraintreePaymentWidget();
|
||||
|
||||
Array
|
||||
.from(document.getElementsByClassName('toggle-payment-with-token'))
|
||||
.forEach((element) => element.addEventListener('click', (element) => {
|
||||
document.getElementById('dropin-container').classList.add('hidden');
|
||||
document.getElementById('save-card--container').style.display = 'none';
|
||||
document.querySelector('input[name=token]').value = element.target.dataset.token;
|
||||
|
||||
document.getElementById('pay-now-with-token').classList.remove('hidden');
|
||||
document.getElementById('pay-now').classList.add('hidden');
|
||||
}));
|
||||
|
||||
document
|
||||
.getElementById('toggle-payment-with-credit-card')
|
||||
.addEventListener('click', (element) => {
|
||||
document.getElementById('dropin-container').classList.remove('hidden');
|
||||
document.getElementById('save-card--container').style.display = 'grid';
|
||||
document.querySelector('input[name=token]').value = "";
|
||||
|
||||
document.getElementById('pay-now-with-token').classList.add('hidden');
|
||||
document.getElementById('pay-now').classList.remove('hidden');
|
||||
});
|
||||
|
||||
let payNowWithToken = document.getElementById('pay-now-with-token');
|
||||
|
||||
payNowWithToken
|
||||
.addEventListener('click', (element) => {
|
||||
payNowWithToken.disabled = true;
|
||||
payNowWithToken.querySelector('svg').classList.remove('hidden');
|
||||
payNowWithToken.querySelector('span').classList.add('hidden');
|
||||
|
||||
document.getElementById('server-response').submit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
new BraintreeCreditCard().handle();
|
||||
</script>
|
||||
@endsection
|
||||
|
Loading…
x
Reference in New Issue
Block a user