Symfony 4 - Настройка формы Braintree

Пытаюсь настроить Braintree Drop в пользовательском интерфейсе в моем приложении Symfony 4. (https://developers.braintreepayments.com/start/hello-client/javascript/v3, https://developers.braintreepayments.com/start/hello-server/php)

Я создал сервис:

namespace App\Services;

use Braintree\ClientToken;
use Braintree\Configuration;

class Braintree

{
    // environment variables:
    const ENVIRONMENT = 'BRAINTREE_ENVIRONMENT';
    const MERCHANT_ID = 'BRAINTREE_MERCHANT_ID';
    const PUBLIC_KEY = 'BRAINTREE_PUBLIC_KEY';
    const PRIVATE_KEY = 'BRAINTREE_PRIVATE_KEY';
    function __construct() {
        Configuration::environment(getenv(self::ENVIRONMENT));
        Configuration::merchantId(getenv(self::MERCHANT_ID));
        Configuration::publicKey(getenv(self::PUBLIC_KEY));
        Configuration::privateKey(getenv(self::PRIVATE_KEY));
    }
    //
    public function generateNonce() {
        return ClientToken::generate();
    }
}

и я добавил форму и некоторый javascript в свой шаблон веточки:

{% block body %}
    {{ parent() }}

    <div class = "container">
        <div class = "card">
            <div class = "row">
                <div class = "col-12">
                    <h3>Booking New</h3>

                    <div id = "datepicker"></div>

                    {{ form_start(bookingForm) }}
                        {{ form_widget(bookingForm) }}

                        <button type = "submit" class = "btn btn-primary">Create</button>
                    {{ form_end(bookingForm) }}

                </div>
            </div>
            <div class = "row">
                <div class = "col-12">
                    <form method = "post" id = "payment-form">
                        <section>
                            <label for = "amount">
                                <span class = "input-label">Amount</span>
                                <div class = "input-wrapper amount-wrapper">
                                    <input id = "amount" name = "amount" type = "tel" min = "1" placeholder = "Amount" value = "10">
                                </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>
                    <button id = "submit-button">Request payment method</button>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script src = "https://js.braintreegateway.com/web/dropin/1.14.1/js/dropin.min.js"></script>
    <script src = "https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src = "https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script>
      var form = document.querySelector('#payment-form');
      var client_token = "<?php echo($gateway->ClientToken()->generate()); ?>";
      braintree.dropin.create({
        authorization: client_token,
        selector: '#bt-dropin',
        paypal: {
          flow: 'vault'
        }
      }, function (createErr, instance) {
        if (createErr) {
          console.info('Create Error', createErr);
          return;
        }
        form.addEventListener('submit', function (event) {
          event.preventDefault();
          instance.requestPaymentMethod(function (err, payload) {
            if (err) {
              console.info('Request Payment Method Error', err);
              return;
            }
            // Add the nonce to the form and submit
            document.querySelector('#nonce').value = payload.nonce;
            form.submit();
          });
        });
      });
    </script>
    <script>
      $( function() {
        $( "#datepicker" ).datepicker();
      } );
    </script>
{% endblock %}

Когда я загружаю страницу, она не отображает форму Braintree, как я ожидал от braintree.dropin.create. Когда я нажимаю "Отправить", тоже ничего не происходит.

Как мне правильно настроить этот код?

Редактировать:

Проверил консоль:

Create Error 
r
message: "There was an error creating Drop-in."
name: "DropinError"
_braintreeWebError: n {name: "BraintreeError", code: "CLIENT_INVALID_AUTHORIZATION", message: "Authorization is invalid. Make sure your client token or tokenization key is valid.", type: "MERCHANT", details: undefined}
__proto__: Error

Есть ли что-нибудь в вашей консоли javascript, когда вы пытаетесь отобразить форму?

Domagoj 05.01.2019 01:43

Да, я добавил ошибку из консоли в OP.

TimothyAURA 05.01.2019 05:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
407
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из вашей ошибки консоли я могу сделать вывод, что эта строка неверна:

var client_token = "<?php echo($gateway->ClientToken()->generate()); ?>";

Вместо использования блока php внутри вашего javascript вы должны сделать AJAX-запрос к своему бэкэнду, который вернет клиентский токен, который вы затем можете использовать в своей форме.

Рассмотрим этот пример:

// Set up our HTTP request
var xhr = new XMLHttpRequest();

// Setup our listener to process completed requests
xhr.onload = function () {

    // Process our return data
    if (xhr.status >= 200 && xhr.status < 300) {
        var client_token = xhr.response.client_token; // Set your client token and use it later
    } else {
        // What do when the request fails
        console.info('The request failed!');
    }

    // Code that should run regardless of the request status
    console.info('This always runs...');
};

// Create and send a GET request
// The first argument is the post type (GET, POST, PUT, DELETE, etc.)
// The second argument is the endpoint URL
xhr.open('GET', '/route/to/braintree/controller'); // Create a Symfony route which will use `BraintreeService` and return generated client token.
xhr.send();

Это скорее псевдокод, но он должен дать вам общее представление о том, что вам следует делать. Судя по вашему коду, вы должны сначала получить этот client_token, а затем отрендерить форму.

Если проблема не в этом, продолжайте изучать эту ошибку консоли, это определенно причина, по которой вы не можете отобразить форму. Возможно, посетите документацию Braintree еще раз, у них есть отличные фреймворки и независимые от фреймворков примеры.

Спасибо. Итак, я должен создать маршрут в ProfileController пользователя (скажем, profile / braintree / generate_token) и передать ему мою службу Braintree, которую я создал, указав его в методе действия? Затем используйте свой js-код, чтобы получить client_token из этого маршрута? Звук в порядке?

TimothyAURA 05.01.2019 12:55

Да что-то подобное. Общая идея правильная, как вы ее реализуете, зависит только от вас.

Domagoj 05.01.2019 14:20

Другие вопросы по теме