Admin paga al vendedor a través de laravel paypal

Estoy implementando una funcionalidad donde admin paga a los vendedores en sus cuentas de correo electrónico PAYPAL. pero por alguna razón estoy recibiendo este error al implementar el siguiente código. Creo que el error viene cuando la función processPaymentInvoiceViaCheckout retornos redirect($approvalUrl)

Argumento 1 pasó a Symfony\Component\HttpFoundation\Response::setContent() debe ser de la cadena de tipo o null, objeto dado, llamado en

Rutas

//create payment object
Route::get('/invoices/process-payment','PaypalController@processPaymentInvoiceViaCheckout');

//when payment object is created then get its details and execute payment to send money.
Route::get('/invoices/response-success','PaypalController@paypalResponseSuccess');

//when cancel to pay
Route::get('/invoices/response-cancel','PaypalController@paypalResponseCancel');

Controlador

php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payee;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;
use PHPUnit\TextUI\ResultPrinter;

class PaypalController extends Controller
{
    private $api_context;

    public function __construct()
    {
        $this-api_context = new ApiContext(
            new OAuthTokenCredential(config('paypal.client_id'), config('paypal.secret'))
        );
        $this->api_context->setConfig(config('paypal.settings'));
    }

    public function processPaymentInvoiceViaCheckout(){
        $payer = new Payer();
        $payer->setPaymentMethod("paypal");

        $item1 = new Item();
        $item1->setName('Ground Coffee 40 oz')
            ->setCurrency('USD')
            ->setQuantity(1)
//            ->setSku("123123") // Similar to `item_number` in Classic API
            ->setPrice(7.5);
        $item2 = new Item();
        $item2->setName('Granola bars')
            ->setCurrency('USD')
            ->setQuantity(5)
//            ->setSku("321321") // Similar to `item_number` in Classic API
            ->setPrice(2);

        $itemList = new ItemList();
        $itemList->setItems(array($item1, $item2));
        $details = new Details();
        $details->setShipping(1.2)
            ->setTax(1.3)
            ->setSubtotal(17.50);
        $amount = new Amount();
        $amount->setCurrency("USD")
            ->setTotal(20)
            ->setDetails($details);
        $payee = new Payee();

        //this is the email id of the seller who will receive this amount

        $payee->setEmail("[email protected]");
        $transaction = new Transaction();
        $transaction->setAmount($amount)
            ->setItemList($itemList)
            ->setDescription("Payment description")
            ->setPayee($payee)
            ->setInvoiceNumber(uniqid());
        $redirectUrls = new RedirectUrls();
        $redirectUrls->setReturnUrl(url('/invoices/response-success'))
            ->setCancelUrl(url('/invoices/response-cancel'));
        $payment = new Payment();
        $payment->setIntent("sale")
            ->setPayer($payer)
            ->setRedirectUrls($redirectUrls)
            ->setTransactions(array($transaction));
        $request = clone $payment;
        try {
            //create payment object
            $createdPayment = $payment->create($this->api_context);
            //get payment details to get payer id so that payment can be executed and transferred to seller.
            $paymentDetails = Payment::get($createdPayment->getId(), $this->api_context);
            $execution = new PaymentExecution();
            $execution->setPayerId($paymentDetails->getPayer());
            $paymentResult = $paymentDetails->execute($execution,$this->api_context);
        } catch (\Exception $ex) {
            //handle exception here
        }
        //Get redirect url
        //The API response provides the url that you must redirect the buyer to. Retrieve the url from the $payment->getApprovalLink() method
        $approvalUrl = $payment->getApprovalLink();

        return redirect($approvalUrl);
    }

    public function paypalResponseCancel(Request $request)
    {

        //normally you will just redirect back customer to platform
        return redirect('invoices')->with('error','You can cancelled payment');
    }

    public function paypalResponseSuccess(Request $request)
    {
        if (empty($request->query('paymentId')) || empty($request->query('PayerID')) || empty($request->query('token'))){
            //payment was unsuccessful
            //send failure response to customer

        }
        $payment = Payment::get($request->query('paymentId'), $this->api_context);
        $execution = new PaymentExecution();
        $execution->setPayerId($request->query('PayerID'));

        // Then we execute the payment.
        $result = $payment->execute($execution, $this->api_context);


        dd($request->all(),$result);
        //payment is received,  send response to customer that payment is made.
    }
}

Pregunta hecha hace 3 años, 4 meses, 28 días - Por bytebard66b1


2 Respuestas:

  • El error que estás experimentando parece estar relacionado con el tipo de dato que estás devolviendo en el método processPaymentInvoiceViaCheckout de tu controlador.

    En Laravel, al usar redirect() estás devolviendo una instancia de la clase Illuminate\Http\RedirectResponse, que sería el tipo correcto de dato a devolver en este caso para redirigir al usuario a la URL de aprobación de PayPal. El error sugiere que se está esperando una cadena de texto o un objeto nulo en setContent() en lugar de un objeto.

    Para solucionar este error, asegúrate de que estás devolviendo una instancia de Illuminate\Http\RedirectResponse al hacer la redirección. Puedes corregir tu método processPaymentInvoiceViaCheckout de la siguiente manera:

    php
    public function processPaymentInvoiceViaCheckout(){
        // Tu código existente...
        try {
            // Tu código existente...
    
            //Get redirect url
            //The API response provides the url that you must redirect the buyer to. Retrieve the url from the $payment->getApprovalLink() method
            $approvalUrl = $payment->getApprovalLink();
    
            return redirect($approvalUrl);
        } catch (\Exception $ex) {
            // Manejar la excepción aquí
            return redirect('invoices')->with('error', 'Error al procesar el pago');
        }
    }
    

    Al manejar la excepción dentro del bloque try-catch y devolver una instancia de Illuminate\Http\RedirectResponse en la redirección, deberías poder solucionar el error que estás experimentando. Asegúrate también de tener configuradas correctamente las rutas de retorno en PayPal y que la URL de aprobación de PayPal sea válida.

    Respondida el Dec 20, 2020 a las 09:19 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El error que estás recibiendo se debe a que estás intentando establecer un objeto como el contenido de una respuesta HTTP. El método setContent de la clase Response espera un argumento de tipo cadena o null, pero le estás pasando un objeto que contiene una instancia de Payment de PayPal.

    Para resolver este problema, debes redirigir al usuario a la URL de aprobación que devuelve PayPal después de crear el objeto de pago. Puedes utilizar el método redirect de Laravel para hacer esto:

    php
    return redirect($approvalUrl);
    

    El código modificado quedaría así:

    php
    // ...
    
    // Get redirect url
    // The API response provides the url that you must redirect the buyer to. Retrieve the url from the $payment->getApprovalLink() method
    $approvalUrl = $payment->getApprovalLink();
    
    // Redirect the user to the approval URL
    return redirect($approvalUrl);
    

    Respondida el Dec 20, 2020 a las 09:20 - por Gemini

    Votos positivos: 0 | Votos negativos: 0