Can anyone please explain me how could i make a working Braintree payment with hosted fields, in Laravel. I tried to look at the documentation myself but i couldn't make it working.
i created the token in the controller to be sent to the view like:
$gateway = new \Braintree\Gateway([
'environment' => config('services.braintree.environment'),
'merchantId' => config('services.braintree.merchantId'),
'publicKey' => config('services.braintree.publicKey'),
'privateKey' => config('services.braintree.privateKey')
]);
$paypalToken = $gateway->ClientToken()->generate();
return view('checkout')->with(['paypalToken' => $paypalToken]);
On the blade view i have this JS:
var form = document.querySelector('#payment-form');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: '{{ $paypalToken }}'
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error(clientErr);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: '10/2019'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
// submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload){
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
}, false);
});
// Create a PayPal Checkout component.
braintree.paypalCheckout.create({
client: clientInstance
}, function (paypalCheckoutErr, paypalCheckoutInstance) {
if (paypalCheckoutErr) {
console.error('Error creating PayPal Checkout:', paypalCheckoutErr);
return;
}
// Set up PayPal with the checkout.js library
paypal.Button.render({
env: 'sandbox', // or 'production'
commit: true,
payment: function () {
return paypalCheckoutInstance.createPayment({
flow: 'checkout', // Required
amount: '{{ presentPrice($newTotal + 5000) }}', // Required
currency: 'USD', // Required
});
},
onAuthorize: function (data, actions) {
return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) {
// Submit `payload.nonce` to your server.
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
},
onCancel: function (data) {
console.log('checkout.js payment cancelled', JSON.stringify(data, 0, 2));
},
onError: function (err) {
console.error('checkout.js error', err);
}
}, '#paypal-button').then(function () {
// The PayPal button will be rendered in an html element with the id
// `paypal-button`. This function will be called when the PayPal button
// is set up and ready to be used.
});
});
});
Here is the method in were i process the payment:
$gateway = new \Braintree\Gateway([
'environment' => config('services.braintree.environment'),
'merchantId' => config('services.braintree.merchantId'),
'publicKey' => config('services.braintree.publicKey'),
'privateKey' => config('services.braintree.privateKey')
]);
$nonce = $request->payment_method_nonce;
$result = $gateway->transaction()->sale([
'amount' => round(getNumbers()->get('newTotal') / 100, 2),
'paymentMethodNonce' => $nonce,
'options' => [
'submitForSettlement' => True
]
]);
if ($result->success) {
$transaction = $result->transaction;
$order = $this->addToOrdersTablesPaypal(
$email,
$firstName.' '.$lastName,
null
);
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
} else {
$order = $this->addToOrdersTablesPaypal(
$email,
$firstName.' '.$firstName,
$result->message
);
return back()->withErrors('An error occurred with the message: '.$result->message);
}
can anyone help me, understand what is missing?
i solved it, i actually found an workaround, i had to create a controller for the hosted fields, and it worked.