【问题标题】:Passing Braintree nonce to ruby on rails controller在 Rails 控制器上将 Braintree nonce 传递给 ruby
【发布时间】:2016-11-29 21:01:18
【问题描述】:

我目前正在使用 Braintree 托管字段,将信用卡嵌入到我的应用程序中。我正在研究如何将付款随机数从视图传递到控制器。我拥有的 javascript 似乎正在触发 Braintree api 并向我的警报返回一个随机数,但我现在只需要将它推送到控制器以执行最后一段代码

在我拥有的控制器创建方法中

def create
    result = Braintree::PaymentMethod.create(
        :customer_id => current_user.customer_cim_id,
        :payment_method_nonce => nonce_from_the_client,
        :cardholder_name => "#{current_user.first_name} #{current_user.last_name}",
        :options => {
            :make_default => true,
            :fail_on_duplicate_payment_method => true
        }
    )

新视图

- title t('.title')
= form_for(@payment_method, :url => myaccount_payment_methods_path(@payment_method), :html => {:id => 'cardForm'}) do |f|
  = render :partial => 'form', :locals => {:f => f}
/ Load Hosted Fields component.
%script{:src => '//js.braintreegateway.com/web/3.0.0-beta.10/js/hosted-fields.min.js'}

表单视图

.mdl-grid
  .panel
    %header.panel__header
      %h1 Card Payment
    .panel__content
      .textfield--float-label
        %label.hosted-field--label{:for => "card-number"}
          %i.material-icons credit_card
          Card Number
        #card-number.hosted-field
      .textfield--float-label
        %label.hosted-field--label{:for => "expiration-date"}
          %i.material-icons date_range
          Expiration Date
        #expiration-date.hosted-field
      .textfield--float-label
        %label.hosted-field--label{:for => "cvv"}
          %i.material-icons lock
          CVV
        #cvv.hosted-field
    %footer.panel__footer
      = f.submit class: 'pay-button', id: 'button-pay', disabled: true

应用程序.js

var form = document.querySelector('#cardForm');
var submit = document.querySelector('input[type="submit"]');

braintree.client.create({
    authorization: 'sandbox_92dswc7q_mbmb637xwpzgxbrd'
}, function (err, clientInstance) {
    if (err) {
        console.error(err);
        return;
    }

    // Create input fields and add text styles
    braintree.hostedFields.create({
        client: clientInstance,
        styles: {
            'input': {
                'color': '#282c37',
                'font-size': '16px',
                'transition': 'color 0.1s',
                'line-height': '3'
            },
            // Style the text of an invalid input
            'input.invalid': {
                'color': '#E53A40'
            },
            // placeholder styles need to be individually adjusted
            '::-webkit-input-placeholder': {
                'color': 'rgba(0,0,0,0.6)'
            },
            ':-moz-placeholder': {
                'color': 'rgba(0,0,0,0.6)'
            },
            '::-moz-placeholder': {
                'color': 'rgba(0,0,0,0.6)'
            },
            ':-ms-input-placeholder ': {
                'color': 'rgba(0,0,0,0.6)'
            }

        },
        // Add information for individual fields
        fields: {
            number: {
                selector: '#card-number',
                placeholder: '1111 1111 1111 1111'
            },
            cvv: {
                selector: '#cvv',
                placeholder: '123'
            },
            expirationDate: {
                selector: '#expiration-date',
                placeholder: '10 / 2019'
            }
        }
    }, function (err, hostedFieldsInstance) {
        if (err) {
            console.error(err);
            return;
        }

        hostedFieldsInstance.on('validityChange', function (event) {
            // Check if all fields are valid, then show submit button
            var formValid = Object.keys(event.fields).every(function (key) {
                return event.fields[key].isValid;
            });

            if (formValid) {
                $('.pay-button').prop("disabled", false);
            } else {
                $('.pay-button').prop("disabled", true);
            }
        });

        hostedFieldsInstance.on('empty', function (event) {
            $('header').removeClass('header-slide');
            $('#card-image').removeClass();
            $(form).removeClass();
        });

        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.setPlaceholder('cvv', '1234');
                }
            } else {
                hostedFieldsInstance.setPlaceholder('cvv', '123');
            }
        });

        submit.addEventListener('click', function (event) {
            event.preventDefault();

            hostedFieldsInstance.tokenize(function (err, payload) {
                if (err) {
                    console.error(err);
                    return;
                }

                // This is where you would submit payload.nonce to your server
                alert('Got a nonce: ' + payload.nonce);
                // If this was a real integration, this is where you would
                // send the nonce to your server.
                console.log('Got a nonce: ' + payload.nonce);
            });
        }, false);
    });
});

【问题讨论】:

    标签: ruby-on-rails controller braintree braintree-rails


    【解决方案1】:

    全面披露:我在 Braintree 工作。如果您还有任何问题,请随时联系support

    在 application.js 中的 alert 行之后,您需要向您的服务器发送一个包含付款方式 nonce 的请求。例如,您可以使用 Ajax 执行此操作:

    $.ajax({ type: "POST", url: your_payment_url, data: {"payment_method_nonce":payload.nonce} });

    然后在您的 Ruby on Rails 控制器中,您可以使用请求中的付款方式 nonce 调用 Transaction.sale 以完成交易。 有关托管字段的更多信息,请查看此link

    编辑保险柜问题:

    如果您使用保险柜,您可以向用户收费,而无需每次都支付随机数。创建客户后(通过控制面板或Customer.create,您可以直接通过Customer 对象的payment_methods 属性检索payment_method_token。稍后要向用户收费,请在您的服务器上检索他们的payment_method_token 并调用Transaction.sale ,传入payment_method_token

    result = Braintree::Transaction.sale(
      :amount => "your_amount",
      :payment_method_token => "payment_method_token"
    )
    

    【讨论】:

    • 如果我们将客户存储在保险库中,这将如何工作,因为每次他们想要交易时我们都需要获得一个新的随机数,不是吗?
    • 在我的回答中添加了对您问题的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多