Braintree Payment - ASP.Net Core2.1





5.00/5 (5 votes)
In this post, we are going to implement braintree payment gateway with ASP.NET Core 2.1
Introduction
Based on the previous post, this article is extended to implement payment gateway. We are going to modify/extend the existing sample application by downloading the full source code from github.
Let’s get started by opening the existing application, first of all, we are going to add Braintree package. Go to NuGet to install Braintree .NET Client Library which is supported by both .NET Framework, .NET Core.
Configuration: This is where we configured the environment, merchant with API key for Braintree.
public class BraintreeConfiguration : IBraintreeConfiguration
{
public string Environment { get; set; }
public string MerchantId { get; set; }
public string PublicKey { get; set; }
public string PrivateKey { get; set; }
private IBraintreeGateway BraintreeGateway { get; set; }
public IBraintreeGateway CreateGateway()
{
Environment = System.Environment.GetEnvironmentVariable("BraintreeEnvironment");
MerchantId = System.Environment.GetEnvironmentVariable("BraintreeMerchantId");
PublicKey = System.Environment.GetEnvironmentVariable("BraintreePublicKey");
PrivateKey = System.Environment.GetEnvironmentVariable("BraintreePrivateKey");
if (MerchantId == null || PublicKey == null || PrivateKey == null)
{
Environment = "sandbox";
MerchantId = "9j4ynyf697k9685t";
PublicKey = "25sy94dv3rqgg355";
PrivateKey = "b0d5e1b1fa9dc24c263a3e83a148a7b3";
}
return new BraintreeGateway(Environment, MerchantId, PublicKey, PrivateKey);
}
public IBraintreeGateway GetGateway()
{
if (BraintreeGateway == null)
{
BraintreeGateway = CreateGateway();
}
return BraintreeGateway;
}
}
Payments Controller
Generate Client-Token: Initially, HttpGet
method named GenerateToken
gets called to generate client-token for authorization to initialize client UI.
[HttpGet, Route("GenerateToken")]
public object GenerateToken()
{
var gateway = config.GetGateway();
var clientToken = gateway.ClientToken.Generate();
return clientToken;
}
Create Transaction: Finally, transaction is done with Amount
and PaymentMethodNonce
which is payment authorization for customer generated by client script.
[HttpPost, Route("Checkout")]
public object Checkout(vmCheckout model)
{
string paymentStatus = string.Empty;
var gateway = config.GetGateway();
var request = new TransactionRequest
{
Amount = model.Price,
PaymentMethodNonce = model.PaymentMethodNonce,
Options = new TransactionOptionsRequest
{
SubmitForSettlement = true
}
};
Result<Transaction> result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
paymentStatus = "Succeded";
//Do Database Operations Here
}
else
{
string errorMessages = "";
foreach (ValidationError error in result.Errors.DeepAll())
{
errorMessages += "Error: " + (int)error.Code + " - " + error.Message + "\n";
}
paymentStatus = errorMessages;
}
return paymentStatus;
}
Finally, the full Payments Controller.
[ApiController, Route("api/[controller]"), Produces("application/json")]
public class PaymentsController : ControllerBase
{
public IBraintreeConfiguration config = new BraintreeConfiguration();
public static readonly TransactionStatus[] transactionSuccessStatuses =
{
TransactionStatus.AUTHORIZED,
TransactionStatus.AUTHORIZING,
TransactionStatus.SETTLED,
TransactionStatus.SETTLING,
TransactionStatus.SETTLEMENT_CONFIRMED,
TransactionStatus.SETTLEMENT_PENDING,
TransactionStatus.SUBMITTED_FOR_SETTLEMENT
};
[HttpGet, Route("GenerateToken")]
public object GenerateToken()
{
var gateway = config.GetGateway();
var clientToken = gateway.ClientToken.Generate();
return clientToken;
}
[HttpPost, Route("Checkout")]
public object Checkout(vmCheckout model)
{
string paymentStatus = string.Empty;
var gateway = config.GetGateway();
var request = new TransactionRequest
{
Amount = model.Price,
PaymentMethodNonce = model.PaymentMethodNonce,
Options = new TransactionOptionsRequest
{
SubmitForSettlement = true
}
};
Result<Transaction> result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
paymentStatus = "Succeded";
//Do Database Operations Here
}
else
{
string errorMessages = "";
foreach (ValidationError error in result.Errors.DeepAll())
{
errorMessages += "Error: " + (int)error.Code + " - " + error.Message + "\n";
}
paymentStatus = errorMessages;
}
return paymentStatus;
}
}
HTML View
In index.html, we need to add drop-in library reference.
<script src="//js.braintreegateway.com/web/dropin/1.9.4/js/dropin.min.js"
type="text/javascript"></script>
The below code snippet is where(<div id="dropin"></div>
) to render Drop-in UI in payment.html where user can input card information. After providing valid card information, checkout action is performed by clicking on Checkout button.
<div class="container-fluid"> <div class="row"> <h3> {{title}} - {{cartmodel.Price}}$</h3> <div id="dropin"></div> <button type="submit" id="checkout" class="btn btn-sm btn-success button"> Checkout <i class="fa fa-shopping-cart"></i> </button> <h5>{{paymentresult}}</h5> </div> </div>
AngularJS Controller
Get client token: To create dropin UI, we need to provide client-token generated by server for authorization.
//Generate View
braintree.dropin.create({
authorization: client_token,
container: '#dropin',
card: {
overrides: {
styles: {
input: {
color: 'blue',
'font-size': '18px'
},
'.number': {
'font-family': 'monospace'
},
'.invalid': {
color: 'red'
}
},
fields: {
number: {
//placeholder: 'Card Number',
formatInput: true // Turn off automatic formatting
}
}
}
}
}, function (createErr, instance) {
});
Request Payment Method: This is where client requests for payment method information(PaymentMethodNonce
), later PaymentMethodNonce
will use in server to charge a card.
//Checkout Submit
document.getElementById("checkout").addEventListener('click', function () {
//event.preventDefault();
instance.requestPaymentMethod(function (err, payload) {
if (err) {
console.log('Error', err);
return;
}
//Token Braintree
$scope.cartmodel.PaymentMethodNonce = payload.nonce;
$scope.checkOut();
});
});
Finally, the full Client Script.
templatingApp.controller('PaymentController', ['$scope', '$http', function ($scope, $http) {
$scope.title = "Braintree Payment";
$scope.paymentresult = null;
$scope.cartmodel = {
FirstName: "Shashangka",
LastName: "LastName",
Email: "shashangka@gmail.com",
Street: "Bejpara, Jessore",
Price: 50
};
//Generate Token PaymentGateway
PaymentGateway();
function PaymentGateway() {
$http({
method: 'GET',
url: '/api/Payments/GenerateToken'
}).then(function successCallback(response) {
//console.log(response.data);
var client_token = response.data;
//Generate View
braintree.dropin.create({
authorization: client_token,
container: '#dropin',
card: {
overrides: {
styles: {
input: {
color: 'blue',
'font-size': '18px'
},
'.number': {
'font-family': 'monospace'
},
'.invalid': {
color: 'red'
}
},
fields: {
number: {
//placeholder: 'Card Number',
formatInput: true // Turn off automatic formatting
}
}
}
}
}, function (createErr, instance) {
//Checkout Submit
document.getElementById("checkout").addEventListener('click', function () {
//event.preventDefault();
instance.requestPaymentMethod(function (err, payload) {
if (err) {
console.log('Error', err);
return;
}
//Token Braintree
$scope.cartmodel.PaymentMethodNonce = payload.nonce;
$scope.checkOut();
});
});
});
}, function errorCallback(response) {
console.log(response);
});
};
//CheckOut
$scope.checkOut = function () {
console.log($scope.cartmodel);
$http({
method: 'POST',
url: '/api/Payments/Checkout',
data: $scope.cartmodel
}).then(function successCallback(response) {
console.log(response.data);
$scope.paymentresult = response.data;
}, function errorCallback(response) {
console.log(response);
});
};
}]);
Testing: Ready-made payment Drop-in UI, Test Card No: 378282246310005 or 4111111111111111
After a successful transaction, the below screen will appear:
Braintree: As we can see, the list of transactions in Braintree.
Hope this will help, thanks for reading! 🙂