I am using the Braintree for Payment Process. I have created a subscrition plan and I am using PayPal and Card Payment in My Site. I was able to create a Successful subscription, But I want to show the get the response when the subscription is active/canceled and payment done or not. I know this can be done by webhooks But I am not getting where to start. I am using the laravel Framework. My Client Side code:
<form id="cardForm">
<div class="panel">
<header class="panel__header">
<h1>Card Payment</h1>
</header>
<div class="panel__content">
<div class="textfield--float-label">
<label class="hosted-field--label" for="card-number"><span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path
d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z"/>
</svg></span> Card Number
</label>
<div id="card-number" class="hosted-field"></div>
</div>
<div class="textfield--float-label">
<label class="hosted-field--label" for="expiration-date">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
<path
d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z"/>
</svg>
</span>
Expiration Date</label>
<div id="expiration-date" class="hosted-field"></div>
</div>
<div class="textfield--float-label">
<label class="hosted-field--label" for="cvv">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24">
<path
d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>
</svg>
</span>
CVV</label>
<div id="cvv" class="hosted-field"></div>
</div>
</div>
<footer class="panel__footer">
<button class="pay-button">Submit</button>
</footer>
</div>
</form>
<script>
var paypalButton = document.querySelector('#paypal');
var cardButton = document.querySelector('.pay-button');
var CLIENT_AUTHORIZATION = $('#client').val();
console.log(CLIENT_AUTHORIZATION);
braintree.client.create({
authorization: CLIENT_AUTHORIZATION
}, function (clientErr, clientInstance) {
if (clientErr) {
console.error('Error creating client:', clientErr);
return;
}
braintree.paypal.create({
client: clientInstance
}, function (paypalErr, paypalInstance) {
if (paypalErr) {
console.error('Error creating PayPal:', paypalErr);
return;
}
paypalButton.removeAttribute('disabled');
paypalButton.addEventListener('click', function (event) {
paypalInstance.tokenize({
flow: 'vault',
enableShippingAddress: false,
shippingAddressEditable: false,
}, function (tokenizeErr, payload) {
if (tokenizeErr) {
if (tokenizeErr.type !== 'CUSTOMER') {
console.error('Error tokenizing:', tokenizeErr);
alert(tokenizeErr.message);
}
return;
}
paypalButton.setAttribute('disabled', true);
console.log('Got a nonce! You should submit this to your server.');
console.log(payload.nonce);
$.ajax({
url: '/subscription',
type: 'post',
data: {
nonce: payload.nonce,
payload: payload
},
success: function (response) {
console.log(response);
},
error: function (response, status, err) {
}
});
});
}, false);
});
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '16px',
'font-family': 'roboto, verdana, sans-serif',
'font-weight': 'lighter',
'color': 'black'
},
':focus': {
'color': 'black'
},
'.valid': {
'color': 'black'
},
'.invalid': {
'color': 'red'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '1111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '111'
},
expirationDate: {
selector: '#expiration-date',
placeholder: 'MM/YY'
},
}
}, function (err, hostedFieldsInstance) {
if (err) {
console.error(err);
return;
}
hostedFieldsInstance.on('focus', function (event) {
var field = event.fields[event.emittedBy];
$(field.container).next('.hosted-field--label').addClass('label-float').removeClass('filled');
});
hostedFieldsInstance.on('blur', function (event) {
var field = event.fields[event.emittedBy];
if (field.isEmpty) {
$(field.container).next('.hosted-field--label').removeClass('label-float');
} else if (event.isValid) {
$(field.container).next('.hosted-field--label').addClass('filled');
} else {
$(field.container).next('.hosted-field--label').addClass('invalid');
}
});
hostedFieldsInstance.on('empty', function (event) {
var field = event.fields[event.emittedBy];
$(field.container).next('.hosted-field--label').removeClass('filled').removeClass('invalid');
});
hostedFieldsInstance.on('validityChange', function (event) {
var field = event.fields[event.emittedBy];
if (field.isPotentiallyValid) {
$(field.container).next('.hosted-field--label').removeClass('invalid');
} else {
$(field.container).next('.hosted-field--label').addClass('invalid');
}
});
cardButton.removeAttribute('disabled');
$('#cardForm').submit(function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (err, payload) {
if (err) {
$('.panel__header > h1').html(err.message);
$('.panel__header').css("background", "#D50000 none repeat scroll 0 0");
return;
}
cardButton.setAttribute('disabled', true);
$('.pay-button').html("Please Wait ..");
$.ajax({
url: '/subscription',
type: 'post',
data: {
nonce: payload.nonce,
payload: payload
},
success: function (response) {
console.log(response);
},
error: function (response, status, err) {
}
});
});
});
});
});
</script>
My server side code:
public function dropin()
{
$clientToken = \Braintree_ClientToken::generate();
return view('User::user.dropui')->with("client", $clientToken);
}
public function subscription(Request $request)
{
$result = Braintree_Customer::create(array(
'email' => 'alokchaturvedi@globussoft.in',
'firstName' => 'Aloknotrail ',
'lastName' => 'Kumar',
));
if($result->success == 1){
//print_r($result->customer->id);
$resultcreate = Braintree_PaymentMethod::create([
'customerId' => $result->customer->id,
'paymentMethodNonce' => $request->nonce,
'options' => [
'failOnDuplicatePaymentMethod' => true
]
]);
if($resultcreate->success == 1){
//print_r($resultcreate->paymentMethod->token);
$resultSubscription = Braintree_Subscription::create([
'paymentMethodToken' => $resultcreate->paymentMethod->token,
'planId' => 'pro'
]);
}else{
dd($resultcreate);
}
}
dd($resultSubscription);
}
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
To create webhooks to track specific changes in subscriptions and transactions, go to the Braintree Control Panel and assign specific triggers to endpoints on your server. When an action occurs (like a transaction being settled), your endpoint will be called with the POST parameters of bt_signature
and bt_payload
. An example of creating a webhookNotification
which contains information about the event, is below:
$webhookNotification = Braintree_WebhookNotification::parse(
$_POST["bt_signature"], $_POST["bt_payload"]
);
$webhookNotification->kind;
# => "subscription_went_past_due"
$webhookNotification->timestamp;
# => Sun Jan 1 00:00:00 UTC 2016
For more information on webhooks, please check out this documentation.