From 625d6adb2aa6d26e377b6054572160fc9a41f712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Wed, 5 Nov 2025 22:53:23 +0100 Subject: [PATCH] feat(online-payments): test cards for sandboxes --- src/components/TestCards/TestCards.astro | 196 ++++++ src/components/TestCards/index.ts | 1 + src/content/docs/online-payments/testing.mdx | 83 +++ src/lib/testCards.tsx | 632 +++++++++++++++++++ 4 files changed, 912 insertions(+) create mode 100644 src/components/TestCards/TestCards.astro create mode 100644 src/components/TestCards/index.ts create mode 100644 src/content/docs/online-payments/testing.mdx create mode 100644 src/lib/testCards.tsx 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.brand} + {card.name} + {card.returnsMethodData && ( + Method Data + )} +
+
+ {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, + }, +];