laravel 使用 paypal/rest-api-sdk-php 的贝宝集成错误

laravel paypal intergration error using paypal/rest-api-sdk-php

下面是我在 myweb 应用程序中单击付款按钮时出现的错误。我的问题的解决方案是什么?我已经看过类似的问题,但似乎没有解决我的解决方案。 访问 https://api.sandbox.paypal.com/v1/payments/payment 时收到 Http 响应代码 400。 PayPal\Core\PayPalHttpConnection:错误:访问 https://api.sandbox.paypal.com/v1/payments/payment 时获得 Http 响应代码 400。 {"name":"MALFORMED_REQUEST","message":"传入 JSON 请求未映射到 API 请求","information_link":"https:// developer.paypal.com/webapps/developer/docs/api/#MALFORMED_REQUEST","debug_id":"7abde5aa538aa"}

下面是我的控制器 PaypalController.php

<?php

namespace App\Http\Controllers;

use Gloudemans\Shoppingcart\Facades\Cart;
use Illuminate\Support\Facades\Input;
use Illuminate\Http\Request;
use PayPal\Api\Details;
use PayPal\Api\Amount;
use PayPal\Api\Item;
use PayPal\Api\WebProfile;
use PayPal\Api\ItemList;
use PayPal\Api\InputFields;
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\Rest\ApiContext;
use Redirect;
use Session;
use URL;
use App\Invoice;
use App\Project;
use App\Suborder;
use Str;
//Use Request;
use Auth;
use Config;
use DB;

class PaypalController extends Controller
{
    private $apiContext;

    public function __construct()
    {
        # Main configuration in constructor
        $paypalConfig = Config::get('paypal');

        $this->apiContext = new ApiContext(new OAuthTokenCredential(
                $paypalConfig['client_id'],
                $paypalConfig['secret'])
        );

        $this->apiContext->setConfig($paypalConfig['settings']);
    }

    public function pay_amount(Request $request, $id)
    {
       $id =DB::table('projects')->where('id', $id)->get();
        return view('projects.pay')
        ->with('id', $id);
    }

    public function payWithpaypal(Request $request, $id)
    {
        # We initialize the payer object and set the payment method to PayPal
        $payer = new Payer();
        $payer->setPaymentMethod('paypal');

        # We insert a new order in the order table with the 'initialised' status
        // $project = new Project();
        // $project->user_name = Auth::user()->name;
        // $project->invoice_id = null;
        // $project->status = 'initialised';
        // $project->save();

        $project = Project::findOrFail($request->id);
        //$project = new Project();
        $project->update(['user_name' => (Auth::user()->name)]);
        $project->update(['invoice_id' => (null)]);
        $project->update(['status' => ('initialised')]);
        $project->save();

        # We need to update the order if the payment is complete, so we save it to the session
        Session::put('projectId', $project->getKey());

        # We get all the items from the cart and parse the array into the Item object

        //dd($project->project_id);

        $item = new Item();
        $items[] = (new Item())
            ->setCurrency('USD')
            ->setQuantity(1)
            ->setPrice($project->amount);
            //->setName($project->project_id)
            //->setName($item->name)
            //->setQuantity($item->qty)
            //->setPrice($item->price);
            //->setPrice($project->total_amount);

            //->setPrice($request->get('amount')); 

        # We create a new item list and assign the items to it

        $itemList = new ItemList();
        $itemList->setItems(array($items));

        # Disable all irrelevant PayPal aspects in payment
        // $inputFields = new InputFields();
        // $inputFields->setAllowNote(true)
        //     ->setNoShipping(1)
        //     ->setAddressOverride(0);

        // $webProfile = new WebProfile();
        // $webProfile->setName(uniqid())
        //     ->setInputFields($inputFields)
        //     ->setTemporary(true);

        // $createProfile = $webProfile->create($this->apiContext);

        # We get the total price of the cart

        $amount = new Amount();
        $amount->setCurrency('USD')
                ->setTotal($project->amount);
            //->setTotal(Cart::subtotal());


        $transaction = new Transaction();
        $transaction->setAmount($amount);
        $transaction->setItemList($itemList)
            ->setDescription('Your transaction description');    

        $redirectURLs = new RedirectUrls();
        $redirectURLs->setReturnUrl(URL::to('status'))
            ->setCancelUrl(URL::to('status'));

        $payment = new Payment();
        $payment->setIntent('Sale')
        //$payment->setIntent('authorize')
            ->setPayer($payer)
            ->setRedirectUrls($redirectURLs)
            ->setTransactions(array($transaction));

        //$payment->setExperienceProfileId($createProfile->getId());
        //$payment->create($this->apiContext);


        try {

            $payment->create($this->apiContext);
            $execution = new PaymentExecution(); $result = $payment->execute($execution, $apiContext);


        } catch (\PayPal\Exception\PPConnectionException $ex) {

            if (\Config::get('app.debug')) {

                \Session::put('error', 'Connection timeout');
                return Redirect::to('/');

            } else {

                \Session::put('error', 'Some error occur, sorry for inconvenient');
                return Redirect::to('/');

            }

        }

        foreach ($payment->getLinks() as $link) {

            if ($link->getRel() == 'approval_url') {

                $redirect_url = $link->getHref();
                break;

            }

        }

        # We store the payment ID into the session
        Session::put('paypalPaymentId', $payment->getId());

        if (isset($redirectURL)) {
            return Redirect::away($redirectURL);
        }

        Session::put('error', 'There was a problem processing your payment. Please contact support.');

        return Redirect::to('/client/projects');
    }


    public function getPaymentStatus()
    {
        /** Get the payment ID before session clear **/
        $payment_id = Session::get('paypal_payment_id');

        /** clear the session payment ID **/
        Session::forget('paypal_payment_id');
        if (empty(Input::get('PayerID')) || empty(Input::get('token'))) {

            \Session::put('error', 'Payment failed');
            return Redirect::to('/');

        }

        $payment = Payment::get($payment_id, $this->_api_context);
        $execution = new PaymentExecution();
        $execution->setPayerId(Input::get('PayerID'));

        /**Execute the payment **/
        $result = $payment->execute($execution, $this->_api_context);

        if ($result->getState() == 'approved') {

            \Session::put('success', 'Payment success');
            return Redirect::to('/');

        }

        \Session::put('error', 'Payment failed');
        return Redirect::to('/');

    }

 
}```

PayPal-PHP-SDK 和 v1/payments API 已弃用。

而是使用 v2/checkout/orders API 的 Checkout-PHP-SDK,在此处记录:https://developer.paypal.com/docs/business/checkout/server-side-api-calls/#server-side-api-calls

您应该制作两条路线,一条用于 'Create Order',一条用于 'Capture Order'。这些路由应该 return/output 只有 JSON 数据(没有 HTML 或文本)

将这两条路线与以下批准流程配对:https://developer.paypal.com/demo/checkout/#/pattern/server