thephpleague / omnipay

A framework agnostic, multi-gateway payment processing library for PHP 5.6+
http://omnipay.thephpleague.com/
MIT License
5.91k stars 925 forks source link

I'm getting DiscoveryFailedException Error #691

Open iamjohnseun opened 1 year ago

iamjohnseun commented 1 year ago

I recently ran composer update on my server and now i can't get omnipay to work anymore. I am using PayPal and Stripe gateways but the error i am getting for both gateways is:

Fatal error: Uncaught Http\Discovery\Exception\DiscoveryFailedException: Could not find resource using any discovery strategy. Find more information at http://docs.php-http.org/en/latest/discovery.html#common-errors - No valid candidate found using strategy "Http\Discovery\Strategy\CommonClassesStrategy". We tested the following candidates: Nyholm\Psr7\Factory\HttplugFactory, Http\Message\MessageFactory\GuzzleMessageFactory, Http\Message\MessageFactory\DiactorosMessageFactory, Http\Message\MessageFactory\SlimMessageFactory. - No valid candidate found using strategy "Http\Discovery\Strategy\CommonPsr17ClassesStrategy".

Any ideas on resolving this? I currently can't receive payments so it URGENT. Thank you.

iamjohnseun commented 1 year ago

I did do some research and searched the issues and documentation but i found no solution. I also searched the internet and i tried to run: composer install nyholm/psr7 as suggested in here but i still couldn't get it to work.

iamjohnseun commented 1 year ago

I have also tried to run: composer require php-http/curl-client guzzlehttp/psr7 php-http/message As suggested here, but i am still getting the same error.

judgej commented 1 year ago

What do you have installed as a HTTP client? If nothing yet, try installing Guzzle. If you give us the "requires" section of your composer.json, that might tell us what is missing.

Factory discovery can be a real pain when you least expect it, because it is generally very poorly documented. It is supposed to make it easier by looking for installed packages it can use, but if nobody is told one or more of a selection of packages needs to be installed, then it leaves you hanging there.

So what I think needs to happen here, as a quick-start:

You may not even need the guzzle 7 adapter. I tend to resort to trial-and-error adding things in, and taking them out again to see if they are needed. The documentation is out there, but spread over too many packages to easily get a good picture of what is needed, if you aren't working with these packages every day.

Hopefully that helps.

iamjohnseun commented 1 year ago

For anyone who updates by any chance, run composer require php-http/message-factory to solve the issue.

my composer.json currently looks like this.

{
  "require": {
    "league/omnipay": "^3",
    "omnipay/paypal": "^3.0",
    "omnipay/stripe": "^3.2",
    "php-http/curl-client": "^2.3",
    "guzzlehttp/psr7": "^2.5",
    "php-http/message": "^1.16",
    "php-http/message-factory": "^1.1"
  }
}
iamjohnseun commented 1 year ago

What do you have installed as a HTTP client? If nothing yet, try installing Guzzle. If you give us the "requires" section of your composer.json, that might tell us what is missing.

Factory discovery can be a real pain when you least expect it, because it is generally very poorly documented. It is supposed to make it easier by looking for installed packages it can use, but if nobody is told one or more of a selection of packages needs to be installed, then it leaves you hanging there.

So what I think needs to happen here, as a quick-start:

  • Install the guzzle client composer require guzzlehttp/guzzle:^7.0 (IIRC that already includes the PSR-7 messages by default). This is the client that Omnipay will use to talk over the internet to the payment gateways.
  • Install the adapter so that Omnipay knows how to discover that Guzzle 7 is installed: composer require php-http/guzzle7-adapter. The adapter allows the discovery service to find Guzzle, and then pass it on to Omnipay to use. It will be wrapped in a standard wrapper, so that Omnipay does not care what client you are using (Guzzle is a good one, but not the only one). This flexibility has the double-edged sword of more layers to consider.
  • If that still isn't working then composer require guzzlehttp/psr7 but I'm not sure you will need that.

You may not even need the guzzle 7 adapter. I tend to resort to trial-and-error adding things in, and taking them out again to see if they are needed. The documentation is out there, but spread over too many packages to easily get a good picture of what is needed, if you aren't working with these packages every day.

Hopefully that helps.

I did have guzzle installed on my previous installation as i was using the default option and not using a special adapter as specified in the installation documentation.

I even created a new project to test if i would get the same error, I cloned the omnipay-example on my server and the error persisted.

Perhaps it is been caused by some some [dependency changes]? (https://github.com/thephpleague/omnipay/commit/38f66a0cc043ed51d6edf7956d6439a2f263501f)?

judgej commented 1 year ago

I don't see the guzzle client in your composer.json. Are you specifically trying to use the curl client, or trying to get it working any which way?

Guzzle 7 client already includes the PSR messages so you don't need to add that explicitely. I'm not sure any Omnipay driver even used PSR-7 messages.

chronon commented 1 year ago

I've run into the same issue, and can confirm explicitly installing php-http/message-factory fixes it (for now). However, the php-http/message-factory repository has been recently deprecated/archived, stating:

The PHP-HTTP factories have become obsolete with the PSR-17 factories standard. All major HTTP client implementors provide PSR-17 factories.

This package will remain available for the time being to not break legacy code, but we encourage everybody to move to PSR-17.

The reason php-http/message-factory needs to be explicitly installed is due to php-http/message v1.16.0 recently removing it as a dependency. From the changelog there:

Remove direct dependency on php-http/message-factory as it is only needed for the deprecated Httplug factories. Upgrade to PSR-17 message factories provided by your HTTP client implementation. If you need the Httplug factories for the time being, you can composer require php-http/message-factory in your application.

I'm using guzzlehttp/guzzle with Omnipay and can't get things to work without the deprecated php-http/message-factory package, and am not sure what needs to be fixed where.