braintree / braintree_php

Braintree PHP library
https://developer.paypal.com/braintree/docs/start/overview
MIT License
547 stars 224 forks source link

Settlement Route with Test Transactions #327

Closed ooiginla closed 1 year ago

ooiginla commented 1 year ago

General information

Issue description

In the file Braintree\TestingGateway\Transaction::_doTestRequest() method.

 private function _doTestRequest($testPath, $transactionId)
    {
        self::_checkEnvironment();
        $path = $this->_config->merchantPath() . '/transactions/' . $transactionId . $testPath;
        $response = $this->_http->put($path); 
        return Transaction::factory($response['transaction']);
    }

When you try to settle a transaction that has been previously settled, it gives an error undefined parameter ($response['transaction']). This can be properly handled.

^ ErrorException {#1051 ▼
  #message: "Undefined array key "transaction""
  #code: 0
  #file: "/var/www/html/vendor/braintree/braintree_php/lib/Braintree/TestingGateway.php"
  #line: 44
  #severity: E_WARNING
  trace: {...}
}
hollabaq86 commented 1 year ago

👋 @ooiginla thanks for reaching out. Can I get a little more info on your use case, here? This function is only available in the TestingGateway class, which is used in a handful of tests that are designed to be run once. Why are you using the TestGateway?

ooiginla commented 1 year ago

The documentation under testing settlement routes states we can use this method to move transactions from submitted for settlement to settled and the escrow status to held during testing. We have exposed this api to other product clients within our ecosystem but when a transaction is already settled in test, this method throws an error because it is expecting a transaction and does hot handle that use case where it returns the full error object.

hollabaq86 commented 1 year ago

The documentation under testing settlement routes

What documentation? Can you provide me a link? I'm trying to get a full understanding of what we need to be changing.

The preferred way to test settling a transaction is via Transaction->submitForSettlement() using sandbox credentials.

ooiginla commented 1 year ago

So when I am creating a transaction, I already have submitted_for_settlement option as true. So, my transaction comes back as status: submitted_for_settlement and escrow_status: hold_pending

https://developer.paypal.com/braintree/docs/reference/general/testing/php#settlement-status

$sale_result = $gateway->transaction()->sale([
  'amount' => '100.00',
  'paymentMethodNonce' => nonceFromTheClient,
  'options' => [
    'submitForSettlement' => True
  ]
]);

// This is why i am calling the settle method on the test
$transaction = $gateway->testing()->settle($sale_result->transaction->id);
get_class($transaction)
# Braintree\Transaction

$transaction->status
# Braintree\Transaction::SETTLED

If you trace the $gateway->testing()->settle() method, it calls behind the scenes TestingGateway::settle() method which returns self::_doTestRequest('/settle', $transactionId);

hence the reason i started with that in my first complaint, the doTestRequests returns Transaction::factory($response['transaction']);

In a case i am passing an already settled transaction to $gateway->testing()->settle($sale_result->transaction->id);

it throws a bug. i hope this is clear.

Except you want to tell me an alternative way of moving my transaction to settled state after it is in a submittedForSettlement stage on testing.

hollabaq86 commented 1 year ago

Thanks @ooiginla the documentation link and your use case really helped clear things up.

Anyhoo, confusion cleared and we'll look into fixing this up. If you want to PR the fix, feel free, but don't feel obligated to!

For internal tracking, issue 7065

hollabaq86 commented 1 year ago

👋 @ooiginla we released a fix for this in v6.11.2, let us know if you still encounter issues!