Обработка ошибок Fetch API в JavaScript: отображение ответа API во всплывающем окнеPhp

Кемеровские программисты php общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Обработка ошибок Fetch API в JavaScript: отображение ответа API во всплывающем окне

Сообщение Anonymous »

Я работаю над интеграцией платежей с использованием API Payway в приложении Symfony с шаблонами Twig. Когда я отправляю данные кредитной карты с истекшим сроком действия, API правильно возвращает ответ JSON, указывающий на ошибку. Однако вместо всплывающего окна с сообщением об ошибке полный ответ JSON отображается непосредственно на странице.
Вот ответ JSON от API, когда срок действия карты истек:
Вот ответ JSON от API, когда срок действия карты истек:
р>

Код: Выделить всё

json
Copy code
{
"error": "Payment failed",
"details": {
"transactionId": 3825557492,
"receiptNumber": "3825557492",
"status": "declined",
"responseCode": "54",
"responseText": "Expired card",
"transactionType": "payment",
"customerNumber": "DUMMYCUSTOMER123",
"customerName": "2566",
"orderNumber": "5240000123-061223",
"currency": "aud",
"principalAmount": 1000,
"surchargeAmount": 12,
"paymentAmount": 1012,
"paymentMethod": "creditCard",
"creditCard": {
"cardNumber": "456471...012",
"expiryDateMonth": "02",
"expiryDateYear": "25",
"cardScheme": "visa",
"cardType": "credit",
"cardholderName": "2566",
"panType": "fpan"
},
"merchant": {
"merchantId": "TEST",
"merchantName": "Test Merchant",
"links": [
{
"rel": "self",
"href": "https://api.payway.com.au/rest/v1/merchants/TEST"
}
]
},
"transactionDateTime": "25 Jul 2024 05:11 AEST",
"settlementDate": "25 Jul 2024",
"declinedDate": "25 Jul 2024",
"customerIpAddress": "127.0.0.1",
"isVoidable": false,
"isRefundable": false,
"links": [
{
"rel": "self",
"href": "https://api.payway.com.au/rest/v1/transactions/3825557492"
}
]
}
}
Цель:
Я хочу, чтобы в случае сбоя платежа отображалось всплывающее окно с конкретным сообщением об ошибке (например, «Срок действия карты истек»), а не переход на новую страницу с полным ответом в формате JSON.
Код:
Вот мой код JavaScript, который обрабатывает отправку формы и запрос на получение:

Код: Выделить всё

class ResponseError extends Error {
constructor(message, response) {
super(message);
this.response = response;
}
}

document.addEventListener('DOMContentLoaded', function() {
const creditCardForm = document.getElementById('creditCardForm');
const hiddenForm = document.getElementById('hiddenForm');
const submitButton = document.getElementById('submitButton');

creditCardForm.addEventListener('submit', async function(event) {
event.preventDefault();

// Disable the submit button to prevent multiple submissions
submitButton.disabled = true;
submitButton.innerText = 'Processing...';

const formData = new FormData(creditCardForm);

try {
const response = await fetch(creditCardForm.action, {
method: 'POST',
body: formData
});

if (!response.ok) {
throw new ResponseError('Failed to fetch', response);
}

const data = await response.json();

if (data.singleUseTokenId) {
document.getElementById('token').value = data.singleUseTokenId;
hiddenForm.submit();
} else {
alert('Unable to generate token.  Please try again.');
submitButton.disabled = false;
submitButton.innerText = 'Submit';
}
} catch (error) {
if (error instanceof ResponseError) {
const errorData = await error.response.json();
alert(`Error: ${errorData.details.responseText || 'Unknown error'}`);
} else {
console.error('Error:', error);
alert('An unexpected error occurred. Please try again.');
}
submitButton.disabled = false;
submitButton.innerText = 'Submit';
}
});
});
это метод контроллера для этой части:

Код: Выделить всё

  public function generateSingleUseToken(Request $request, int $id, HttpClientInterface $client, InvoiceRepository $invoiceRepository): JsonResponse
{
$cardNumber = $request->request->get('cardNumber');
$expiryDateMonth = $request->request->get('expiryDateMonth');
$expiryDateYear = $request->request->get('expiryDateYear');
$cvn = $request->request->get('cvn');
$cardholderName = $request->request->get('cardholderName');

try {
$response = $client->request('POST', $_ENV['PAYWAY_BASE_URL'] . '/single-use-tokens', [
'headers' => [
'Authorization' => 'Basic ' . base64_encode($_ENV['PAYWAY_PUBLISHABLE_KEY'] . ':'),
'Content-Type' => 'application/x-www-form-urlencoded',
],
'body' => http_build_query([
'paymentMethod' => 'creditCard',
'cardNumber' => $cardNumber,
'expiryDateMonth' => $expiryDateMonth,
'expiryDateYear' => $expiryDateYear,
'cvn' => $cvn,
'cardholderName' => $cardholderName
]),
]);

$data = $response->toArray(false);

if (!isset($data['singleUseTokenId'])) {
return new JsonResponse($data, 400);
}

return new JsonResponse(['singleUseTokenId' => $data['singleUseTokenId']]);

} catch (HttpExceptionInterface $e) {
$responseContent = $e->getResponse()->getContent(false);
$responseData = json_decode($responseContent, true);
return new JsonResponse($responseData, $e->getStatusCode());
} catch (\Exception $e) {
return new JsonResponse(['error' => 'An error occurred.', 'message' => $e->getMessage()], 500);
}
Проблема:
Несмотря на попытки правильно обработать ошибки, я продолжаю получать полный ответ JSON, отображаемый напрямую, а не специальное сообщение об ошибке. Что я здесь упускаю или делаю неправильно? Как я могу гарантировать, что конкретное сообщение об ошибке (например, «Срок действия карты истек») отображается во всплывающем окне?

Подробнее здесь: https://stackoverflow.com/questions/787 ... in-a-popup
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Php»