Question

I'm trying to create an order programmatically using braintree payment method and the customer's saved credit card.

// prepare adresses, products in quote, shipping method - skipped
    $quote->setPaymentMethod('braintree');
    $quote->setInventoryProcessed(false);
    // Set Sales Order Payment

    $quote->getPayment()->importData(array('method' => 'braintree, 'cc_type' => 'AE', 'cc_exp_month' => '05', 'cc_exp_year' => '2022', 'public_hash' => $public_hash));

    $customer = $this->customerRepository->get($contact->email);
   // prepare customer
    $quote->setCustomer($customer);

    // Collect Totals & Save Quote
    $quote->collectTotals()->save();
    $order = $this->quoteManagement->submit($quote);

I have access to all of the saved CC information from the customer, I'm just not sure what info needs to be passed in $quote->getPayment(importData(array(....));

In my payment.log file I see the following error when attempting to create orders using the saved CC:

Cannot determine payment method.

Any ideas how to process payments using Braintree vaulted cards?

Was it helpful?

Solution

I was able to figure this out, you just need to pass the payment_method_nonce and public_hash along with the payment method braintree_cc_vault:

...

$quote->getPayment()->importData(array('method' => 'braintree_cc_vault', 'public_hash' => $public_hash, 'payment_method_nonce' => $paymentMethodNonce));

...

EDIT, added more info:

To get the public_hash and payment_method_nonce for each saved credit card for a given customer, I am doing the following:

...

protected $paymentTokenManagement;
protected $command;
protected $session;

public function __construct(
    \Magento\Framework\App\Action\Context $context,
    \Magento\Vault\Api\PaymentTokenManagementInterface $paymentTokenManagement,
    \Magento\Braintree\Gateway\Command\GetPaymentNonceCommand $command,
    \Magento\Framework\Session\SessionManagerInterface $session,
    ...
    array $data = []
  ) {
    ...
    $this->paymentTokenManagement = $paymentTokenManagement;
    $this->command = $command;
    $this->session = $session;
    parent::__construct($context);
  }

public function execute()
{
  $customerId = 1;

  // Get Saved CC
  $cardList = $this->paymentTokenManagement->getListByCustomerId($customerId);

  foreach($cardList as $card) {
    if ($card->getIsActive()) {
      // Get Card Public Hash for each active card
      $public_hash = $card->getData('public_hash');

      // Need to pass Customer ID and Store ID below
      $paymentMethodNonce = $this->command->execute(['public_hash' => $public_hash, 'customer_id' => $customerId, 'store_id' => $this->session->getStoreId()])->get();
      $paymentMethodNonce = $paymentMethodNonce['paymentMethodNonce'];
    }
  }
}

You can then pass $public_hash and $paymentMethodNonce to:

$quote->getPayment()->importData(array('method' => 'braintree_cc_vault', 'public_hash' => $public_hash, 'payment_method_nonce' => $paymentMethodNonce));

Please note, this is just a snippet of my full code -- you may need to alter it to fit into your project.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top