Test Stripe Terminal
Learn how to effectively test your Terminal integration.
Note
Much of the process for testing Stripe Terminal is similar to that for testing online Stripe payments. Also, you can’t use Stripe Terminal with mobile wallets (for example, Apple Pay or Google Pay) in testmode. For more information, see the general Stripe testing guide.
The best way to achieve a successful Terminal deployment is to test every part of your integration. We provide testing tools for each stage:
- Before ordering a reader, test your integration with the reader simulator.
- Test your complete hardware integration with a physical test card.
Simulated reader
Stripe Terminal SDKs and server-driven integration come with a built-in simulated card reader, so you can develop and test your app without connecting to physical hardware. Whether your integration is complete or you’re still building it, use the simulated reader to emulate all the Terminal flows in your app.
The simulated reader doesn’t provide a UI. After connecting to it in your app, you can see it working when calls to the Stripe SDK or API succeed.
Simulated readers for SDKs automatically simulate card presentment as needed. For the server-driven integration, update your integration to simulate card presentment.
Simulated test cards
The simulated reader can be configured to use a simulated test card, enabling you to test different flows within your point of sale application.
Before collecting a payment method, configure the simulated reader to use one of the following test card numbers or test payment methods to produce specific responses. Configuration set during the collect step (such as the test card number) is persisted for 30 minutes. This means a subsequent confirm step uses the same configuration, even if you don’t pass it again explicitly. Any configuration passed on the confirm call takes priority over the cached values from the collect step.
Standard test cards
| Test card number | Test payment method | Brand |
|---|---|---|
visa | Visa | |
visa_debit | Visa (debit) | |
mastercard | Mastercard | |
mastercard_debit | Mastercard (debit) | |
mastercard_prepaid | Mastercard (prepaid) | |
amex | American Express | |
amex2 | American Express | |
discover | Discover | |
discover2 | Discover | |
diners | Diners Club | |
diners_14digits | Diners Club (14 digit card) | |
jcb | JCB | |
unionpay | UnionPay | |
interac | Interac | |
eftpos_au_debit | eftpos Australia | |
eftpos_au_visa_debit | eftpos Australia/Visa | |
eftpos_au_mastercard_debit | eftpos Australia/Mastercard | |
cartes_bancaires_visa_debit | Cartes Bancaires (CB) / Visa | |
cartes_bancaires_mastercard_debit | Cartes Bancaires (CB) / Mastercard | |
girocard_debit | Girocard |
Test cards for specific success cases
| Test card number | Test payment method | Result |
|---|---|---|
offline_pin_cvm | Simulates the cardholder being prompted for and entering an offline PIN. The resulting charge has cardholder_verification_method set to offline_pin. | |
offline_pin_sca_retry | Simulates an SCA -triggered retry flow where a cardholder’s initial contactless charge fails and the reader then prompts the user to insert their card and enter their offline PIN. The resulting charge has cardholder_verification_method set to offline_pin. | |
online_pin_cvm | Simulates a cardholder being prompted for and entering an online PIN. The resulting charge has cardholder_verification_method set to online_pin. | |
online_pin_sca_retry | Simulates an SCA -triggered retry flow where a cardholder’s initial contactless charge fails and the reader then prompts the user to input their online PIN. The final charge has cardholder_verification_method set to online_pin. |
Test cards for specific error cases
Note
Using these specific cards for saving directly without charging and SetupIntents returns a setup_intent_authentication_failure response.
| Test card number | Test payment method | Result |
|---|---|---|
charge_declined | Charge is declined with a card_declined code. | |
charge_declined_insufficient_funds | Charge is declined with a card_declined code. The decline_code attribute is insufficient_funds. | |
charge_declined_lost_card | Charge is declined with a card_declined code. The decline_code attribute is lost_card. | |
charge_declined_stolen_card | Charge is declined with a card_declined code. The decline_code attribute is stolen_card. | |
charge_declined_expired_card | Charge is declined with an expired_card code. | |
charge_declined_processing_error | Charge is declined with a processing_error code. | |
refund_fail | Charge succeeds but refunding a captured charge fails asynchronously with a failure_reason of expired_or_canceled_card. Because refunds fail asynchronously, the refund appears successful at first, only returning the failed status in subsequent fetches. We also notify you of refund failures using the refund.failed webhook event. |
Simulated card presentment
When using the server-driven integration, use the present_payment_method endpoint to simulate a cardholder tapping or inserting their card on the reader.
Command Line
Select a language
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
{
"id": "tmr_xxx",
"object": "terminal.reader",
"action": {
"failure_code": null,
"failure_message": null,
"process_payment_intent": {
"payment_intent": "pi_xxx"
},
"status": "succeeded",
"type": "process_payment_intent"
},
…
}
If you don’t specify parameters, the simulated payment defaults to a valid test card based on the payment method type of the PaymentIntent. Below are the default test cards for Terminal payment method types:
| Payment method type | Test card number | Test payment method |
|---|---|---|
card_present | visa | |
card_present and interac_present | visa | |
interac_present | interac |
With the standard test cards, you can also use test amounts to simulate failure scenarios
Test reader update
Use reader software update scenarios to test how your integration handles updates. This works with simulated and physical mobile readers in a sandbox.
Set the testReaderUpdate property on BluetoothConnectionConfiguration, UsbConnectionConfiguration, or TapToPayConnectionConfiguration to trigger a reader update scenario during connection. This works with simulated and physical mobile readers, and with simulated Tap to Pay readers in a sandbox.
Create a TestReaderUpdate with one of the factory methods. You can optionally specify UpdateComponent values such as .firmware, .config, .keys, or .incremental.
| TestReaderUpdate | Result |
|---|---|
.available(components) | An optional update is available. Tell the user that an update is available and highlight the requiredAt date. |
.required(components) | A required update runs during connection. Your MobileReaderDelegate receives the didStartInstallingUpdate callback. |
.requiredOffline(components) | A required update exists. If you connect offline, the connection fails because the reader version isn’t allowed. If you connect online, the reader updates and connects normally. |
.lowBattery() | A required update exists, but the reader battery is too low to start the update. The connection fails. |
.lowBatterySucceedConnect() | A required update exists, but the reader battery is too low to start the update. The update fails, but the connection succeeds because the reader runs a recent software version. |
.random() | Randomly selects one of the preceding scenarios, or nil to simulate no available update. |
ConnectReaderViewController.swift
Select a language
Swift
Objective-C
No results
// Create a TestReaderUpdate to simulate a required update during connection
let testReaderUpdate = TestReaderUpdate.required([.firmware, .config])
let connectionConfig: BluetoothConnectionConfiguration
do {
connectionConfig = try BluetoothConnectionConfigurationBuilder(delegate: readerDelegate, locationId: "{{LOCATION_ID}}")
.setTestReaderUpdate(testReaderUpdate)
.build()
} catch {
// Handle the error building the connection configuration
return
}
Terminal.shared.connectReader(selectedReader, connectionConfig: connectionConfig) { reader, error in
if let reader = reader {
print("Successfully connected to reader: \(reader)")
} else if let error = error {
print("connectReader failed: \(error)")
}
}
Note
TapToPayConnectionConfiguration only supports the .required(components) scenario. Other types return an error.
Use the SimulatorConfiguration approach Deprecated
Caution
The simulatorConfiguration.availableReaderUpdate approach is deprecated as of SDK 5.5. Use the testReaderUpdate connection configuration property instead.
Set Terminal.shared.simulatorConfiguration.availableReaderUpdate to one of the following configurations. Calling connectReader triggers a simulated reader update. This only works with the simulated mobile reader.
| Update configuration | Result |
|---|---|
SimulateReaderUpdateNone | No update is available. |
SimulateReaderUpdateRequired | A required update is available and takes 1 minute. Your MobileReaderDelegate receives the didStartInstallingUpdate callback. |
SimulateReaderUpdateRequiredForOffline | A required update is overdue and takes 1 minute. If you operate offline, the reader can’t connect. Your MobileReaderDelegate receives the didStartInstallingUpdate callback. |
SimulateReaderUpdateAvailable | An optional update is available. Tell the user that an update is available and highlight the requiredAt date. |
SimulateReaderUpdateLowBattery | A required update starts to install but fails because the reader battery is low. The reader connection also fails. This simulates the reader running an older software version. |
SimulateReaderUpdateLowBatterySucceedConnect | A required update starts to install but fails because the reader battery is low. The reader still connects. This simulates the reader running a recent software version that’s still allowed. The update retries the next time you connect to the reader. |
SimulateReaderUpdateRandom | Randomly selects one of the preceding scenarios. |
Physical test cards
Test payments with your Stripe Terminal reader using a physical test card. You can purchase readers and physical test cards from the Terminal tab in the Stripe Dashboard. We also support physical test cards from providers, such as B2.
This physical test card supports both chip entry and contactless payments. It only works with Stripe’s pre-certified readers, and only against the Stripe API in a sandbox. If you attempt to use your physical test card in live mode, the Stripe API returns an error. Unless stated otherwise, use the PIN 1234 when prompted.
When creating payments using a physical test card, use amounts ending in the following decimal values to produce specific responses:
| Decimal | Result |
|---|---|
| 00 | Payment is approved. |
| 01 | Payment is declined with a call_issuer code. |
| 02 | When using readers featuring a cardholder-facing screen, insert (or tap, if supported) the test card. If the card requires a PIN, the payment declines with offline_pin_required and requests PIN entry if the reader supports chip entry. Enter 1234 to complete the test payment. |
| 03 | When using readers featuring a cardholder-facing screen, insert (or tap, if supported) the test card. If the card requires a PIN, the payment declines with online_or_offline_pin_required and requests PIN entry. Enter any 4-digit PIN to complete the test payment. |
| 05 | Payment is declined with an generic_decline code. |
| 55 | Payment is declined with an incorrect_pin code. |
| 65 | Payment is declined with an withdrawal_count_limit_exceeded code. |
| 75 | Payment is declined with an pin_try_exceeded code. |
For example, a payment processed using a physical test card for the amount _25.00 the related setting succeeds; a payment processed for the amount _10.05 the related setting is declined.
Note
Some currencies have zero decimal. For those currencies, use the two decimal digits in the table above as the rightmost two digits.
For example, to get your payment declined with generic_decline code, you need an amount of _105 the related setting.
Interac test cards Canada only
To test your Interac integration, you can use the simulated interac test card or an Interac physical test card. You can order it from the Terminal hardware shop in the Dashboard. You can’t use the Stripe-branded physical test card as an Interac card.
The Interac test card works for both interac_present payments and interac_present refunds. You can use the same test amounts you use for testing card_present payments. Unless stated otherwise, use the PIN 1234 when prompted. To test a declined refund, create a partial refund with an amount ending with the following decimal values: 01, 05, 55, 65, or 75.
Note
The Interac test card doesn’t support contactless payments.
eftpos test cards Australia only
To test your eftpos integration, you can use the simulated eftpos test card or an eftpos physical test card. You can order it from the Terminal hardware shop in the Dashboard. You can’t use the Stripe-branded physical test card as an eftpos card.
You can use the same test amounts you use for testing card_present payments. Unless stated otherwise, use the PIN 1234 when prompted.
