I am actually trying to implement braintree using Angular with asp.net core. But i am facing an issue, I don’t understand how to solve it. I am follwing this article. I am using version 14 of angular. I have doing exactly the same as mentioned article. I don’t know which authorization it is demanding. when i run the application, in the braintree UI, I failed to input Card Number ,Expiration date,CVV maybe for this error. here is my code:-
app.component.ts
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import * as braintree from 'braintree-web';
@Component({
selector: 'app-paypal',
templateUrl: './paypal.component.html',
styleUrls: ['./paypal.component.css']
})
export class PaypalComponent implements OnInit {
CToken: any;
hostedFieldsInstance: braintree.HostedFields;
cardholdersName: string;
constructor(private http: HttpClient) { }
ngOnInit(): void {
this.getToken();
this.createBraintreeUI();
}
getToken() {
this.http.get('https://localhost:5001/api/paypal').subscribe({
next: response => this.CToken = response,
error: error => console.log(error)
})
console.log(this.CToken);
}
createBraintreeUI() {
braintree.client.create({
authorization: this.CToken
}).then((clientInstance) => {
braintree.hostedFields.create({
client: clientInstance,
styles: {
// Override styles for the hosted fields
},
fields: {
number: {
selector: '#card-number',
placeholder: '1111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '111'
},
expirationDate: {
selector: '#expiration-date',
placeholder: 'MM/YY'
}
}
}).then((hostedFieldsInstance) => {
this.hostedFieldsInstance = hostedFieldsInstance;
hostedFieldsInstance.on('focus', (event) => {
const field = event.fields[event.emittedBy];
});
hostedFieldsInstance.on('blur', (event) => {
const field = event.fields[event.emittedBy];
});
hostedFieldsInstance.on('empty', (event) => {
const field = event.fields[event.emittedBy];
});
hostedFieldsInstance.on('validityChange', (event) => {
const field = event.fields[event.emittedBy];
if (field.isPotentiallyValid) {
} else {
}
});
});
});
}
// Tokenize the collected details so that they can be sent to your server
tokenizeUserDetails() {
this.hostedFieldsInstance.tokenize({cardholderName: this.cardholdersName}).then((payload) => {
console.log(payload);
console.log("Bro! this is payload!!!"+payload.nonce);
// submit payload.nonce to the server from here
}).catch((error) => {
console.log(error);
// perform custom validation here or log errors
});
}
}
app.compoment.html
<form id="cardForm">
<div class="panel">
<header class="panel__header">
<h1>Card Payment</h1>
</header>
<div class="panel__content">
<div class="textfield--float-label">
<!-- Begin hosted fields section -->
<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>
<!-- End hosted fields section -->
</div>
<div class="custom-name">
<label class="hosted-field--label" for="cardholder-name" name="cardholderName">
<span class="icon">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
</span>
Cardholder's Name</label>
<input type="text" placeholder="e.g. JOHN DOE" class="name-custom-input" [(ngModel)]="cardholdersName" name="cardholderName"/>
</div>
<div class="textfield--float-label">
<!-- Begin hosted fields section -->
<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>
<!-- End hosted fields section -->
</div>
<div class="textfield--float-label">
<!-- Begin hosted fields section -->
<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>
<!-- End hosted fields section -->
</div>
</div>
<footer class="panel__footer">
<input type="button" value="Pay" (click)="tokenizeUserDetails();" class="pay-button"/>
</footer>
</div>
</form>
Backend
[Produces("application/json")]
...
[HttpGet]
public async Task<string> client_token()
{
var gateway = _braintreeService.GetGateway();
var clientToken = gateway.ClientToken.generate();
return clientToken;
}
here is my error in console
ERROR Error: Uncaught (in promise): BraintreeError: options.authorization is required when instantiating a client.
Angular 16
4431 main.ts:11
Webpack 7
__webpack_require__
__webpack_exec__
<anonymous>
O
<anonymous>
webpackJsonpCallback
<anonymous>
core.js:6498
Angular 3
RxJS 5
Angular 18
4431 main.ts:11
Webpack 7
I am a beginner. how to resolve this issue. or any alternative implementation? please help.
2
Answers
Check order of asynchronous requests.
It appears you’re not including your Braintree token in your request.
This is likely happening because you’re making one asynchronous request before another completes.
A simple way to fix this would be to move the call to
this.createBraintreeUI()
inside the response to you token request. That way you would only make the second request after the first completes.Something like this:
There may be more issues, as this is a complex integration with Braintree, but if you check that
console.log()
statement you have and it’s showing your token, and the token looks correct, then you’re on the right path.(For instance, you might have another problem where you can’t pass
authorization: this.CToken
there in the first line of yourthis.createBraintreeUI()
function. You might have to setauthorization
to a property ofthis.CToken
. So look at the console.log statement showing your token and see if it looks correct. )https://i.stack.imgur.com/2vyw6.png
First I use
Fix
https://i.stack.imgur.com/to6tV.png
Second Way
check condition inside and write on
Example: