Braintree-國(guó)外支付對(duì)接(二)

來(lái)源: CSDN
作者:葉飛紛飛
時(shí)間:2021-10-09
18823
在前文國(guó)外支付對(duì)接:Braintree(一)的基礎(chǔ)上已經(jīng)拿到了相關(guān)配置信息,接下來(lái)就是碼代碼了,這里完成的主要功能是支付與退款。

在前文 國(guó)外支付對(duì)接:Braintree(一)的基礎(chǔ)上   已經(jīng)拿到了相關(guān)配置信息,接下來(lái)就是碼代碼了,這里完成的主要功能是支付與退款。

在此之前,先說(shuō)一下Briantree的支付流程:

    第一步先生成clientToken,一組根據(jù) MerchantId,BraintreePublicKey,BraintreePrivateKey生成的字符串,用于前端生成初始化支付控件。第二步點(diǎn)擊支付按鈕客戶輸入用戶名密碼確定支付之后,Briantree在前端會(huì)返回nonce給我們(相當(dāng)于支付授權(quán)憑證)。第三步,將nonce傳到后臺(tái),我們進(jìn)行扣款。至此支付完成。

1.項(xiàng)目引用

   后端

 從官方下載的demo中可以看到,其實(shí)我們的后端需要用的dll就是一個(gè):Braintree.dll,NUGET上也能下載

20180313134438618.jpg

  前端

     需要的就是引用官方j(luò)s,這個(gè)需要看個(gè)人需求吧,如果你不想麻煩自己寫樣式,可以直接使用官方的js生成的支付按鈕,那么用drop-in UI即可。使用drop-in是最直接便利的方式,我們?cè)谇岸酥苯右茫?/p>

<script src="https://js.braintreegateway.com/web/dropin/1.9.2/js/dropin.min.js"></script>

 生成的樣式長(zhǎng)這樣:

20180313135344735.JPG

     如果需要自己設(shè)計(jì)樣式,按照自己的規(guī)則來(lái)控制前端的話,那就得使用Customer UI。那當(dāng)然需要引用的js就不同了,前端的寫法也就不同了,后面細(xì)說(shuō)。這塊主要的js是

<script src="https://js.braintreegateway.com/web/3.29.0/js/client.min.js"></script>

2.代碼解析

 web.config配置

        API keys 拿到之后需要在程序中使用,我們直接配置在web.config中即可,當(dāng)然安全著想也可以加密配置到數(shù)據(jù)庫(kù)中。

4fbc5de198566686e09921519d3ac4c4.png

   前端(這里先介紹使用drop-in UI的寫法)

 html:

   form只需要2個(gè)參數(shù)amount,nonce。最重要的是要定義一個(gè)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({//支付控件初始化開(kāi)始

            authorization: client_token,//由后端傳過(guò)來(lái)的值,一組根據(jù) MerchantId,BraintreePublicKey,BraintreePrivateKey生成的字符串

            container: '#bt-dropin',

            paypal: {

                flow: 'vault',

                buttonStyle: {  //可以修改一點(diǎn)點(diǎn)按鈕的樣式,限制性很多

                    color: 'black',

                    shape: 'rect',

                    size: 'medium'

                }

            },

            //此處與上面的paypal設(shè)置不一樣,親么可以自己去嘗試一下,不同點(diǎn)在哪

            //paypal: {

            //    flow: 'checkout',

            //    amount: document.querySelector('#amount').value,

            //    currency: 'USD'

            //}, 

            card: {//此項(xiàng)選填,干掉也沒(méi)關(guān)系

                cardholderName: { required: true }, //必填的話,就會(huì)多生成一個(gè)持卡人姓名的輸入框

                overrides: {

                    fields: {

                        number: {

                            placeholder: 'Card Number',

                        },

                        cvv: {

                            placeholder: 'CVV'

                        },

                        postalCode: {

                            placeholder: 'Postal Code'

                        }

                    },

                }

            },

            //threeDSecure: {//3D安全校驗(yàn),選填,用于信用卡支付的時(shí)候,若改卡的持卡人在開(kāi)卡的時(shí)候啟用了額外的身份校驗(yàn),例如密碼,那么點(diǎn)支付的時(shí)候則會(huì)彈出一個(gè)額外的框,輸入密碼。

            //    amount: document.querySelector('#amount').value

            //}

        }, function (createErr, instance) {

            form.addEventListener('submit', function (event) {

                event.preventDefault();

                instance.requestPaymentMethod(function (err, payload) {//客戶輸入密碼等之后,接收返回的結(jié)果,即nonce,支付授權(quán)憑證

                    if (err) {

                        console.log('Error', err);

                        return;

                    }

                    // Add the nonce to the form and submit

                    document.querySelector('#nonce').value = payload.nonce;

                    form.submit();

                });

            });

        });

    });

</script>

一組根據(jù) MerchantId,BraintreePublicKey,BraintreePrivateKey生成的字符串

            container: '#bt-dropin',

            paypal: {

                flow: 'vault',

                buttonStyle: {  //可以修改一點(diǎn)點(diǎn)按鈕的樣式,限制性很多

                    color: 'black',

                    shape: 'rect',

                    size: 'medium'

                }

            },

            //此處與上面的paypal設(shè)置不一樣,親么可以自己去嘗試一下,不同點(diǎn)在哪

            //paypal: {

            //    flow: 'checkout',

            //    amount: document.querySelector('#amount').value,

            //    currency: 'USD'

            //}, 

            card: {//此項(xiàng)選填,干掉也沒(méi)關(guān)系

                cardholderName: { required: true }, //必填的話,就會(huì)多生成一個(gè)持卡人姓名的輸入框

                overrides: {

                    fields: {

                        number: {

                            placeholder: 'Card Number',

                        },

                        cvv: {

                            placeholder: 'CVV'

                        },

                        postalCode: {

                            placeholder: 'Postal Code'

                        }

                    },

                }

            },

            //threeDSecure: {//3D安全校驗(yàn),選填,用于信用卡支付的時(shí)候,若改卡的持卡人在開(kāi)卡的時(shí)候啟用了額外的身份校驗(yàn),例如密碼,那么點(diǎn)支付的時(shí)候則會(huì)彈出一個(gè)額外的框,輸入密碼。

            //    amount: document.querySelector('#amount').value

            //}

        }, function (createErr, instance) {

            form.addEventListener('submit', function (event) {

                event.preventDefault();

                instance.requestPaymentMethod(function (err, payload) {//客戶輸入密碼等之后,接收返回的結(jié)果,即nonce,支付授權(quán)憑證

                    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的規(guī)則有2種,根據(jù)需要來(lái)吧。

       由于braintree平臺(tái)中雖然只有一個(gè)商戶ID,即Merchant ID,但是確可以有多個(gè)Merchant Accounts,即收賬賬號(hào),設(shè)置的界面:Account-->Merchant Account Info

20180313143835179.jpg

  第一種,使用默認(rèn)配置:

  每個(gè)Merchant ID都會(huì)有一個(gè)default Merchant Account,所以下面的寫法,就是默認(rèn)將款額收到默認(rèn)賬戶上

var config = new BraintreeGateway(environment, merchantId, publicKey, privateKey) ;

var gateway = config.GetGateway();

var clientToken = gateway.ClientToken.generate();

  第二種:指另付款到某一個(gè)賬號(hào)

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

  2.綜合

   支付功能:一共3個(gè)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之后,在這里進(jìn)行扣款

 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"];//得到前端傳來(lái)的nonce參數(shù)

            var request = new TransactionRequest//新建交易請(qǐng)求

            {

                MerchantAccountId = "TestAccount",//注意這里,如果你的clientToken生成的時(shí)候設(shè)置了MerchantAccountId,那么扣款的時(shí)候也必須要加上這個(gè)參數(shù),否則是會(huì)失敗的

                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是官方生產(chǎn)的此交易的唯一編號(hào),如果要進(jìn)行查詢和退款的話,就必須要將此ID記錄數(shù)據(jù)庫(kù).

                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");

            }

        }

//支付結(jié)果頁(yè)展示

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();

        }

 退款:

   這里要說(shuō)明下,即時(shí)客戶完成了交易,已經(jīng)進(jìn)行了扣款,但是如果要立馬退款的話,是不行的。因?yàn)閎raintree內(nèi)部也要進(jìn)行交易審核,審核過(guò)程需要時(shí)間,而且是時(shí)間不固定,可能十幾分鐘,可能幾個(gè)小時(shí)。所以這里我們要根據(jù)當(dāng)前退款的訂單狀態(tài)進(jìn)行是退款還是作廢。2種操作的過(guò)程是不一樣的。退款會(huì)在briantree賬戶上生成退款交易單,但是作廢不會(huì),雖然2種操作最都會(huì)退款給客戶。

 public ActionResult RefundTest(string trId, decimal amount)

        {

            var gateway = config.GetGateway();

            try

            {

                Transaction transaction = gateway.Transaction.Find(trId);

                if (transaction.Status == TransactionStatus.SETTLED || transaction.Status == TransactionStatus.SETTLING)

                {//交易狀態(tài)為以上時(shí),方可進(jìn)行退款操作

                    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))

                {//交易狀態(tài)為此狀態(tài)時(shí)不可退款,但是能void交易,即作廢,那么就可同時(shí)退款可客戶

                    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");

 }

 

//扣款結(jié)果顯示

public ActionResult RefundResponce(string msg)

        {

            ViewBag.Mesg = msg;

            return View();

        }

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


其實(shí)還有很多需要解說(shuō)和注意的地方,還是自己去多多摸索的話學(xué)到的更多。雖然都是英文的,可以鍛煉英文的說(shuō)。

關(guān)于自定義支付控件樣式,即Customer UI的使用,下篇談,官方介紹,有demo,還可以自己編碼測(cè)試的網(wǎng)站

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于CSDN,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
Paypal、Stripe、Braintree,跨境電商金流第三方支付到底用哪家?
Paypal、Stripe、Braintree,跨境電商金流第三方支付到底用哪家?
做跨境電子商務(wù)生意,電商網(wǎng)站的金流肯定是一個(gè)最大的麻煩,Paypal或是Stripe和Braintree則是國(guó)際上大家最常用的金流整合第三方支付服務(wù)商。這些金流服務(wù)大幅簡(jiǎn)化網(wǎng)站付費(fèi)過(guò)程,都讓消費(fèi)者只要填入Email、信用卡號(hào)、CVC信用卡驗(yàn)證碼就可結(jié)帳,但到底該用哪家,之間又有什么不同,這篇給大家說(shuō)分明。
Braintree
PayPal
跨境支付
2021-10-092021-10-09
iOS 接入國(guó)際支付 Stripe 和 Braintree
iOS 接入國(guó)際支付 Stripe 和 Braintree
Braintree 是 PayPal 旗下的服務(wù),所以如果要支持 PayPal 賬戶結(jié)算就只能使用 Braintree,可用單獨(dú)接入Paypal,但是單獨(dú)接入Paypal的單筆交易費(fèi)率是比Braintree高很多的。
Braintree
iOS
跨境支付
2021-10-092021-10-09
Braintree-國(guó)外支付對(duì)接(三) 之Customer UI
Braintree-國(guó)外支付對(duì)接(三) 之Customer UI
Braintree-國(guó)外支付對(duì)接(二) 中的支付按鈕的生成是braintree自帶的樣式和事件控制的,即drop-in,生成的界面我們不能過(guò)多的更改和控制。所以假如我們想要自己編寫控件,自己控制樣式,但又能正常點(diǎn)擊觸發(fā)支付等事件。那么就使用Customer UI.
Braintree
跨境支付
2021-10-092021-10-09
Braintree-國(guó)外支付對(duì)接(二)
Braintree-國(guó)外支付對(duì)接(二)
在前文國(guó)外支付對(duì)接:Braintree(一)的基礎(chǔ)上已經(jīng)拿到了相關(guān)配置信息,接下來(lái)就是碼代碼了,這里完成的主要功能是支付與退款。
Braintree
跨境支付
2021-10-092021-10-09
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪
投稿采訪
出海管家
出海管家