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
This is what I added to my code for capturing a transaction to get the order's ID, right below
require 'paypal-client.php';
: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:
added just below
It's working now. Many thanks Preston PHX for pointing me in the right direction again.
This is your problem line:
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:
By the way, a detail about PHP (and incidentally, shell languages like bash) you may not be aware of:
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.