Click here to Skip to main content
13,704,859 members
Click here to Skip to main content
Add your own
alternative version

Stats

3.2K views
49 downloads
9 bookmarked
Posted 16 Aug 2018
Licenced CPOL

Braintree Payment - ASP.Net Core2.1

, 16 Aug 2018
Rate this:
Please Sign up or sign in to vote.
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! 🙂

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Shashangka Shekhar
Architect OnAir International Ltd
Bangladesh Bangladesh
Hi, I am Shashangka Shekhar,

Working with Microsoft Technologies. Since March 2011, it was my first step to working with Microsoft Technologies, achieved bachelor’s degree on Computer Science from State University of Bangladesh(Dhaka). Have 6+ years of professional experience, currently working as Software Architect at OnAir International Ltd.

I believe in desire of learning & also love to be a part of .Net Community by sharing knowledge’s.

You may also be interested in...

Comments and Discussions

 
PraiseNice Article Pin
Sarathlal Saseendran17-Aug-18 11:19
memberSarathlal Saseendran17-Aug-18 11:19 
GeneralRe: Nice Article Pin
Shashangka Shekhar17-Aug-18 18:57
professionalShashangka Shekhar17-Aug-18 18:57 
GeneralMy vote of 5 Pin
Hyland Computer Systems17-Aug-18 9:23
memberHyland Computer Systems17-Aug-18 9:23 
GeneralRe: My vote of 5 Pin
Shashangka Shekhar17-Aug-18 18:56
professionalShashangka Shekhar17-Aug-18 18:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04-2016 | 2.8.180920.1 | Last Updated 16 Aug 2018
Article Copyright 2018 by Shashangka Shekhar
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid