skip to Main Content

I’ve been trying to finish my server side implementation of the PayPal Smart Button and got stuck with capturing the transaction. I’m using a Sandbox account. I’m not sure if the problem is the order ID.

The response I get when trying to capture a transaction:

Fatal error: Uncaught PayPalHttpHttpException: 
{"name":"RESOURCE_NOT_FOUND",
 "details[{"field":"order_id",
     "value":"$orderId",
     "location":"path",
     "issue":"INVALID_RESOURCE_ID",
     "description":"Specified resource ID does not exist. Please check the resource ID and try again."}],
 "message":"The specified resource does not exist.",
 "debug_id":"df5cdbddfc1ea",
 "links":[{"href":"https://developer.paypal.com/docs/api/orders/v2/#error-INVALID_RESOURCE_ID",
 "rel":"information_link","method":"GET"}]} in /usr/local/ampps/www/shop-files/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php:215
 Stack trace: #0 /usr/local/ampps/www/shop-files/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php(100): PayPalHttpHttpClient->parseResponse(Object(PayPalHttpCurl)) 
#1 /usr/local/ampps/www/shop-files/capture-transaction.php(29): PayPalHttpHttpClient->execute(Object(PayPalCheckoutSdkOrdersOrdersCaptureRequest))
 #2 /usr/local/ampps/www/shop-files/capture-transaction.php(62): SampleCaptureIntentExamplesCaptureOrder::captureOrder('$orderId', in /usr/local/ampps/www/shop-files/vendor/paypal/paypalhttp/lib/PayPalHttp/HttpClient.php on line 215

The response I get when creating a transaction:

{
    "id": "1XB529992P492602W",
    "intent": "CAPTURE",
    "status": "CREATED",
    "purchase_units": [
        {
            "reference_id": "default",
            "amount": {
                "currency_code": "GBP",
                "value": "12.00"
            },
            "payee": {
                "email_address": "[email protected]",
                "merchant_id": "SUHPR7WSYJPJQ"
            }
        }
    ],
    "create_time": "2020-10-14T08:36:00Z",
    "links": [
        {
            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/1XB529992P492602W",
            "rel": "self",
            "method": "GET"
        },
        {
            "href": "https://www.sandbox.paypal.com/checkoutnow?token=1XB529992P492602W",
            "rel": "approve",
            "method": "GET"
        },
        {
            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/1XB529992P492602W",
            "rel": "update",
            "method": "PATCH"
        },
        {
            "href": "https://api.sandbox.paypal.com/v2/checkout/orders/1XB529992P492602W/capture",
            "rel": "capture",
            "method": "POST"
        }
    ]
}

My php code for creating a transaction:

<?php
namespace SampleCaptureIntentExamples;
session_start();
require __DIR__ . '/vendor/autoload.php';

use SamplePayPalClient;
use PayPalCheckoutSdkOrdersOrdersCreateRequest;
require 'paypal-client.php';

class CreateOrder {
  public static function createOrder() {
    $request = new OrdersCreateRequest();
    $request->prefer('return=representation');
    $request->body = self::buildRequestBody();
 
    $client = PayPalClient::client();
    $response = $client->execute($request);
 
    echo json_encode($response->result, JSON_PRETTY_PRINT);

    return $response;
  }
    private static function buildRequestBody() {
      return array(
        'intent'=>'CAPTURE',
        'application_context'=>
          array(
            'return_url'=>'https://localhost/basket.php',
            'cancel_url'=>'https://localhost/basket.php'
          ),
        'purchase_units'=>
          array(
            0=>
              array(
                'amount'=>
                  array(
                    'currency_code'=>'GBP',
                    'value'=>$_SESSION['total']
                  )             
              )
          )
      );
    }
}

if (!count(debug_backtrace()))
{
  CreateOrder::createOrder(true);
}
?>

Code for capturing a transaction:

<?php

namespace SampleCaptureIntentExamples;

require __DIR__ . '/vendor/autoload.php';
use SamplePayPalClient;
use PayPalCheckoutSdkOrdersOrdersCaptureRequest;
require 'paypal-client.php';

class CaptureOrder
{ 
  public static function captureOrder($orderId)
  {
    $request = new OrdersCaptureRequest($orderId);

    $client = PayPalClient::client();
    $response = $client->execute($request);
  
      echo json_encode($response->result, JSON_PRETTY_PRINT);

    return $response;
  }
}
if (!count(debug_backtrace()))
{
  CaptureOrder::captureOrder('$orderId', true);
}
?>

JavaScript:

createOrder: function(data) {
      return fetch('/shop-files/create-order.php', {
        method: 'post',
      }).then(function(res) {
        return res.json();
      }).then(function(orderData) {
        return orderData.id;
      });
    },
    onShippingChange: function(data, actions) {
      if (data.shipping_address.country_code !== "GB") {
        return actions.reject();
      }
      return actions.resolve();
    },
    onApprove: function(data) {
      return fetch('/shop-files/capture-transaction.php', {
        method: 'post',
        headers: {
          'content-type': 'application/json'
        },
      }).then(function(res) {
          return res.json();
      }).then(function(orderData) {
          if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
              return actions.restart();
          }
          if (errorDetail) {
              var msg = 'Sorry, your transaction could not be processed.';
              if (errorDetail.description) msg += 'nn' + errorDetail.description;
              if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
              return alert(msg);
          }
          alert('Transaction completed by ' + orderData.payer.name.given_name);
      });
    }
  }).render('#paypal-button-container');

2

Answers


  1. Chosen as BEST ANSWER

    This is what I added to my code for capturing a transaction to get the order's ID, right below require 'paypal-client.php';:

    // Get JSON row data from the request
    $json = file_get_contents('php://input');
    // Convert JSON string into array
    $data = json_decode($json, true);
    // Get the value of the key 'orderID'
    $orderId = $data['orderID'];
    

    I'm not sure if the comments explain exactly what is happening, so any correction would be most welcome.

    Also the JavaScript code is a bit different with this:

    body: JSON.stringify({
      orderID: data.orderID
    })
    

    added just below

    headers: {
      'content-type': 'application/json'
    },
    

    It's working now. Many thanks Preston PHX for pointing me in the right direction again.


  2. This is your problem line:

    CaptureOrder::captureOrder('$orderId', true);
    

    You are literally sending the text string inside the single quotes: ‘$orderId‘ to PayPal. The $ and those 7 letters are going to PayPal. You are not sending the contents of your $orderId variable.

    Get rid of your string quotes:

    CaptureOrder::captureOrder($orderId, true);
    

    By the way, a detail about PHP (and incidentally, shell languages like bash) you may not be aware of:

    Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.

    ref: https://www.php.net/manual/en/language.types.string.php#language.types.string.parsing

    Basically, double quotes and single quotes behave differently in this respect.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search