在现代电子商务中,集成一个安全、可靠的支付网关是至关重要的。本文将指导如何在现有的应用程序中集成Braintree支付网关。将从下载完整的源代码开始,然后逐步进行修改和扩展。
首先,需要从GitHub下载现有应用程序的完整源代码。这将为提供一个基础,可以在此基础上进行修改和扩展。
接下来,将添加Braintree包。将使用NuGet来安装Braintree .NET客户端库,该库支持.NET Framework和.NET Core。
在配置环境中,需要设置环境、商家ID以及API密钥。以下是C#代码示例:
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;
}
}
在支付控制器中,将创建一个名为GenerateToken的HttpGet方法,用于生成客户端令牌,以便初始化客户端UI。以下是JavaScript代码示例:
[HttpGet, Route("GenerateToken")]
public object GenerateToken()
{
var gateway = config.GetGateway();
var clientToken = gateway.ClientToken.Generate();
return clientToken;
}
最后,将处理交易。交易将使用金额和支付方法一次性完成,这是由客户端脚本生成的。以下是JavaScript代码示例:
[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 result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
paymentStatus = "Succeeded";
// 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;
}
以下是完整的支付控制器代码:
[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 result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
paymentStatus = "Succeeded";
// 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;
}
}
在index.html中,需要添加drop-in库的引用。以下是HTML代码示例:
<script src="https://js.braintreegateway.com/web/dropin/1.9.4/js/dropin.min.js" type="text/javascript"></script>
在payment.html中,将渲染Drop-in UI,用户可以在此输入卡信息。提供有效的卡信息后,用户可以通过点击结账按钮来执行结账操作。以下是HTML代码示例:
<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>
为了创建dropin UI,需要提供由服务器生成的客户端令牌,以便进行授权。以下是JavaScript代码示例:
// 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;
}
$scope.cartmodel.PaymentMethodNonce = payload.nonce;
$scope.checkOut();
});
});
});
以下是完整的客户端脚本代码:
angular.module('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
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;
}
$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);
});
};
}]);