You are here

public function Braintree3DSReview::buildPaneForm in Commerce Braintree 8

Builds the pane form.

Parameters

array $pane_form: The pane form, containing the following basic properties:

  • #parents: Identifies the position of the pane form in the overall parent form, and identifies the location where the field values are placed within $form_state->getValues().

\Drupal\Core\Form\FormStateInterface $form_state: The form state of the parent form.

array $complete_form: The complete form structure.

Overrides CheckoutPaneInterface::buildPaneForm

File

src/Plugin/Commerce/CheckoutPane/Braintree3DSReview.php, line 91

Class

Braintree3DSReview
Adds 3DS authentication for Braintree vaulted/stored payment methods.

Namespace

Drupal\commerce_braintree\Plugin\Commerce\CheckoutPane

Code

public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {

  /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */
  $payment_method = $this->order
    ->get('payment_method')->entity;

  /** @var \Drupal\commerce_braintree\Plugin\Commerce\PaymentGateway\HostedFieldsInterface $braintree_plugin */
  $braintree_plugin = $this->order
    ->get('payment_gateway')->entity
    ->getPlugin();

  // 3DS nonces are single-use, so a new nonce must be generated from the
  // stored payment method and authenticated for use in payment transaction.
  try {
    $result = $braintree_plugin
      ->createPaymentMethodNonce($payment_method
      ->getRemoteId());
    $pane_form['#attached']['library'][] = 'commerce_braintree/checkout-review';
    $amount = Calculator::trim($this->order
      ->getBalance()
      ->getNumber());
    $pane_form['#attached']['drupalSettings']['commerceBraintree'] = [
      'clientToken' => $braintree_plugin
        ->generateClientToken(),
      'formId' => $complete_form['#id'],
      'amount' => $amount,
      'nonce' => $result->paymentMethodNonce->nonce,
      'bin' => $result->paymentMethodNonce->details['bin'],
      'email' => $this->order
        ->getEmail(),
    ];

    // Unused non-hidden element included to ensure pane is built.
    $pane_form['payment_errors'] = [
      '#type' => 'markup',
      '#markup' => '<div id="payment-errors"></div>',
      '#weight' => -200,
    ];

    // Populated by the JS library.
    $pane_form['payment_method_nonce'] = [
      '#type' => 'hidden',
      '#attributes' => [
        'class' => [
          'braintree-nonce',
        ],
      ],
    ];
  } catch (\Braintree\Exception $e) {
    ErrorHelper::handleException($e);
  } catch (PaymentGatewayException $e) {
    $this->logger
      ->error($e
      ->getMessage());
    $message = $this
      ->t('We encountered an unexpected error processing your payment method. Please try again later.');
    $this
      ->messenger()
      ->addError($message);
    $this->checkoutFlow
      ->redirectToStep($this
      ->getErrorStepId());
  }
  $cacheability = new CacheableMetadata();
  $cacheability
    ->addCacheableDependency($this->order);
  $cacheability
    ->setCacheMaxAge(0);
  $cacheability
    ->applyTo($pane_form);
  return $pane_form;
}