Braintree-国外支付对接(三) 之Customer UI

前篇:Braintree-国外支付对接(二) 中的支付按钮的生成是braintree自带的样式和事件控制的,即drop-in,生成的界面我们不能过多的更改和控制。所以假如我们想要自己编写控件,自己控制样式,但又能正常点击触发支付等事件。那么就使用Customer UI.

使用Customer UI需要映入的官方JS有很大不同,但是我们的后端是不需要变的,因为提交的参数和返回的参数是一样的。下面给出的例子,没有过多的写的样式很漂亮华丽,简单点:

<div class="wrapper">

    <div class="checkout container">

        <header>

            <h1>Hi,

                <br>

                Let"s test a transaction</h1>

            <p>

                Make a test payment with Braintree using PayPal or a card

            </p>

        </header>

 

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

 

                <fieldset>

                    <legend>Card</legend>

 

                    <div class="cardinfo-card-number">

                      <label class="cardinfo-label" for="cc-number">Card Number</label>

                      <div class="input-wrapper" id="cc-number"></div>

                      <div id="card-image"></div>

                    </div>

 

                    <div class="cardinfo-card-number">

                      <label class="cardinfo-label" for="cc-number">CVV</label>

                      <div class="input-wrapper" id="cc-cvv"></div>

                    </div>

 

                     <div class="cardinfo-card-number">

                      <label class="cardinfo-label" for="cc-expiration-date">Expiration-Date</label>

                      <div class="input-wrapper" id="cc-expiration-date"></div>

                    </div>     

                    <button style="margin-top: 10px; background-color: pink;" class="button" id="card-button" type="button"><span style="padding: 0.7em 1em">Done</span></button>

                </fieldset>

                <fieldset>

                    <legend>Paypal</legend>

                    <button style="margin-top: 10px; background-color: pink;" class="button" disabled id="paypal-button" type="button"><span>Paypal</span></button>

                    <span id="payer"></span>

                </fieldset>

            </section>

 

            <input id="nonce" name="payment_method_nonce" type="hidden" />

            <button class="button" type="submit"><span>Test Transaction</span></button>

        </form>

    </div>

</div>

 

<style>

    .cardinfo-card-number {position: relative;}

    .cardinfo-label {

  display: block;

  font-size: 11px;

  margin-bottom: 0.5em;

  text-transform: uppercase;

}

    .input-wrapper {

  border-radius: 2px;

  background: rgba(255, 255, 255, 0.86);

  height: 2.75em;

  border: 1px solid #eee;

  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);

          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);

  padding: 5px 10px;

  margin-bottom: 1em;

}

    #card-image

    {

        position: absolute;

        top: 36px;

        right: 0px;

        width: 44px;

        height: 28px;

        background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/346994/card_sprite.png);

        background-size: 86px 458px;

        border-radius: 4px;

        background-position: -100px 0;

        background-repeat: no-repeat;

        margin-bottom: 1em;

    }

 

        #card-image.visa

        {

            background-position: 0 -398px;

        }

 

        #card-image.master-card

        {

            background-position: 0 -281px;

        }

 

        #card-image.american-express

        {

            background-position: 0 -370px;

        }

 

        #card-image.discover

        {

            background-position: 0 -163px;

        }

 

        #card-image.maestro

        {

            background-position: 0 -251px;

        }

 

        #card-image.jcb

        {

            background-position: 0 -221px;

        }

 

        #card-image.diners-club

        {

            background-position: 0 -133px;

        }

</style>

<script src="/App_Themes/javascript/vendor/jquery-2.1.4.min.js"></script>

 

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

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

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

<script src="https://js.braintreegateway.com/web/3.29.0/js/paypal-checkout.js"></script>

<script src="https://js.braintreegateway.com/web/3.29.0/js/three-d-secure.js"></script>

 

<script>

    $(function () {

        var client_token = "@ViewBag.ClientToken";

        var paypalButton = document.querySelector("#paypal-button");

        var cardButton = document.querySelector("#card-button");

 

        braintree.client.create({

            authorization: client_token  

        }, function (clientErr, clientInstance) {  //****

            if (clientErr) {

                //console.error("Error creating client:", clientErr);

                return;

            }

 

            //paypal支付

            braintree.paypal.create({

                client: clientInstance  //****

            }, function (paypalErr, paypalInstance) {

                if (paypalErr) {

                    console.error("Error creating PayPal:", paypalErr);

                    return;

                }

                paypalButton.removeAttribute("disabled");

                paypalButton.addEventListener("click", function (event) {

                    // Because tokenization opens a popup, this has to be called as a result of

                    // customer action, like clicking a button. You cannot call this at any time.

                    paypalInstance.tokenize({

                        flow: "checkout",

                        amount: document.querySelector("#amount").value,

                        currency: "USD"

                        // For more tokenization options, see the full PayPal tokenization documentation

                        // http://braintree.github.io/braintree-web/current/PayPal.html#tokenize

                    }, function (tokenizeErr, payload) {

                        if (tokenizeErr) {

                            if (tokenizeErr.type !== "CUSTOMER") {

                                console.log("Error tokenizing:", tokenizeErr);

                            }

                            return;

                        }

                        // Tokenization succeeded

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

                        $("#payer").html(payload.details.email);

                        paypalButton.firstChild.innerHTML = "switch account";

                        console.log("Paypal Got nonce:", payload.nonce);

                    });

                }, false);

            });

 

 

            ///信用卡支付

            // Create input fields and add text styles  

            braintree.hostedFields.create({

                client: clientInstance,  //****

                // Add information for individual fields

                fields: {

                    number: {

                        selector: "#cc-number",

                        placeholder: "1111 1111 1111 1111"

                    },

                    cvv: {

                        selector: "#cc-cvv",

                        placeholder: "123"

                    },

                    expirationDate: {

                        selector: "#cc-expiration-date",

                        placeholder: "10 / 2019"

                    }

                }

            }, function (err, hostedFieldsInstance) {

                if (err) {

                    console.log(err);

                    return;

                }

 

                hostedFieldsInstance.on("cardTypeChange", function (event) {

                    // Change card bg depending on card type

                    if (event.cards.length === 1) {

                        //$(form).removeClass().addClass(event.cards[0].type);

                        $("#card-image").removeClass().addClass(event.cards[0].type);

                        //$("header").addClass("header-slide");

 

                        // Change the CVV length for AmericanExpress cards

                        if (event.cards[0].code.size === 4) {

                            hostedFieldsInstance.setAttribute({

                                field: "cvv",

                                attribute: "placeholder",

                                value: "1234"

                            });

                        }

                    } else {

                        hostedFieldsInstance.setAttribute({

                            field: "cvv",

                            attribute: "placeholder",

                            value: "123"

                        });

                    }

                });

 

                cardButton.addEventListener("click", function (event) {

                    event.preventDefault();

                    hostedFieldsInstance.tokenize(function (err, payload) {

                        if (err) {

                            console.log(err);

                            return;

                        }

 

                        var a = payload.details.cardType;

                        var b = payload.details.lastFour;

                        //document.querySelector("#nonce").value = payload.nonce;

                        // This is where you would submit payload.nonce to your server

                        var my3DSContainer;

                        braintree.threeDSecure.create({

                            client: clientInstance

                        }, function (threeDSecureErr, threeDSecure) {

                            if (threeDSecureErr) {

                                console.log("Error creating 3DSecure" + threeDSecureErr);

                                return;

                            }

                            else{

                                threeDSecure.verifyCard({

                                    nonce: payload.nonce,

                                    amount: document.querySelector("#amount").value,

                                    addFrame: function (err, iframe) {

                                        // Set up your UI and add the iframe.

                                        my3DSContainer = document.createElement("div");

                                        my3DSContainer.appendChild(iframe);

                                        document.body.appendChild(my3DSContainer);

                                    },

                                    removeFrame: function () {

                                        //Remove UI that you added in addFrame.

                                        document.body.removeChild(my3DSContainer);

                                    }

                                }, function (err, thpayload) {

                                    if (err) {

                                        console.log(err);

                                        return;

                                    }

                                    //hostedFieldsInstance.clear("number");

                                    //hostedFieldsInstance.clear("cvv");

                                    //hostedFieldsInstance.clear("expirationDate");

                                    debugger;

                                    if (thpayload.liabilityShiftPossible) {

                                        if (thpayload.liabilityShifted) {

                                            //Liablity has shifted

                                            //submitNonceToServer(payload.nonce);

                                            document.querySelector("#nonce").value = thpayload.nonce;

                                            console.log("Card Got nonce:", thpayload.nonce);

 

                                        } else {

                                            console.log("Invalid Card!");

                                        }

                                    } else {

                                        document.querySelector("#nonce").value = thpayload.nonce;

                                        console.log("No3D nonce:", thpayload.nonce);

                                    }

                                });

                            }

                        });

 

                    });

                }, false);

            });

 

        });

    });

</script>

界面效果:

20180322133748501.JPG

paypal和信用卡的初始化方法是不一样的,信用卡的稍微复杂点。它们所依赖的js也是不一样的。

这里要注意,所有引入的braintree官方的js的版本必须要一致,原因嘛,你去改下版本试下就知道了。版本不一致的话,paypal支付或者信用卡支付的时候官方会返回错误给我们,提示就是必须引入的client.min.js版本和paypal-checkout.js或者其他的js要一致。你用到哪种支付的时候,就会提示你要与哪种支付所依赖的js版本要一致。

client.min.js

         这是第一个要引入的,客户端支付控件初始化,其他支付方式的初始化都是依赖于braintree.client.create()返回的clientInstance作为参数去初始化的。代码中注释了*的地方。

    2. hosted-fields.min.js

           这是将信用卡支付中的输入框控件(卡号,CVV等)标记为信用卡支付时校验的字段,标记了之后我们就拿不到其客户真正输入的值,且一切相应的判断(比如卡号,CVV的正确性,必填性)这些就都不需要我们自己来控制。其外最重要的,不可让商城拿到客户的卡信息这是为了保护客户的财产泄露,引发商家的承担不必要的责任。入正式的时候需要进行PCI安全验证,这点上就很能让你通过了。

    3. paypal-checkout.js

           这是paypal支付需要的,braintree.paypal.create()。这个很简单的。

    4.three-d-secure.js

           3D安全校验需要的,这个东西启用的主要原因就是 为支付减少风险。也为商家转移责任。

参考资料:

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

我们是设计师、工程师、梦想者,是您扬帆出海的私人顾问专家


相关内容:
[亚马逊开店深圳办事处地址在哪里]
[亚马逊开店深圳办事处地址在哪里]
亚马逊开店深圳办事处地址揭秘:一站式开店服务,轻松拥抱财富!各位亲爱的创业者们,你们好!今天要给大家带来一个好消息——亚马逊开店深圳办事处地址终于揭开了神秘面纱!在这里,
亚马逊开店卖翡翠怎么样?
亚马逊开店卖翡翠怎么样?
亚马逊开店卖翡翠:珠宝行业的巨大商机等你来挖掘!在炎热的夏季,一杯清凉的饮料、一本好书和一个精美的翡翠饰品,想必是很多人的首选。翡翠作为中国传统文化中的瑰宝之一,以其晶莹

TG客服:@SSjiejie — 官方频道:@SSwangluo

三生网络 © 2009-2023 超15年出海经验,跨境项目专家