Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
24015a9
add stripe 3ds support
pbennett1-godaddy Sep 8, 2026
8de3a58
Merge branch 'main' into add-stripe-3ds-support
pbennett1-godaddy Sep 14, 2026
7aebf0c
address feedback
pbennett1-godaddy Sep 15, 2026
bfe4aea
Merge branch 'main' of https://github.com/godaddy/javascript into add…
pbennett1-godaddy Sep 15, 2026
58075ca
link stripe PI to session gate
pbennett1-godaddy Sep 16, 2026
7a6aa3b
add stripe provider to track intents
pbennett1-godaddy Sep 17, 2026
8e5ae46
Fix Stripe duplicate submission locking
pbennett1-godaddy Sep 21, 2026
5dc1c06
Merge branch 'main' into add-stripe-3ds-support
pbennett1-godaddy Sep 21, 2026
c0cd13b
Ignore duplicate Stripe submissions without throwing
pbennett1-godaddy Sep 21, 2026
90e5c1c
Track Stripe express completion with its supplied payment type
pbennett1-godaddy Sep 21, 2026
2816911
Name Stripe express completion events by payment type
pbennett1-godaddy Sep 21, 2026
2e675ac
Use generic express completion event with payment type
pbennett1-godaddy Sep 21, 2026
fd268c0
Redirect checkout when the loaded order is already paid
pbennett1-godaddy Sep 21, 2026
593918c
Refresh paid order status after uncertain checkout confirmation
pbennett1-godaddy Sep 21, 2026
602d407
Merge branch 'main' into add-stripe-3ds-support
pbennett1-godaddy Sep 21, 2026
b198638
Merge main and preserve 3DS recovery alongside checkout tips
pbennett1-godaddy Sep 22, 2026
1e48cd2
Handle Stripe verification for express checkout
pbennett1-godaddy Sep 22, 2026
ff4c9ac
adjust PI handling for stripe
pbennett1-godaddy Sep 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/bright-cards-handle-3ds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@godaddy/react': patch
'@godaddy/localizations': patch
---

Add Stripe 3DS verification support for card and express checkout, with localized payment errors and compatibility with existing checkout error handling.

Improve payment retry handling, prevent duplicate submissions, and recognize already-paid orders. Update express payment tracking to reflect the payment method used and successful checkout completion.
2 changes: 2 additions & 0 deletions packages/localizations/src/deDe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ export const deDe = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Abrufen der Bestellung fehlgeschlagen',
DATA_SOURCES_NOT_FOUND: 'Datenquellen nicht gefunden',
TRANSACTION_API_NOT_FOUND: 'Transaktions-API-Datenquelle nicht gefunden',
PAYMENT_ACTION_REQUIRED:
'Deine Zahlung erfordert eine zusätzliche Bestätigung. Versuche es erneut oder wähle eine andere Zahlungsmethode.',
TRANSACTION_PROCESSING_FAILED:
'Verarbeitung der Transaktion fehlgeschlagen',
TRANSACTION_CREATION_FAILED:
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/enAu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const enAu = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Failed to retrieve order',
DATA_SOURCES_NOT_FOUND: 'Data sources not found',
TRANSACTION_API_NOT_FOUND: 'Transaction API data source not found',
PAYMENT_ACTION_REQUIRED:
'Your payment needs additional verification. Please try again or choose another payment method.',
TRANSACTION_PROCESSING_FAILED: 'Failed to process transaction',
TRANSACTION_CREATION_FAILED: 'Failed to find or create transaction',
ORDER_OPENING_FAILED: 'Failed to open order',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/enIe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const enIe = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Failed to retrieve order',
DATA_SOURCES_NOT_FOUND: 'Data sources not found',
TRANSACTION_API_NOT_FOUND: 'Transaction API data source not found',
PAYMENT_ACTION_REQUIRED:
'Your payment needs additional verification. Please try again or choose another payment method.',
TRANSACTION_PROCESSING_FAILED: 'Failed to process transaction',
TRANSACTION_CREATION_FAILED: 'Failed to find or create transaction',
ORDER_OPENING_FAILED: 'Failed to open order',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/enUs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const enUs = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Failed to retrieve order',
DATA_SOURCES_NOT_FOUND: 'Data sources not found',
TRANSACTION_API_NOT_FOUND: 'Transaction API data source not found',
PAYMENT_ACTION_REQUIRED:
'Your payment needs additional verification. Please try again or choose another payment method.',
TRANSACTION_PROCESSING_FAILED: 'Failed to process transaction',
TRANSACTION_CREATION_FAILED: 'Failed to find or create transaction',
ORDER_OPENING_FAILED: 'Failed to open order',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esAr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ export const esAr = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de API de transacciones no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'Error al procesar transacción',
TRANSACTION_CREATION_FAILED: 'Error al encontrar o crear transacción',
ORDER_OPENING_FAILED: 'Error al abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esCl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ export const esCl = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de API de transacción no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'Error al procesar transacción',
TRANSACTION_CREATION_FAILED: 'Error al encontrar o crear transacción',
ORDER_OPENING_FAILED: 'Error al abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esCo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ export const esCo = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de API de transacciones no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'Error al procesar transacción',
TRANSACTION_CREATION_FAILED: 'Error al encontrar o crear transacción',
ORDER_OPENING_FAILED: 'Error al abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esEs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ export const esEs = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de la API de transacciones no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'No se pudo procesar la transacción',
TRANSACTION_CREATION_FAILED: 'No se pudo encontrar o crear la transacción',
ORDER_OPENING_FAILED: 'No se pudo abrir el pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esMx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ export const esMx = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de API de transacciones no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'Error al procesar transacción',
TRANSACTION_CREATION_FAILED: 'Error al encontrar o crear transacción',
ORDER_OPENING_FAILED: 'Error al abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esPe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ export const esPe = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de API de transacciones no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'Error al procesar transacción',
TRANSACTION_CREATION_FAILED: 'Error al encontrar o crear transacción',
ORDER_OPENING_FAILED: 'Error al abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/esUs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ export const esUs = {
DATA_SOURCES_NOT_FOUND: 'Fuentes de datos no encontradas',
TRANSACTION_API_NOT_FOUND:
'Fuente de datos de Transaction API no encontrada',
PAYMENT_ACTION_REQUIRED:
'Tu pago requiere una verificación adicional. Inténtalo de nuevo o elige otro método de pago.',
TRANSACTION_PROCESSING_FAILED: 'Error al procesar transacción',
TRANSACTION_CREATION_FAILED: 'Error al encontrar o crear transacción',
ORDER_OPENING_FAILED: 'Error al abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/frCa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ export const frCa = {
DATA_SOURCES_NOT_FOUND: 'Sources de données introuvables',
TRANSACTION_API_NOT_FOUND:
'Source de données API de transaction introuvable',
PAYMENT_ACTION_REQUIRED:
'Votre paiement nécessite une vérification supplémentaire. Réessayez ou choisissez un autre moyen de paiement.',
TRANSACTION_PROCESSING_FAILED: 'Échec du traitement de la transaction',
TRANSACTION_CREATION_FAILED:
'Échec de la recherche ou création de transaction',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/frFr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ export const frFr = {
DATA_SOURCES_NOT_FOUND: 'Sources de données non trouvées',
TRANSACTION_API_NOT_FOUND:
"Source de données de l'API de transaction non trouvée",
PAYMENT_ACTION_REQUIRED:
'Votre paiement nécessite une vérification supplémentaire. Réessayez ou choisissez un autre moyen de paiement.',
TRANSACTION_PROCESSING_FAILED: 'Échec du traitement de la transaction',
TRANSACTION_CREATION_FAILED:
'Échec de la recherche ou de la création de la transaction',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/idId.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const idId = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Gagal mengambil pesanan',
DATA_SOURCES_NOT_FOUND: 'Sumber data tidak ditemukan',
TRANSACTION_API_NOT_FOUND: 'Sumber data API transaksi tidak ditemukan',
PAYMENT_ACTION_REQUIRED:
'Pembayaran Anda memerlukan verifikasi tambahan. Coba lagi atau pilih metode pembayaran lain.',
TRANSACTION_PROCESSING_FAILED: 'Gagal memproses transaksi',
TRANSACTION_CREATION_FAILED: 'Gagal menemukan atau membuat transaksi',
ORDER_OPENING_FAILED: 'Gagal membuka pesanan',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/itIt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ export const itIt = {
DRAFT_ORDER_RETRIEVAL_FAILED: "Errore nel recupero dell'ordine",
DATA_SOURCES_NOT_FOUND: 'Fonti dati non trovate',
TRANSACTION_API_NOT_FOUND: 'Fonte dati API transazioni non trovata',
PAYMENT_ACTION_REQUIRED:
'Il pagamento richiede una verifica aggiuntiva. Riprova o scegli un altro metodo di pagamento.',
TRANSACTION_PROCESSING_FAILED: "Errore nell'elaborazione della transazione",
TRANSACTION_CREATION_FAILED:
'Errore nella ricerca o creazione della transazione',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/ptBr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ export const ptBr = {
DATA_SOURCES_NOT_FOUND: 'Fontes de dados não encontradas',
TRANSACTION_API_NOT_FOUND:
'Fonte de dados da API de transação não encontrada',
PAYMENT_ACTION_REQUIRED:
'Seu pagamento precisa de uma verificação adicional. Tente novamente ou escolha outra forma de pagamento.',
TRANSACTION_PROCESSING_FAILED: 'Falha ao processar transação',
TRANSACTION_CREATION_FAILED: 'Falha ao encontrar ou criar transação',
ORDER_OPENING_FAILED: 'Falha ao abrir pedido',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/qaPs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ export const qaPs = {
DRAFT_ORDER_RETRIEVAL_FAILED: '[Fâîlëd ţö rëţrîëvë ördër]',
DATA_SOURCES_NOT_FOUND: '[Dâţâ šöürçëš ñöţ föüñd îñ šÿšţëm]',
TRANSACTION_API_NOT_FOUND: '[Ţrâñšâçţîöñ ÂÞÎ dâţâ šöürçë ñöţ föüñd]',
PAYMENT_ACTION_REQUIRED:
'[Your payment needs additional verification. Please try again or choose another payment method.]',
TRANSACTION_PROCESSING_FAILED: '[Fâîlëd ţö þröçëšš ţrâñšâçţîöñ]',
TRANSACTION_CREATION_FAILED: '[Fâîlëd ţö fîñd ör çrëâţë ţrâñšâçţîöñ]',
ORDER_OPENING_FAILED: '[Fâîlëd ţö öþëñ ördër fôr þröçëššîñg]',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/trTr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ export const trTr = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Sipariş alınamadı',
DATA_SOURCES_NOT_FOUND: 'Veri kaynakları bulunamadı',
TRANSACTION_API_NOT_FOUND: 'İşlem API veri kaynağı bulunamadı',
PAYMENT_ACTION_REQUIRED:
'Ödemeniz için ek doğrulama gerekiyor. Lütfen tekrar deneyin veya başka bir ödeme yöntemi seçin.',
TRANSACTION_PROCESSING_FAILED: 'İşlem işlenemedi',
TRANSACTION_CREATION_FAILED: 'İşlem bulunamadı veya oluşturulamadı',
ORDER_OPENING_FAILED: 'Sipariş açılamadı',
Expand Down
2 changes: 2 additions & 0 deletions packages/localizations/src/viVn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ export const viVn = {
DRAFT_ORDER_RETRIEVAL_FAILED: 'Không thể truy xuất đơn hàng',
DATA_SOURCES_NOT_FOUND: 'Không tìm thấy nguồn dữ liệu',
TRANSACTION_API_NOT_FOUND: 'Không tìm thấy nguồn dữ liệu API giao dịch',
PAYMENT_ACTION_REQUIRED:
'Thanh toán của bạn cần được xác minh thêm. Vui lòng thử lại hoặc chọn phương thức thanh toán khác.',
TRANSACTION_PROCESSING_FAILED: 'Không thể xử lý giao dịch',
TRANSACTION_CREATION_FAILED: 'Không thể tìm hoặc tạo giao dịch',
ORDER_OPENING_FAILED: 'Không thể mở đơn hàng',
Expand Down
1 change: 1 addition & 0 deletions packages/localizations/src/zhCn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ export const zhCn = {
DRAFT_ORDER_RETRIEVAL_FAILED: '获取订单失败',
DATA_SOURCES_NOT_FOUND: '数据源未找到',
TRANSACTION_API_NOT_FOUND: '交易 API 数据源未找到',
PAYMENT_ACTION_REQUIRED: '您的付款需要额外验证。请重试或选择其他付款方式。',
TRANSACTION_PROCESSING_FAILED: '处理交易失败',
TRANSACTION_CREATION_FAILED: '查找或创建交易失败',
ORDER_OPENING_FAILED: '打开订单失败',
Expand Down
1 change: 1 addition & 0 deletions packages/localizations/src/zhSg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ export const zhSg = {
DRAFT_ORDER_RETRIEVAL_FAILED: '检索订单失败',
DATA_SOURCES_NOT_FOUND: '数据源未找到',
TRANSACTION_API_NOT_FOUND: '交易API数据源未找到',
PAYMENT_ACTION_REQUIRED: '您的付款需要额外验证。请重试或选择其他付款方式。',
TRANSACTION_PROCESSING_FAILED: '处理交易失败',
TRANSACTION_CREATION_FAILED: '查找或创建交易失败',
ORDER_OPENING_FAILED: '打开订单失败',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { fireEvent, screen, waitFor } from '@testing-library/react';
import { act, fireEvent, screen, waitFor } from '@testing-library/react';
import { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { describe, expect, it } from 'vitest';
import { describe, expect, it, vi } from 'vitest';
import { useCheckoutContext } from '@/components/checkout/checkout';
import { DeliveryMethods } from '@/components/checkout/delivery/delivery-methods';
import {
isCheckoutConfirmationBlockedError,
PaymentProvider,
useConfirmCheckout,
} from '@/components/checkout/payment/utils/use-confirm-checkout';
import { confirmCheckout, getDraftOrder } from '@/lib/godaddy/godaddy';
import { GraphQLErrorWithCodes } from '@/lib/graphql-with-errors';
import {
buildCheckoutSession,
Expand All @@ -19,6 +20,7 @@ import {
clearOperations,
getOperations,
mockGodaddyApi,
mockWindowLocation,
type RenderCheckoutOptions,
renderCheckout,
setApiError,
Expand Down Expand Up @@ -346,6 +348,47 @@ describe('Checkout confirm errors', () => {
expect(window.location.href).not.toContain('should-not-go-here');
});

it('refreshes after a lost confirmation response and redirects the paid order', async () => {
mockWindowLocation();
const successUrl = 'https://merchant.example/success';
const { session, user } = renderCheckoutWithConfirmSeam(
{
sessionOverrides: { ...offlineSessionOverrides(), successUrl },
},
{
isExpress: true,
paymentType: 'offline',
paymentProvider: PaymentProvider.OFFLINE,
}
);
await waitForCheckoutReady();
vi.mocked(confirmCheckout).mockImplementationOnce(async () => {
vi.mocked(getDraftOrder).mockResolvedValue({
checkoutSession: {
...session,
draftOrder: buildDraftOrder({
statuses: { status: 'OPEN', paymentStatus: 'PAID' },
}),
},
});
throw new Error('Confirmation response lost');
});
await user.click(
await screen.findByRole('button', { name: /confirm seam/i })
);
expect(await screen.findByRole('status')).toHaveTextContent(
'Payment successful'
);
expect(
screen.queryByRole('button', { name: /confirm seam/i })
).not.toBeInTheDocument();
await act(async () => {
await vi.advanceTimersByTimeAsync(1100);
});
expect(window.location.href).toBe(successUrl);
expect(confirmCheckout).toHaveBeenCalledTimes(1);
});

it('surfaces DRAFT_ORDER_UPDATE_FAILED when the in-confirm draft-order fetch fails', async () => {
const draftOrder = buildDraftOrder();
const session = buildCheckoutSession({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ describe('CheckoutErrorList', () => {
expect(screen.getByText('CUSTOM_RAW_CODE')).toBeInTheDocument();
});

it('renders a localized action-required message', () => {
renderErrorList({ checkoutErrors: ['PAYMENT_ACTION_REQUIRED'] });
expect(
screen.getByText(enUs.apiErrors.PAYMENT_ACTION_REQUIRED)
).toBeInTheDocument();
expect(
screen.queryByText('PAYMENT_ACTION_REQUIRED')
).not.toBeInTheDocument();
});

it('renders checkout disabled copy with checkout errors', () => {
renderErrorList({
checkoutErrors: ['TRANSACTION_PROCESSING_FAILED'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { act, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { checkoutQueryKeys } from '@/components/checkout/utils/query-keys';
import {
buildDraftOrder,
getOperations,
mockWindowLocation,
renderCheckout,
waitForCheckoutReady,
} from './checkout-test-env';

describe('Checkout paid-order recovery', () => {
beforeEach(() => {
mockWindowLocation();
});

it('redirects a paid order to the session success URL without showing payment controls', async () => {
const successUrl = 'https://merchant.example/success';
renderCheckout({
sessionOverrides: { successUrl },
draftOrderOverrides: {
statuses: { status: 'OPEN', paymentStatus: 'PAID' },
},
});

expect(await screen.findByRole('status')).toHaveTextContent(
'Payment successful'
);
expect(
screen.queryByRole('button', { name: /pay now/i })
).not.toBeInTheDocument();
await act(async () => {
await vi.advanceTimersByTimeAsync(1100);
});
expect(window.location.href).toBe(successUrl);
expect(getOperations('ConfirmCheckoutSession')).toHaveLength(0);
});

it('keeps payment controls hidden when a paid order has no success URL', async () => {
const initialUrl = window.location.href;
renderCheckout({
draftOrderOverrides: {
statuses: { status: 'OPEN', paymentStatus: 'PAID' },
},
});

expect(await screen.findByRole('status')).toHaveTextContent(
'Payment successful'
);
await act(async () => {
await vi.advanceTimersByTimeAsync(1100);
});
expect(window.location.href).toBe(initialUrl);
expect(
screen.queryByRole('button', { name: /pay now/i })
).not.toBeInTheDocument();
});

it.each(['UNPAID', 'PENDING'])(
'does not redirect an order whose payment status is %s',
async paymentStatus => {
const initialUrl = window.location.href;
renderCheckout({
sessionOverrides: { successUrl: 'https://merchant.example/success' },
draftOrderOverrides: { statuses: { paymentStatus } },
});
await waitForCheckoutReady();
await act(async () => {
await vi.advanceTimersByTimeAsync(1100);
});
expect(window.location.href).toBe(initialUrl);
expect(screen.queryByText('Payment successful')).not.toBeInTheDocument();
}
);

it('uses the loaded order status when the session snapshot is still unpaid', async () => {
const successUrl = 'https://merchant.example/success';
const { queryClient, session } = renderCheckout({
sessionOverrides: { successUrl },
draftOrderOverrides: { statuses: { paymentStatus: 'UNPAID' } },
});
await waitForCheckoutReady();
act(() => {
queryClient.setQueryData(checkoutQueryKeys.draftOrder(session.id), {
checkoutSession: {
...session,
draftOrder: buildDraftOrder({
statuses: { status: 'OPEN', paymentStatus: 'PAID' },
}),
},
});
});
expect(await screen.findByRole('status')).toHaveTextContent(
'Payment successful'
);
await act(async () => {
await vi.advanceTimersByTimeAsync(1100);
});
expect(window.location.href).toBe(successUrl);
});
});
Loading
Loading