Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Braintree Payment - ASP.Net Core2.1

0.00/5 (No votes)
16 Aug 2018 1  
In this post, we are going to implement braintree payment gateway with Asp.net Core 2.1

Introduction

Based on previous post this article is extended to implement payment gateway. We are going to modify/extend existing sample application by downloading 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 get 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>

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 request 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 successful transaction below screen will appear.

Braintree: As we can see the list of transaction in Braintree.  

Hope this will help, Thanks 🙂

References:

  • https://developers.braintreepayments.com/start/hello-client/javascript/v3
  • https://developers.braintreepayments.com/start/hello-server/dotnet
  • https://github.com/braintree/braintree_aspnet_example

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here