Can't refund order using Paypal API

Viewed 843

I'm integrating PayPal using PHP and cURL and managed to create orders and capture the payments via the https://api.sandbox.paypal.com/v2/checkout/orders and https://api.sandbox.paypal.com/v2/checkout/orders/<order_id>/capture endpoints

The orders I'm trying to refund have been successfully captured and looking at the details it shows their status is "COMPLETED" and the final_capture field is true, so the order has been placed and I can see the transaction ended successfully in the merchant account

Now I'm trying to test refunds using the capture ID I get from the capture call but it always fails with an error with the following response body { "error":"invalid_subject", "error_description":"Subject Authentication failed" }

I tracked down the problem behind the Subject Authentication failed problem being a wrong Paypal-Auth-Assertion header, that I printed and double checked multiple times already and it seems to be right. Here's the code I use to make the call

// Codeigniter function to read from $_POST
$capture_id = $this->input->post('paypal_capture_id');

$auth_1 = base64_encode("{\"alg\":\"none\"}");
$auth_2 = base64_encode("{\"payer_id\":<payer_id>,\"iss\":<client_id>}");
$auth_assertion_header = $auth_1 . "." . $auth_2 . ".";


$curlSES=curl_init(); 
curl_setopt($curlSES,CURLOPT_URL,"https://api.sandbox.paypal.com/v2/payments/captures/$capture_id/refund");
curl_setopt($curlSES, CURLOPT_POST, true);
curl_setopt($curlSES, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Authorization: Bearer '. $access_token,
    'PayPal-Auth-Assertion:' . $auth_assertion_header 
));
curl_setopt($curlSES, CURLOPT_POSTFIELDS, '{}'); // empty payload means full refund
curl_setopt($curlSES, CURLOPT_RETURNTRANSFER, true);

$result=curl_exec($curlSES);

Where payer_id and client_id are filled using a merchant id account used for the sandbox environment and the client_id is the secret id for the application provided by Paypal, the $access_token has been previously generated from a function I use in other parts of the application and it works fine.

Furthermore, if I try to make the same call using Postman (and the PayPal API explorer as well) it produces a different error, that is

{
  "error": "invalid_request",
  "error_description": "No permissions to set target_client_id"
}

No search result for this error is really helpful so I'm lost on what I'm doing wrong there, although it doesn't seem related to the Paypal-Auth-Assertion as it falls back to the Subject Authentication failed error if I provide a wrong value on purpose.

1 Answers

I was facing the same issue, when trying to refund a captured order for a partner account. It seems to me u are using the string escaped json from the example. Try using the json_encode function like below:

$header = base64_encode(json_encode(['alg' => 'none']));
$body = base64_encode(json_encode(['payer_id' => $merchantId, 'iss' => $clientId]));
$authHeader = $header . "." . $body . ".";

I was able to refund a captured order with this $authHeader.

Greetings

Related