Search code examples
phppdopaypal-rest-sdk

Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Id cannot be null'


Quite confused as to why i received this error. The purpose of the page is to make a paypal payment using product information stored in my database.

Here is the full error:

( ! ) Fatal error: Uncaught exception 'InvalidArgumentException' with message 'Id cannot be null' in /paypal/rest-api-sdk-php/lib/PayPal/Validation/ArgumentValidator.php on line 25
( ! ) InvalidArgumentException: Id cannot be null in /paypal/rest-api-sdk-php/lib/PayPal/Validation/ArgumentValidator.php on line 25
Call Stack
#   Time    Memory  Function    Location
1   0.0018  238920  {main}( )   ../makepurchase.php:0
2   0.0138  394792  PayPal\Api\Payment->execute( )  ../makepurchase.php:73
3   0.0141  396480  PayPal\Validation\ArgumentValidator::validate( )    ../Payment.php:368

*Line 25 is the PDO SELECT statement.

and here is my code for makepurchase.php:

try {
      $dbh = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_USERNAME, DB_USERNAME, DB_PASSWORD);
} catch   (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

error_reporting(E_ERROR | E_WARNING | E_PARSE);
  $book_id =$_GET["book_id"];
  $user =$_GET["user"];


$sth = $dbh->prepare("SELECT title, price FROM books2 WHERE b_id= :book_id");
$sth->bindValue(':book_id', $book_id);
$sth->execute();
$results = $sth->fetch(PDO::FETCH_ASSOC);
if(!empty($results)) {
    $title = $results['title'];
    $price = $results['price'];
}

echo '<pre />';
print_r($_GET);


$payer = new Payer();
$payer->setPaymentMethod("paypal");


$item1 = new Item();
$item1->setName($title)
    ->setCurrency('USD')
    ->setQuantity(1)
    ->setPrice($price);



 $details = new Details();
 $details->setShipping(1.2)
     ->setTax(1.3)
     ->setSubtotal(17.50);



$transaction = new Transaction();
$transaction->setAmount($price)
    ->setItemList($item1)
    ->setDescription("Payment description")
    ->setInvoiceNumber(uniqid());



$payment = new Payment();
$payment->setIntent("sale")
    ->setPayer($user)
    ->setRedirectUrls($redirectUrls)
    ->setTransactions(array($transaction));

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


$request = clone $payment;


try {
    $payment->create($apiContext);
} catch (Exception $ex) {
    ResultPrinter::printError("Created Payment Using PayPal. Please visit the URL to Approve.", "Payment", null, $request, $ex);
    exit(1);
}


$approvalUrl = $payment->getApprovalLink();

ResultPrinter::printResult("Setting up payment using Paypal. Please visit the URL to Approve.", "Payment", "<a href='$approvalUrl' >$approvalUrl</a>", $request, $payment);

return $payment;

Here is lines 20-30 of paypal\validation\ArgumentValidator:

  public static function validate($argument, $argumentName = null) { 
if ($argument === null) { // Error if Object Null throw new \InvalidArgumentException("$argumentName cannot be null"); } 
else if (gettype($argument) == 'string' && trim($argument) == ''){ 
// Error if String Empty throw new \InvalidArgumentException("$argumentName string cannot be empty"); } return true; }

Solution

  • I think you misunderstood the steps for creating the payment. From looking at the code, it shows that you are trying to execute the payment before even creating it.

    I would recommend you to just try out the sample first. See how both the steps are.

    However, I will try to get the steps here:

    If your payment type is PAYPAL

    1. Create a payment as shown here: http://paypal.github.io/PayPal-PHP-SDK/sample/doc/payments/CreatePaymentUsingPayPal.html

    2. This will provide you with approval_url, that you could retrieve using $approvalUrl = $payment->getApprovalLink(); code.

    3. Redirect your browser to that URL, asking the buyer to approve the payment by him logging into the account and approving for it.

    4. PayPal will redirect the browser back to return_url or cancel_url based on user's choice.

    5. You would retrieve the PayerID, and paymentId that is passed in the URL by paypal, by following the steps shown in http://paypal.github.io/PayPal-PHP-SDK/sample/doc/payments/ExecutePayment.html

    6. Execute the payment as shown above.

    7. You have money in your account now.

    If your payment type is Credit Card

    1. In case, when you are directly providing the credit card number to the payment, you need to follow only one step, as shown here: http://paypal.github.io/PayPal-PHP-SDK/sample/doc/payments/CreatePayment.html

    2. You DO NOT need to execute the payment, as it does not require paypal to send the user to login into paypal (as you are directly providing a credit card here).

    Let me know if this helps you understand that.

    I highly recommend playing around the samples by hosting it local on your machine, and running them, and understanding the flow. We have added a lot of documentation to our SDK at http://paypal.github.io/PayPal-PHP-SDK/

    Please feel free to create a Github issue if you find any error.

    Btw, the official documentation to APIs in Payments is provided here: https://developer.paypal.com/docs/integration/web/accept-paypal-payment/