1

I need to accept PayPal Express payments from a Laravel-4 app, so am trying to decide if Omnipay is the best solution. The sticking point is that it doesn't seem to implement GetExpressCheckoutDetails, so the purchaser's contact details are not accessible. I've seen these discussions about the problem:

omnipay paypal express not returning address

receive more response data in ci-merchant library codeigniter

However, neither give a definitive solution. If I use Omnipay, would I also have to install PayPal's Classic API (in which case, why bother with Omnipay), or can I implement GetExpressCheckoutDetails in Omnipay, and if so, how?

Thanks in advance for any help on this.

Community
  • 1
  • 1
Keith M
  • 101
  • 8

3 Answers3

2

omnipay\paypal\ProGateway.php add new function

public function fetchExpressCheckoutDetail(array $parameters = array())
{
    return $this->createRequest('\Omnipay\PayPal\Message\FetchExpressCheckoutRequest', $parameters);
}

omnipay\paypal\src\Message add new file FetchExpressCheckoutRequest.php

namespace Omnipay\PayPal\Message;
class FetchExpressCheckoutRequest extends AbstractRequest
{
    public function getData()
    {
        $data = $this->getBaseData('GetExpressCheckoutDetails');

        $this->validate('transactionReference');
        $data['TOKEN'] = $this->getTransactionReference();
        $url = $this->getEndpoint()."?USER={$data['USER']}&PWD={$data['PWD']}&SIGNATURE={$data['SIGNATURE']}&METHOD=GetExpressCheckoutDetails&VERSION={$data['VERSION']}&TOKEN={$data['TOKEN']}";
        parse_str (file_get_contents( $url ),$output);
        $data = array_merge($data,$output);
        return $data;
    }
}

Usage:

$response = $gateway->completePurchase($params)->send();
$data = $response->getData();
$gateway->fetchExpressCheckoutDetail(array('transactionReference'=>$data['TOKEN']))->getData();

It will be not the best. But it works. :)

kei.
  • 71
  • 3
  • tomsowerby has implemented another solution in a pull request at this [link](https://github.com/omnipay/paypal/pull/18). It works, and I hope it's going to be merged. – Keith M Jun 17 '14 at 07:32
0

Omnipay doesn't support GetExpressCheckoutDetails (yet). There is a pull request currently open for this.

However it does implement GetTransactionDetails which you may find useful, as that can return most information about an existing transaction.

Adrian Macneil
  • 13,017
  • 5
  • 57
  • 70
  • The pull request has been quiet for a couple of months. Any idea what the delay is? I tried calling GetTransactionDetails via completePurchase, but it doesn't return the purchaser's contact details. – Keith M Jun 04 '14 at 13:08
  • Just that it's a large pull request and I've been really busy so haven't had time to do the work myself. If it was broken up into separate PRs for GetExpressCheckoutDetails, and the API improved per the comments in that thread it would be fairly easy to merge. – Adrian Macneil Jun 04 '14 at 15:21
0

Based on kei. answer I suggest the following addition to the application:

  1. Create new path app/omnipay/paypal/Message/
  2. Create new file app/omnipay/paypal/ExtendedExpressGateway.php

    namespace App\Omnipay\PayPal;
    
    use Omnipay\PayPal\ExpressGateway;
    
    /**
     * PayPal Express extended Class
     */
    class ExtendedExpressGateway extends ExpressGateway
    {
        public function getName()
        {
            return 'PayPal Express extended';
        }
    
        public function fetchExpressCheckoutDetail(array $parameters = array())
        {
            return $this->createRequest('\\App\\Omnipay\\PayPal\\Message\\FetchExpressCheckoutRequest', $parameters);
        }
    }
    
  3. Create new file app/omnipay/paypal/Message/FetchExpressCheckoutRequest.php

    namespace App\Omnipay\PayPal\Message;
    
    use Omnipay\PayPal\Message\AbstractRequest;
    
    class FetchExpressCheckoutRequest extends AbstractRequest
    {
        public function getData()
        {
            $data = $this->getBaseData('GetExpressCheckoutDetails');
    
            $this->validate('transactionReference');
    
            $data['TOKEN'] = $this->getTransactionReference();
            $url = $this->getEndpoint() . "?USER={$data['USER']}&PWD={$data['PWD']}&SIGNATURE={$data['SIGNATURE']}&METHOD=GetExpressCheckoutDetails&VERSION={$data['VERSION']}&TOKEN={$data['TOKEN']}";
            parse_str(file_get_contents($url), $output);
            $data = array_merge($data, $output);
    
            return $data;
        }
    }
    
  4. Add to psr-4 autoload in composer.json

    "autoload": {
        "classmap": [
            ...
        ],
        "psr-4": {
            "App\\Omnipay\\PayPal\\": "app/omnipay/paypal/"
        }
    },
    
  5. run:

    php artisan dump-autoload
    
  6. Now in app/config/packages/ignited/laravel-omnipay/config.php you can write:

    'driver' => '\\App\\Omnipay\\PayPal\\ExtendedExpressGateway',
    

Now when you update will be no problems

Anatoli
  • 141
  • 2
  • 6
  • 1
    Warning: After implementing these steps and using "$gateway = new App\Omnipay\PayPal\ExtendedExpressGateway();" in place of "Omnipay::create('PayPal_Express');" I found that ExtendedExpressGateway::fetchExpressCheckoutDetail() returned the same information as Omnipay's built-in "$data = $gateway->fetchCheckout($params)->send()->getData();” so it’s probably not worth the trouble. Anyway, if you are having trouble with the psr-4 autoloader not finding ExtendedExpressGateway, remember to put " – Zack Morris Feb 17 '15 at 00:17
  • Thanks @ZackMorris, this helped me a load and idealy should be the accepted best answer, please write a full reply so I can upvote it. The benefit of using this method is that if the payer_id or the transaction_id were not saved, you only have the transaction reference id, this is the only way you can programatically get those details. – TeeHays May 10 '18 at 13:17