Test Mode Only
Reader
Amount Due
—
Payment Declined
—
Waiting for transaction...
No reader found.
Run
stripe:test-payment
to provision a reader.
Reference
1 · Setup — Provision Location & Reader
POST /v1/terminal/locations
{
"display_name": "Laravel Test Location",
"address": {
"line1": "123 Test Street",
"city": "San Francisco",
"state": "CA",
"country": "US",
"postal_code": "94107"
}
}
→ Returns Location with id: "tml_xxx"
POST /v1/terminal/readers
{
"registration_code": "simulated-wpe",
"label": "Laravel Simulated Reader",
"location": "tml_xxx"
}
// Valid codes: simulated-wpe, simulated-s700, simulated-s710
→ Returns Reader with id: "tmr_xxx", status: "online"
2 · New Payment — Create & Send to Reader
POST /v1/payment_intents
{
"amount": 2500,
"currency": "usd",
"payment_method_types": ["card_present"],
"capture_method": "automatic"
}
// Header: Idempotency-Key:
→ Returns PaymentIntent with status: "requires_payment_method"
POST /v1/terminal/readers/{id}/process_payment_intent
{
"payment_intent": "pi_xxx"
}
→ Returns Reader object. PI transitions to requires_confirmation, reader waits for card tap.
3 · Simulate Card Tap (test mode only)
POST /v1/test_helpers/terminal/readers/{id}/present_payment_method
PHP: $stripe->testHelpers->terminal->readers->presentPaymentMethod()
Approved
{}
// card: 4242 4242 4242 4242
Webhook: payment_intent.succeeded
Declined
{
"type": "card_present",
"card_present": {
"number": "4000000000000002"
}
}
Webhook: payment_intent.payment_failed
PI resets to requires_payment_method
Insufficient Funds
{
"type": "card_present",
"card_present": {
"number": "4000000000009995"
}
}
Webhook: payment_intent.payment_failed
PI resets to requires_payment_method
Auth Required
{
"type": "card_present",
"card_present": {
"number": "4001000360000005"
}
}
Prompts online PIN on reader
4 · Retry Declined Card
After a decline the PI resets to requires_payment_method — it is still valid. No new PI needed. Re-send it to the reader and the customer taps a different card.
POST /v1/terminal/readers/{id}/process_payment_intent
{
"payment_intent": "pi_xxx" // same PI as the failed attempt
}
5 · Capture (manual capture_method only)
Only required when the PI was created with capture_method: "manual". With automatic Stripe captures after card confirmation with no API call.
POST /v1/payment_intents/{id}/capture
{} // no body required
→ PI moves to succeeded. Webhook: payment_intent.succeeded
6 · Cancel Payment
POST /v1/terminal/readers/{id}/cancel_action
{} // no body — clears reader display
→ Returns Reader object. Call this before cancelling the PI to free the reader.
POST /v1/payment_intents/{id}/cancel
{} // no body
→ PI moves to canceled. Webhook: payment_intent.canceled
7 · Reconcile (scheduler fallback for missed webhooks)
Run via php artisan stripe:reconcile. Compares local payment status against Stripe and syncs.
GET /v1/payment_intents/{id}
// No body — fetches latest PI state. // Key fields in response: status, last_payment_error.message
Incoming Webhooks (from Stripe → /api/stripe/webhook)
payment_intent.succeeded
PI captured. Order transitions to succeeded. Fired after automatic capture or manual capture call.
payment_intent.payment_failed
Card declined. Order stays processing — PI resets to requires_payment_method. Customer can retry with same PI.
payment_intent.canceled
Order transitions to canceled.