Deprecated: Required parameter $cat_id follows optional parameter $type in /www/wwwroot/ebimall.com/systems/hong.php on line 2088

Deprecated: Required parameter $where follows optional parameter $tree_id in /www/wwwroot/ebimall.com/systems/hlb.php on line 3505
Braintree-国外支付对接(二)_葉飞纷飞的博客-CSDN博客188bio精品生物—专注于实验室精品爆款的电商平台 - 蚂蚁淘旗下精选188款生物医学科研用品
您好,欢迎您进入188进口试剂采购网网站! 服务热线:4000-520-616
蚂蚁淘商城 | 现货促销 | 科研狗 | 生物在线

Braintree-国外支付对接(二)_葉飞纷飞的博客-CSDN博客

在前文 国外支付对接 Braintree 一 的基础上   已经拿到了相关配置信息 接下来就是码代码了 这里完成的主要功能是支付与退款。

在此之前 先说一下Briantree的支付流程

    第一步先生成clientToken 一组根据 MerchantId BraintreePublicKey BraintreePrivateKey生成的字符串 用于前端生成初始化支付控件。第二步点击支付按钮客户输入用户名密码确定支付之后 Briantree在前端会返回nonce给我们 相当于支付授权凭证 。第三步 将nonce传到后台 我们进行扣款。至此支付完成。

1.项目引用

   后端 从官方下载的demo中可以看到 其实我们的后端需要用的dll就是一个 Braintree.dll NUGET上也能下载

   \"\"

     需要的就是引用官方js 这个需要看个人需求吧 如果你不想麻烦自己写样式 可以直接使用官方的js生成的支付按钮 那么用drop-in UI即可。使用drop-in是最直接便利的方式 我们在前端直接引用

 script src https://js.braintreegateway.com/web/dropin/1.9.2/js/dropin.min.js /script 

 生成的样式长这样

\"\"

     如果需要自己设计样式 按照自己的规则来控制前端的话 那就得使用Customer UI。那当然需要引用的js就不同了 前端的写法也就不同了 后面细说。这块主要的js是

 script src https://js.braintreegateway.com/web/3.29.0/js/client.min.js /script 

2.代码解析

 web.config配置

        API keys 拿到之后需要在程序中使用 我们直接配置在web.config中即可 当然安全着想也可以加密配置到数据库中。

        \"\"

   前端(这里先介绍使用drop-in UI的写法) html:
   form只需要2个参数amount,nonce。最重要的是要定义一个div控件给生成支付控件使用 这里使用的id为bt-dropin的div
 form id payment-form method post action /checkouts/Create  section  label for amount  span class input-label Amount /span  div class input-wrapper amount-wrapper  input id amount name amount type tel min 0.01 placeholder Amount value 0.01  /div  /label  div class bt-drop-in-wrapper  div id bt-dropin /div  /div  /section  input id nonce name payment_method_nonce type hidden /  button class button type submit span Test Transaction /span /button  /form 
js
 script src https://js.braintreegateway.com/web/dropin/1.9.2/js/dropin.min.js /script  script  $(function () { var client_token ViewBag.ClientToken  var form document.querySelector( #payment-form  braintree.dropin.create({//支付控件初始化开始 authorization: client_token,//由后端传过来的值 一组根据 MerchantId BraintreePublicKey BraintreePrivateKey生成的字符串 container: #bt-dropin , paypal: { flow: vault , buttonStyle: { //可以修改一点点按钮的样式 限制性很多 color: black , shape: rect , size: medium             //此处与上面的paypal设置不一样 亲么可以自己去尝试一下 不同点在哪            //paypal: {            //    flow: checkout ,            //    amount: document.querySelector( #amount ).value,            //    currency: USD             //},             card: {//此项选填 干掉也没关系 cardholderName: { required: true }, //必填的话 就会多生成一个持卡人姓名的输入框 overrides: { fields: { number: { placeholder: Card Number , cvv: { placeholder: CVV  postalCode: { placeholder: Postal Code  //threeDSecure: {//3D安全校验 选填 用于信用卡支付的时候 若改卡的持卡人在开卡的时候启用了额外的身份校验 例如密码 那么点支付的时候则会弹出一个额外的框 输入密码。 // amount: document.querySelector( #amount ).value }, function (createErr, instance) { form.addEventListener( submit , function (event) { event.preventDefault(); instance.requestPaymentMethod(function (err, payload) {//客户输入密码等之后 接收返回的结果 即nonce 支付授权凭证 if (err) { console.log( Error , err); return; // Add the nonce to the form and submit document.querySelector( #nonce ).value payload.nonce; form.submit(); /script 

      1.生成clientToken的规则有2种 根据需要来吧。

       由于braintree平台中虽然只有一个商户ID 即Merchant ID 但是确可以有多个Merchant Accounts 即收账账号 设置的界面 Account-- Merchant Account Info

  \"\"

  第一种 使用默认配置

  每个Merchant ID都会有一个default Merchant Account 所以下面的写法 就是默认将款额收到默认账户上

var config new BraintreeGateway(environment, merchantId, publicKey, privateKey) ;var gateway config.GetGateway();var clientToken gateway.ClientToken.generate();

  第二种 指另付款到某一个账号

var clientToken gateway.ClientToken.generate(new ClientTokenRequest() { MerchantAccountId TestAccount });

  2.综合

   支付功能 一共3个Action:

//生成clientToken 传到前端 用于生成支付控件public ActionResult New()      {  var gateway config.GetGateway(); //var clientToken gateway.ClientToken.generate(); var clientToken gateway.ClientToken.generate(new ClientTokenRequest() { MerchantAccountId TestAccount }); ViewBag.ClientToken clientToken; return View();//form提交 得到nonce之后 在这里进行扣款 public ActionResult Create()        {            var gateway config.GetGateway();            Decimal amount;            try            {                amount Convert.ToDecimal(Request[ amount             }            catch (FormatException e)            {                TempData[ Flash ] Error: 81503: Amount is an invalid format.                 return RedirectToAction( New             }            var nonce Request[ payment_method_nonce //得到前端传来的nonce参数            var request new TransactionRequest//新建交易请求            {                MerchantAccountId TestAccount ,//注意这里 如果你的clientToken生成的时候设置了MerchantAccountId 那么扣款的时候也必须要加上这个参数 否则是会失败的                Amount amount,                PaymentMethodNonce nonce,                Options new TransactionOptionsRequest                {                    ThreeDSecure new TransactionOptionsThreeDSecureRequest()//这里注意 如果你前端启用了3D安全 那么这里也需要启用                    {                        Required true                    },                    SubmitForSettlement true                }            };            Result Transaction result gateway.Transaction.Sale(request);//扣款            if (result.IsSuccess())//成功            {                Transaction transaction result.Target;                //transaction.Id是官方生产的此交易的唯一编号 如果要进行查询和退款的话 就必须要将此ID记录数据库.                return RedirectToAction( Show , new { id transaction.Id });            }            else if (result.Transaction ! null)            {                return RedirectToAction( Show , new { id result.Transaction.Id, mesg result.Message});            }            else            {                string errorMessages                 foreach (ValidationError error in result.Errors.DeepAll())                {                    errorMessages Error: (int)error.Code - error.Message \\n                 }                TempData[ Flash ] errorMessages;                return RedirectToAction( New3             }        }//支付结果页展示public ActionResult Show(String id, string mesg)        {            var gateway config.GetGateway();            Transaction transaction gateway.Transaction.Find(id);            if (transactionSuccessStatuses.Contains(transaction.Status))            {                //成功            }            else            {                //失败            }            ViewBag.Transaction transaction;            return View();        }

 退款:

   这里要说明下 即时客户完成了交易 已经进行了扣款 但是如果要立马退款的话 是不行的。因为braintree内部也要进行交易审核 审核过程需要时间 而且是时间不固定 可能十几分钟 可能几个小时。所以这里我们要根据当前退款的订单状态进行是退款还是作废。2种操作的过程是不一样的。退款会在briantree账户上生成退款交易单 但是作废不会 虽然2种操作最都会退款给客户。

 public ActionResult RefundTest(string trId, decimal amount) var gateway config.GetGateway(); Transaction transaction gateway.Transaction.Find(trId); if (transaction.Status TransactionStatus.SETTLED || transaction.Status TransactionStatus.SETTLING) {//交易状态为以上时 方可进行退款操作 Result Transaction result gateway.Transaction.Refund(trId, amount); if (!result.IsSuccess()) {//退款失败 //Transaction transaction result.Transaction; //if (transaction.Status TransactionStatus.SETTLEMENT_DECLINED) // //Console.WriteLine(transaction.ProcessorSettlementResponseCode); // // e.g. 4001  // //Console.WriteLine(transaction.ProcessorSettlementResponseText); // // e.g. Settlement Declined  return RedirectToAction( RefundResponce , new { msg result.Message }); else return RedirectToAction( RefundResponce , new { msg OK }); else if (transaction.Status TransactionStatus.AUTHORIZED || transaction.Status TransactionStatus.SUBMITTED_FOR_SETTLEMENT || (transaction.PaymentInstrumentType PaymentInstrumentType.PAYPAL_ACCOUNT transaction.Status TransactionStatus.SETTLEMENT_PENDING)) {//交易状态为此状态时不可退款 但是能void交易 即作废 那么就可同时退款可客户 Result Transaction result gateway.Transaction.Void(trId); if (result.IsSuccess()) return RedirectToAction( RefundResponce , new { msg transaction successfully voided }); else return RedirectToAction( RefundResponce , new { msg result.Message }); //foreach (ValidationError error in result.Errors.DeepAll()) // Console.WriteLine(error.Message); }catch(Exception ex) return RedirectToAction( RefundResponce , new { msg ex.Message }); return RedirectToAction( RefundResponce //扣款结果显示public ActionResult RefundResponce(string msg)        {            ViewBag.Mesg msg;            return View();        }

至此支付和退款功能完成。

其实还有很多需要解说和注意的地方 还是自己去多多摸索的话学到的更多。虽然都是英文的\"哭\" 可以锻炼英文的说。

关于自定义支付控件样式 即Customer UI的使用 下次再说 官方介绍 有demo 还可以自己编码测试的网站

https://developers.braintreepayments.com/guides/hosted-fields/examples/javascript/v3。


以上纯属个人独自研究成果 仅供参考 转载请注明出处

    



新闻动态
行业前沿
技术文章
最新产品

188进口试剂采购网 www.188bio.cn -中国试剂网,试剂网,化学试剂网,国药试剂,抗体公司,试剂公司,试剂盒公司,苏州试剂公司,北京化学试剂公司,天津化学试剂,试剂商城,试剂代理,流式抗体 细胞库查询 sitemap