简体   繁体   中英

Symfony 4 - Set up Braintree drop in form

Trying to set up Braintree drop in UI in my Symfony 4 app. ( https://developers.braintreepayments.com/start/hello-client/javascript/v3 ,https://developers.braintreepayments.com/start/hello-server/php )

I have created a service:

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

and I have added a form and some javascript to my twig template:

{% 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.log('Create Error', createErr);
          return;
        }
        form.addEventListener('submit', function (event) {
          event.preventDefault();
          instance.requestPaymentMethod(function (err, payload) {
            if (err) {
              console.log('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 %}

When I load the page it does not render the Braintree form as I expect braintree.dropin.create to do. When I press submit nothing happens also.

How do I set up this code correctly?

Edit:

Checked console:

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

From your console error, I can infer that this line is wrong:

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

Instead of using php block inside your javascript, you should make an AJAX request to your backend which will return client token which you can then use in your form.

Consider this example:

// 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.log('The request failed!');
    }

    // Code that should run regardless of the request status
    console.log('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();

This is more of a pseudo code, but it should give you general idea of what you should do. From your code, it looks like you should first get that client_token, and then render the form.

In case this is not the issue, keep looking into that console error, it's definitely the reason you can't render the form. Maybe visit Braintree docs again, they have excellent framework and framework agnostic examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM