我正在使用 Braintree 进行付款流程。我创建了一个订阅计划,并且在我的网站中使用 PayPal 和卡付款。我能够创建一个成功的订阅,但是我想在订阅处于活动/取消以及是否完成付款时显示获取响应。我知道这可以通过 webhook 完成,但我不知道从哪里开始。我正在使用 laravel 框架。我的客户端代码:
<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>
我的服务器端代码:
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);
}