diff --git a/src/components/TestCards/TestCards.astro b/src/components/TestCards/TestCards.astro
new file mode 100644
index 00000000..83a9470e
--- /dev/null
+++ b/src/components/TestCards/TestCards.astro
@@ -0,0 +1,196 @@
+---
+import { getIconURL } from "@sumup-oss/icons";
+import { testCards } from "../../lib/testCards";
+
+const successCards = testCards.filter((card) => !card.error && !card.challenge);
+const challengeCards = testCards.filter((card) => card.challenge);
+const errorCards = testCards.filter((card) => card.error);
+
+const sections = [
+ { title: "Successful Transactions", cards: successCards },
+ { title: "3DS Challenge Flows", cards: challengeCards },
+ { title: "Error Cases", cards: errorCards },
+];
+---
+
+
+ {
+ sections.map(({ title, cards }) => (
+
+
{title}
+
+ {cards.map((card) => (
+
+
+
+ {card.number}
+
+
+
{card.description}
+
+ ))}
+
+
+ ))
+ }
+
+
+
+
+
diff --git a/src/components/TestCards/index.ts b/src/components/TestCards/index.ts
new file mode 100644
index 00000000..3884cdfb
--- /dev/null
+++ b/src/components/TestCards/index.ts
@@ -0,0 +1 @@
+export { default as TestCards } from "./TestCards.astro";
diff --git a/src/content/docs/online-payments/testing.mdx b/src/content/docs/online-payments/testing.mdx
new file mode 100644
index 00000000..5a9c66d3
--- /dev/null
+++ b/src/content/docs/online-payments/testing.mdx
@@ -0,0 +1,83 @@
+---
+title: Testing
+description: Learn how to test online payments using sandbox accounts and test cards with different 3D Secure flows.
+sidebar:
+ order: 6
+---
+
+import { Aside, Steps } from '@astrojs/starlight/components';
+import { TestCards } from '@components/TestCards';
+
+Testing your online payments integration is crucial before going live. SumUp provides sandbox test accounts and a comprehensive set of test cards to simulate various payment scenarios, including different 3D Secure authentication flows.
+
+## Setting up a Test Account
+
+Before you can test online payments, you need to create a test account in the SumUp Dashboard.
+
+
+
+1. Log in to your SumUp account.
+
+2. Open the drop-down menu between Support and your user panel.
+
+3. Select **Test Account**. Your merchant account is now switched to test mode.
+
+
+
+
+
+## Test Card Details
+
+When testing with card payments, you can use the following common details for all test cards:
+
+- **CVV**: Any 3 digits (e.g., `123`)
+- **Expiry Date**: Any future date (e.g., `12/25`)
+- **Cardholder Name**: Any name
+
+## Testing Failed Transactions
+
+To test failed transactions with your test account, create a checkout with an amount of `11` in any currency. This will always result in a failed transaction, allowing you to test your error handling logic.
+
+
+
+## Test Cards by Card Scheme
+
+Use the test cards below to simulate different payment scenarios and 3D Secure flows. Each card is designed to trigger specific authentication behaviors:
+
+- **Frictionless**: Authentication completes without user interaction
+- **Challenge**: Requires user authentication (e.g., entering a code or using biometrics)
+- **Error**: Simulates various error conditions
+
+
+
+## Understanding 3D Secure Test Responses
+
+When testing with these cards, you'll encounter different 3D Secure transaction statuses:
+
+- **TransactionStatus=Y**: Authentication successful
+- **TransactionStatus=A**: Authentication attempted (issuer or cardholder not participating)
+- **TransactionStatus=N**: Authentication failed
+- **TransactionStatus=U**: Technical error during authentication
+
+The **ECI (Electronic Commerce Indicator)** values vary by card scheme:
+- **ECI=05**: Full authentication (Visa, Amex, Discover, JCB)
+- **ECI=02**: Full authentication (Mastercard, Maestro)
+- **ECI=06**: Attempted authentication (Visa, Amex, Discover, JCB)
+- **ECI=01**: Attempted authentication (Mastercard, Maestro)
+
+## Next Steps
+
+Once you've thoroughly tested your integration with sandbox accounts and test cards:
+
+1. Switch back to your live account in the Dashboard
+2. Ensure your production credentials are properly configured
+3. Process a small real transaction to verify everything works as expected
+4. Monitor your first transactions closely to ensure proper payment processing
+
+
diff --git a/src/lib/testCards.tsx b/src/lib/testCards.tsx
new file mode 100644
index 00000000..12c4c43a
--- /dev/null
+++ b/src/lib/testCards.tsx
@@ -0,0 +1,632 @@
+export const testCards: {
+ brand:
+ | "visa"
+ | "mastercard"
+ | "maestro"
+ | "american_express"
+ | "discover"
+ | "jcb";
+ number: string;
+ name: string;
+ description: string;
+ returnsMethodData: boolean;
+ error: boolean;
+ challenge: boolean;
+}[] = [
+ // Successful transactions
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0091",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0109",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, TransactionStatus=A)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0026",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, TransactionStatus=Y)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0059",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, TransactionStatus=A)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0007",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0023",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0056",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0106",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6761 3010 0099 3772",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6706 9811 1111 1113",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6799 8510 0000 0032",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6007 9301 2345 6780",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3745 0026 2001 008",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3772 7708 1382 243",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3759 8700 0000 062",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3739 5319 2351 004",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "3617 7580 6770 72",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "6011 0004 0000 1008",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "6011 0100 0000 0003",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "6011 0009 9009 9818",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3530 1113 3330 0000",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3566 0020 2036 0505",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: true,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3569 9900 1227 8361",
+ name: "Successful Frictionless",
+ description:
+ "Successful frictionless authentication (ECI=05, ECI=02 for Mastercard, TransactionStatus=Y)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3569 9900 1227 8353",
+ name: "Frictionless Attempt",
+ description: "Attempt (ECI=06, ECI=01 for Mastercard, TransactionStatus=A)",
+ returnsMethodData: false,
+ error: false,
+ challenge: false,
+ },
+
+ // 3DS Challenge flows
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0042",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0067",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0018",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "visa",
+ number: "4200 0000 0000 0075",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0015",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0049",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0064",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "mastercard",
+ number: "5200 0000 0000 0072",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "maestro",
+ number: "6799 9989 0000 0060 018",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "maestro",
+ number: "6773 6700 0911 4879",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "maestro",
+ number: "6703 4200 5545 6501 5",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "maestro",
+ number: "6759 8888 8888 8888",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "american_express",
+ number: "3434 3434 3434 343",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "american_express",
+ number: "3759 8700 0000 021",
+ name: "Challenge Flow",
+ description: "Card that requires 3D D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "american_express",
+ number: "3759 8700 0169 867",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "american_express",
+ number: "3714 4963 5398 431",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "discover",
+ number: "3625 9600 0000 04",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "discover",
+ number: "6011 2087 0111 7775",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "discover",
+ number: "6559 9065 5990 6557",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "discover",
+ number: "3645 8811 1111 19",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "jcb",
+ number: "3566 0023 4543 2153",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "jcb",
+ number: "3569 9900 1009 5916",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: true,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "jcb",
+ number: "3569 9900 1230 0876",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+ {
+ brand: "jcb",
+ number: "3569 9900 1230 0884",
+ name: "Challenge Flow",
+ description: "Card that requires 3D Secure authentication with challenge",
+ returnsMethodData: false,
+ error: false,
+ challenge: true,
+ },
+
+ // Error cases
+ {
+ brand: "visa",
+ number: "4012 0010 3746 1114",
+ name: "Technical Error",
+ description: "Technical Error (no ECI, TransactionStatus=U)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "visa",
+ number: "4012 0010 3714 1112",
+ name: "User Not Enrolled",
+ description: "User not enrolled (ECI=06, TransactionStatus=N)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "visa",
+ number: "4532 4970 8877 1651",
+ name: "Card Not Participating",
+ description: "Card not participating in 3D Secure",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5434 5800 0000 0006",
+ name: "Technical Error",
+ description: "Technical Error (no ECI, TransactionStatus=U)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5457 3500 7654 3210",
+ name: "User Not Enrolled",
+ description:
+ "User not enrolled (ECI=06, ECI=01 for Mastercard, TransactionStatus=N)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "mastercard",
+ number: "5497 2608 4731 6287",
+ name: "Card Not Participating",
+ description: "Card not participating in 3D Secure",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6761 3010 0094 1201",
+ name: "Technical Error",
+ description: "Technical Error (no ECI, TransactionStatus=U)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6761 3010 0094 6341",
+ name: "User Not Enrolled",
+ description:
+ "User not enrolled (ECI=06, ECI=01 for Mastercard, TransactionStatus=N)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "maestro",
+ number: "6761 2577 0783 6567",
+ name: "Card Not Participating",
+ description: "Card not participating in 3D Secure",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3759 8700 0169 875",
+ name: "Technical Error",
+ description: "Technical Error (no ECI, TransactionStatus=U)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3759 8700 0169 883",
+ name: "User Not Enrolled",
+ description:
+ "User not enrolled (ECI=06, ECI=01 for Mastercard, TransactionStatus=N)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "american_express",
+ number: "3439 2309 2050 144",
+ name: "Card Not Participating",
+ description: "Card not participating in 3D Secure",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "6510 0000 0000 1248",
+ name: "Technical Error",
+ description: "Technical Error (no ECI, TransactionStatus=U)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "6011 0255 0026 5831",
+ name: "User Not Enrolled",
+ description:
+ "User not enrolled (ECI=06, ECI=01 for Mastercard, TransactionStatus=N)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "discover",
+ number: "6011 4207 1174 6440",
+ name: "Card Not Participating",
+ description: "Card not participating in 3D Secure",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3566 0077 7001 7510",
+ name: "Technical Error",
+ description: "Technical Error (no ECI, TransactionStatus=U)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3569 9900 1229 1497",
+ name: "User Not Enrolled",
+ description:
+ "User not enrolled (ECI=06, ECI=01 for Mastercard, TransactionStatus=N)",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+ {
+ brand: "jcb",
+ number: "3096 0233 6337 9943",
+ name: "Card Not Participating",
+ description: "Card not participating in 3D Secure",
+ returnsMethodData: false,
+ error: true,
+ challenge: false,
+ },
+];