Braintree-国外支付对接(二)

版权声明:以上纯属个人独自研究成果,仅供参考,转载请注明出处 https://blog.csdn.net/u012847695/article/details/79652693

前篇: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>

界面效果:

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

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

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

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


猜你喜欢

转载自blog.csdn.net/u012847695/article/details/79652693
今日推荐