Я изо всех сил пытался высмеять проблему 'INSTRUMENT_DECLINED', которая, согласно Paypal, является обычной ошибкой после попытки захвата заказа (https://developer.paypal.com/demo/checkout/#/pattern/server).
Правильная установка заголовка для имитации ответа поможет мне смоделировать другие ошибки из документов https://developer.paypal.com/docs/business/test-and-go-live/simulation-tests/#orders.
Я использую серверную часть Laravel и интерфейсную часть React.
Я уже получил ожидаемый ложный ответ, используя axios и вызывая интерфейс:
return axios
.post(
`https://api-m.sandbox.paypal.com/v2/checkout/orders/${orderID}/capture`,
{},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + accessToken,
"PayPal-Mock-Response":
'{"mock_application_codes":"INSTRUMENT_DECLINED"}',
},
}
)
.then((res) => {
console.info(res);
})
Однако я не хочу раскрывать accessToken во внешнем интерфейсе, я бы предпочел делать все в фоновом режиме с помощью GuzzleHtttp.
У меня уже был положительный ответ - с 'status': 'COMPLETED'без добавления заголовка PayPal-Mock-Response вот так:
$client = new \GuzzleHttp\Client();
$response = $client->request(
'POST',
'https://api-m.sandbox.paypal.com/v2/checkout/orders/' . $paypalOrderId . '/capture',
[
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $access_token,
// 'PayPal-Mock-Response' => json_encode(["mock_application_codes" => "INSTRUMENT_DECLINED"]),
// 'PayPal-Mock-Response' => "['mock_application_codes':'INSTRUMENT_DECLINED]",
],
],
);
$data = json_decode($response->getBody(), true);
Но при добавлении заголовка PayPal-Mock-Response, как показано в закомментированном коде сверху, обе попытки вернули это исключение:
"message": "Client error:
POST https://api-m.sandbox.paypal.com/v2/checkout/orders/9HG50866FU785784C/captureresulted in a404 Not Foundresponse", "exception": "GuzzleHttp\Exception\ClientException", "file": "C:\xampp\htdocs\react\React-Laravel\vinos-gdl\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php",
Это исключение, я уверен, связано с тем, как я передаю заголовок PayPal-Mock-Response в HTTP-вызов Guzzle, но я не могу найти способ сделать это правильно.
Любая помощь очень ценится.
ОБНОВЛЕНИЕ РЕШЕНО **
Хорошо, можно отправить header следующим образом:
'PayPal-Mock-Response' => json_encode(["mock_application_codes" => "INSTRUMENT_DECLINED"]),
Не знаю, была ли у меня опечатка, но я наконец ее понял. Я также использовал INTERNAL_SERVER_ERROR для получения 500 response с сервера и построил catch для каждой ситуации:
} catch (ClientException $e) {
if ($e->hasResponse()) {
return response()->json([
'msg' => 'Client Exception',
'error' => json_decode($e->getResponse()->getBody()),
], 400);
}
return response()->json([
'msg' => 'Client Exception',
'request' => $e->getRequest(),
$e->hasResponse() ? $e->getResponse() : ""
]);
// return response()->json(['msg' => 'Server Error', 'error' => report($e)]);
} catch (BadResponseException $e) {
if ($e->hasResponse()) {
return response()->json([
'msg' => 'Uknown Exception',
'error' => json_decode($e->getResponse()->getBody()),
], 500);
}
return response()->json([
'msg' => 'Uknown Exception',
'request' => $e->getRequest(),
$e->hasResponse() ? $e->getResponse() : ""
]);
}
Спасибо тем, кто прокомментировал.
Да, отправка запроса curl работает, но это много беспорядка. Я бы предпочел протестировать с использованием серверной части ..
то вы также можете попробовать использовать опцию запроса json, docs.guzzlephp.org/en/latest/request-options.html#json






"PayPal-Mock-Response":
'{"mock_application_codes":"INSTRUMENT_DECLINED"}',
...
// 'PayPal-Mock-Response' => "['mock_application_codes':'INSTRUMENT_DECLINED]",
Есть разница между {} (объект JSON) и [] (массив JSON).
То, что у вас внутри скобок, не является массивом, поэтому его синтаксис недействителен. Это не соответствует тому, что ожидает PayPal, отсюда и 404.
код вопроса кажется правильным, поскольку я считаю, что @FerToasted использует любой из них, а json_encode предоставит данный формат, я считаю, что если он выдает 404, то $ orderId отсутствует в их записях или что-то вроде FerToasted может пытаться до того, как заказ будет установлен в PayPal
Нет, не $orderId, это именно response, который я получаю из метода createOrder, и при использовании того же $orderID при использовании метода без PayPal-Mock-Response метод работает правильно, так что речь идет о синтаксисе наверняка ...
Судя по всему, синтаксис этого заголовка не совсем обычный: stackoverflow.com/questions/51812242/…. Я попробую использовать разные комбинации, поскольку, похоже, требуется передать string вместо Json Object или Json Array.
Вы пытались отправить запрос curl через терминал, чтобы посмотреть, работает ли он, поскольку он отправляет 404