paypal-woocommerce icon indicating copy to clipboard operation
paypal-woocommerce copied to clipboard

Braintree ACH "3000 Processor Declined" doesn't fail the order or add an order note

Open peterjohnhunt opened this issue 1 year ago • 0 comments

In the braintree class, when an ACH payment is being processed, it first attempts to create an ACH payment method. However, if that function fails due to a ACH 3000 error, a notice is added to the front end, but the order is left orphaned as pending payment with not trace or logs of what went wrong:

https://github.com/angelleye/paypal-woocommerce/blob/a66ff9f125ff72ad44f198b4b59c8f10fe23b1f3/classes/wc-gateway-braintree-angelleye.php#L1131C28-L1131C28

How to reproduce:

  1. Use Braintree
  2. Pay for an order using ACH
  3. Use ACH account number: 1000000002 (failed 3000 processor unavailable)
  4. WooCommerce order is still marked as pending payment instead of failed
  5. Logs don't include details of the error
  6. Order has no order notes

Recommended approach:

Inside of the process_payment function, if the result of:

$result = $this->braintree_ach_create_payment_method($braintree_customer_id);

is false, we add a log message and update the order status:

$this->add_log("Error: Unable to create ach payment method.");
$order->update_status('failed', sprintf(__('Unable to create Braintree ACH payment token.', 'paypal-for-woocommerce'), $this->response->message, $this->response->transaction->id ?? 'N/A'));

Possible full updated function:

    public function process_payment($order_id) {
        $this->angelleye_braintree_lib($order_id);
        if (AngellEYE_Utility::angelleye_is_save_payment_token($this, $order_id)) {
            $this->storeInVaultOnSuccess = true;
        }
        $this->storeInVaultOnSuccess = apply_filters('angelleye_braintree_store_in_vault_on_success', $this->storeInVaultOnSuccess);
        $order = wc_get_order($order_id);
        if( $this->enable_braintree_ach && isset($_POST['braintree_ach_token'] )) {
            $braintree_customer_id = $this->angelleye_braintree_ach_create_customer_id($order);
            $result = $this->braintree_ach_create_payment_method($braintree_customer_id);
            $payment_method_token = $result->paymentMethod->token;
            if($payment_method_token) {
                $success = $this->angelleye_ach_process_payment($order, $payment_method_token);
            } else {
                $this->add_log("Error: Unable to create ach payment method.");
                $order->update_status('failed', __('Unable to create Braintree ACH payment token.', 'paypal-for-woocommerce'));
            }
        } else {
            if( $this->payment_action == 'Sale' ) {
                $success = $this->angelleye_do_payment($order);
            } else {
                $success = $this->angelleye_save_payment_auth($order);
            }
        }
        if ($success == true) {
            return array(
                'result' => 'success',
                'redirect' => $this->get_return_url($order)
            );
        } else {
            return array(
                'result' => 'fail',
                'redirect' => ''
            );
        }
    }

peterjohnhunt avatar Nov 09 '23 14:11 peterjohnhunt