简体   繁体   中英

Braintree dropin UI - Access token needs to be passed to Braintree\Gateway

Symfony 4 app with Braintree JS drop-in UI

I have created a service called Braintree to start testing.

namespace App\Services;

use Braintree\ClientToken;


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

    /** @var \Braintree_Gateway */
    private $gateway;

    function __construct() {
        $gateway = new \Braintree_Gateway([
            'environment' => getenv(self::ENVIRONMENT),
            'merchantId' => getenv(self::MERCHANT_ID),
            'publicKey' => getenv(self::PUBLIC_KEY),
            'privateKey' => getenv(self::PRIVATE_KEY)
        ]);
    }

public function generate() {
    return ClientToken::generate();
}

I am getting the following error:

HTTP 500 Internal Server Error
Braintree\Configuration::merchantId needs to be set (or accessToken needs to be passed to Braintree\Gateway).

The BT config has been properly entered into the .env file. Why is it not setting the MERCHANT_ID?

Edit:

Add config

Braintree_Gateway:
    class: Braintree_Gateway
    arguments:
        -
          'environment': '%env(BRAINTREE_ENVIRONMENT)%'
          'merchantId': '%env(BRAINTREE_MERCHANT_ID)%'
          'publicKey': '%env(BRAINTREE_PUBLIC_KEY)%'
          'privateKey': '%env(BRAINTREE_PRIVATE_KEY)%'

Edit 2:

The stack trace:

Braintree\Exception\
Configuration
in vendor\braintree\braintree_php\lib\Braintree\Configuration.php (line 261)
    public function assertHasAccessTokenOrKeys()    {        if (empty($this->_accessToken)) {            if (empty($this->_merchantId)) {                throw new Exception\Configuration('Braintree\\Configuration::merchantId needs to be set (or accessToken needs to be passed to Braintree\\Gateway).');            } else if (empty($this->_environment)) {                throw new Exception\Configuration('Braintree\\Configuration::environment needs to be set.');            } else if (empty($this->_publicKey)) {                throw new Exception\Configuration('Braintree\\Configuration::publicKey needs to be set.');            } else if (empty($this->_privateKey)) {
Configuration->assertHasAccessTokenOrKeys()
in vendor\braintree\braintree_php\lib\Braintree\ClientTokenGateway.php (line 34)
ClientTokenGateway->__construct(object(Gateway))
in vendor\braintree\braintree_php\lib\Braintree\Gateway.php (line 59)
Gateway->clientToken()
in vendor\braintree\braintree_php\lib\Braintree\ClientToken.php (line 18)
ClientToken::generate()
in src\Services\Braintree.php (line 25)
Braintree->generate()
in src\Controller\ProfileController.php (line 50)
ProfileController->booking_new(object(EntityManager), object(Request), object(Braintree))
in vendor\symfony\http-kernel\HttpKernel.php (line 149)

Edit 3:

namespace App\Services;

use Braintree_Gateway;

class Braintree extends Braintree_Gateway
{

    //Configure Braintree Environment
    public function __construct(Braintree_Gateway $gateway)
    {
        $this->$gateway = new Braintree_Gateway([
            'environment' => 'sandbox',
            'merchantId' => 'n5z3tjxh8zd6272k',
            'publicKey' => 'v4rjdzqk3gykw4kv',
            'privateKey' => '4ab8b962e81ee8c43bf6fa837cecfb97'
        ]);
    }

    //Generate a client token
    public function generate() {
        return $clientToken = $this->clientToken()->generate();
    }

}

Error is now:

Catchable Fatal Error: Object of class Braintree\Gateway could not be converted to string

Am I getting closer to generating the client token??

The .env -file does not actually populate the system environment. Instead it works as a fallback when the environment is not set. Your call to getenv() only takes into account the system environment. For your file to take effect you have to use the Service container.

#config/services.yaml
services:
    _defaults:
        autowire: true
        autoconfigure: true

    #... all the existing services

    Braintree_Gateway:
        class: Braintree_Gateway
        arguments:
            -
              'environment': '%env(BRAINTREE_ENVIRONMENT)%'
              'merchantId': '%env(BRAINTREE_MERCHANT_ID)%'
              'publicKey': '%env(BRAINTREE_PUBLIC_KEY)%'
              'privateKey': '%env(BRAINTREE_PRIVATE_KEY)%'

The special parameter %env()% will check your system environment for the variable first and if that is not set it will go through the .env files to see if there is a fallback defined. You can also read up on this in the docs: https://symfony.com/doc/current/configuration/external_parameters.html#environment-variables

This will give the service Braintree_Gateway , that you built manually inside your service. Just like with any other service you can inject it into your service instead and autowiring will pass in an already generated Braintree Gateway:

namespace App\Services;

use Braintree\ClientToken;

class Braintree
{
    private $gateway;

    public function __construct(\Braintree_Gateway $gateway)
    {
        $this->gateway = $gateway;
    }

    # ... methods using the gateway
}

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