John Davidson

PHP laravel - PayPal SDK cannot be called from scheduler

0 comments
Message:


I am unable to get PayPal payment status from scheduler. Example below:


function fixUnfinished()
{
$paypalRequest = new OrdersGetRequest("<payment_id>");
$response = app('App\Http\Controllers\PaypalController')->getPayPalClient()->execute($paypalRequest);
...do_something_with_the_response... (eg. dd($response); )
}

If I call this exact same function from a test route, everything works, the response contains the payment status and so on. example:


Route::get('test', function(){ app('App\Http\Controllers\PaypalController')->fixUnfinished(); });

However, if I call the same method from laravel scheduler (App/Console/Kernel.php), It is throwing large amounts of errors. Error sample here:


[2022-05-16 16:03:02] local.ERROR: {"error":"invalid_client","error_description":"Client Authentication failed"} {"exception":"[object] (PayPalHttp\\HttpException(code: 0): {\"error\":\"invalid_client\",\"error_description\":\"Client Authentication failed\"} at C:\\xampp\\htdocs\\AppName\\vendor\\paypal\\paypalhttp\\lib\\PayPalHttp\\HttpClient.php:222)
[stacktrace]
#0 C:\\xampp\\htdocs\\AppName\\vendor\\paypal\\paypalhttp\\lib\\PayPalHttp\\HttpClient.php(103): PayPalHttp\\HttpClient->parseResponse(Object(PayPalHttp\\Curl))
#1 C:\\xampp\\htdocs\\AppName\\vendor\\paypal\\paypal-checkout-sdk\\lib\\PayPalCheckoutSdk\\Core\\AuthorizationInjector.php(37): PayPalHttp\\HttpClient->execute(Object(PayPalCheckoutSdk\\Core\\AccessTokenRequest))
#2 C:\\xampp\\htdocs\\AppName\\vendor\\paypal\\paypal-checkout-sdk\\lib\\PayPalCheckoutSdk\\Core\\AuthorizationInjector.php(29): PayPalCheckoutSdk\\Core\\AuthorizationInjector->fetchAccessToken()
#3 C:\\xampp\\htdocs\\AppName\\vendor\\paypal\\paypalhttp\\lib\\PayPalHttp\\HttpClient.php(67): PayPalCheckoutSdk\\Core\\AuthorizationInjector->inject(Object(PayPalCheckoutSdk\\Orders\\OrdersGetRequest))
#4 C:\\xampp\\htdocs\\AppName\\app\\Http\\Controllers\\PaypalController.php(91): PayPalHttp\\HttpClient->execute(Object(PayPalCheckoutSdk\\Orders\\OrdersGetRequest))
#5 C:\\xampp\\htdocs\\AppName\\app\\Console\\Kernel.php(121): App\\Http\\Controllers\\PaypalController->fixUnfinished()
#6 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(36): App\\Console\\Kernel->App\\Console\\{closure}()
#7 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(36): Closure->__invoke()
#8 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Util.php(41): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#9 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#10 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(37): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#11 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php(651): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#12 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Scheduling\\CallbackEvent.php(118): Illuminate\\Container\\Container->call(Array, Array)
#13 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Scheduling\\Event.php(230): Illuminate\\Console\\Scheduling\\CallbackEvent->execute(Object(Illuminate\\Foundation\\Application))
#14 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Scheduling\\Event.php(200): Illuminate\\Console\\Scheduling\\Event->start(Object(Illuminate\\Foundation\\Application))
#15 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Scheduling\\CallbackEvent.php(77): Illuminate\\Console\\Scheduling\\Event->run(Object(Illuminate\\Foundation\\Application))
#16 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Scheduling\\ScheduleRunCommand.php(156): Illuminate\\Console\\Scheduling\\CallbackEvent->run(Object(Illuminate\\Foundation\\Application))
#17 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Scheduling\\ScheduleRunCommand.php(115): Illuminate\\Console\\Scheduling\\ScheduleRunCommand->runEvent(Object(Illuminate\\Console\\Scheduling\\CallbackEvent))
#18 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(36): Illuminate\\Console\\Scheduling\\ScheduleRunCommand->handle(Object(Illuminate\\Console\\Scheduling\\Schedule), Object(Illuminate\\Events\\Dispatcher), Object(NunoMaduro\\Collision\\Adapters\\Laravel\\ExceptionHandler))
#19 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Util.php(41): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#20 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(93): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#21 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\BoundMethod.php(37): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#22 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php(651): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#23 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(136): Illuminate\\Container\\Container->call(Array)
#24 C:\\xampp\\htdocs\\AppName\\vendor\\symfony\\console\\Command\\Command.php(291): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#25 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Command.php(121): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#26 C:\\xampp\\htdocs\\AppName\\vendor\\symfony\\console\\Application.php(989): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#27 C:\\xampp\\htdocs\\AppName\\vendor\\symfony\\console\\Application.php(299): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Console\\Scheduling\\ScheduleRunCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#28 C:\\xampp\\htdocs\\AppName\\vendor\\symfony\\console\\Application.php(171): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#29 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Console\\Application.php(102): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#30 C:\\xampp\\htdocs\\AppName\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Console\\Kernel.php(129): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#31 C:\\xampp\\htdocs\\AppName\\artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#32 {main}
"}

I am 100% sure the clientId and clientSecret are not the fault, because it works if called from anywhere else than the scheduler. What could be the fault?


Any help appreciated, I am quite new to Laravel.



My Answer:
'ORDER-ID'
);

$response = $paypalClient->execute($paypalRequest);

$status = $response->result->status;

if($status == 'COMPLETED') {
// Do something
} else {
// Do something else
}
}

// Call the function
fixUnfinished();

This code will not work when called from a scheduler because the PayPal SDK requires an active HTTP request to function properly. Schedulers in Laravel run in the background and do not have access to the necessary resources to make HTTP requests.

To fix this issue, you can create a separate command in Laravel that will make the PayPal SDK call and then schedule that command to run at the desired interval. Here's an example of how you can do this:

1. Create a new command in Laravel by running the following command in your terminal:

php artisan make:command CheckPaypalStatus

2. Open the newly created CheckPaypalStatus.php file in the app/Console/Commands directory and update the handle method to include the PayPal SDK code:

php
use Illuminate\Console\Command;
use PayPalCheckoutSdk\Orders\OrdersGetRequest;

class CheckPaypalStatus extends Command
{
protected $signature = 'paypal:check-status';

protected $description = 'Check PayPal payment status';

public function __construct()
{
parent::__construct();
}

public function handle()
{
$paypalRequest = new OrdersGetRequest('ORDER-ID');

$response = $paypalClient->execute($paypalRequest);

$status = $response->result->status;

if($status == 'COMPLETED') {
// Do something
} else {
// Do something else
}
}
}


3. Update your scheduler in the app/Console/Kernel.php file to call the new command at the desired interval:

php
protected function schedule(Schedule $schedule)
{
$schedule->command('paypal:check-status')->everyMinute();
}


4. Finally, run the following command in your terminal to start the scheduler:

php artisan schedule:run

Now, the CheckPaypalStatus command will run at the specified interval and check the PayPal payment status using the PayPal SDK.

Rate this post

3 of 5 based on 8967 votes

Comments




© 2024 Hayatsk.info - Personal Blogs Platform. All Rights Reserved.
Create blog  |  Privacy Policy  |  Terms & Conditions  |  Contact Us