Preview: SendMock has no stable release yet. These docs follow develop.
SendMock
Payments

Payments

Test checkouts for Stripe, PayPal, SSLCommerz and bKash with real redirects and notifications, and every payment with its timeline and Simulate menu.

Try it in the demo.

SendMock is a fake payment gateway. Your app creates a payment through the gateway's real API; SendMock answers like the gateway, shows a test checkout page, sends the browser back to your app and posts the gateway's notification (IPN or webhook), signed as the gateway signs it. No real money moves and no real card is accepted.

All payments, with a payment open

What it solves

  • Checkout without sandbox accounts, internet or a tunnel for the notification URL. See Recipe: Stripe payment.
  • Regional gateways (SSLCommerz, bKash) whose sandboxes are limited or slow. See Recipe: SSLCommerz and bKash.
  • The paths you rarely see: declines with each reason, 3-D Secure, cancel, a payment that stays pending, refunds (full and partial), captures, disputes.
  • Your IPN handler: signature check, order validation, and what happens when the notification arrives twice.
  • A gateway SendMock does not ship. See Advanced: create a gateway.

How it connects

Gets fromSends to
your app over a gateway API (Stripe, PayPal, SSLCommerz, bKash) on port 8026, POST /api/v1/payments/checkout, or POST /api/v1/payments with a test cardthe test checkout page, which drives the outcome
Gateways, which offer Methods, which run Flowsthe browser back to your app's success, fail or cancel URL
Settings > Payments: merchant name, currency, automatic outcomesthe notification through the gateway's endpoint, logged in Deliveries
payment.* and checkout.* events to Rules; the API request to Logs
Gateway (Stripe, SSLCommerz, your own)
  └── offers Methods in order (Card, bKash, Nagad, ...)
        └── each Method runs one Flow (Card form; Account number → OTP → PIN; ...)
              └── a Flow is steps from the step catalogue

Use it

  1. Open Payments > Gateways, edit Stripe, open the Checkout tab and press Open a test checkout.
  2. On the checkout page, pay with the test card 4242 4242 4242 4242, any future expiry and any CVC.
  3. The result shows where the browser goes (your success URL with Stripe's fields) and Return to merchant.
  4. Back in Payments, open the payment: the timeline shows it succeeded and the notification sent. Press Simulate > Refund... and refund part of it; a second notification goes out.

Everything on this screen

The list

Amount in the currency's own format, provider, status, customer and time, newest first, 50 at a time, new and changed payments appearing live. Status chips (All, Succeeded, Pending, Failed, Refunded, Disputed), a provider picker and a currency picker narrow it; filters and the open payment are kept in the URL.

New payment

New payment pays a payment at once with a test card, as your app's server does when it charges without a checkout page (POST /api/v1/payments). Pick the gateway, the amount and currency, a test card from Methods (for example 4000 0000 0000 9995 declines with insufficient funds) and whether to capture at once or only authorize. The card's outcome decides the payment; a card that asks for 3-D Secure fails, as there is no page to approve it on, and a real card number is refused and kept nowhere.

The payment drawer

  • Amount, status, provider and the provider's ids (session, intent, order, transaction), the customer, the payment method (card brand, last 4 and expiry, or a masked wallet number; never a full card number), the failure reason, the refunded amount and the dispute state.
  • Line items and metadata.
  • Timeline: created, 3-D Secure, authorized, captured, succeeded or failed, refunds, disputes, redirects and notifications.
  • Redirects: the success, fail and cancel URLs, which one was used, with the method (GET or POST) and the fields sent.
  • Notifications: each IPN or webhook sent (the gateway's event name, the native event, status code, time), linking to its delivery.

Simulate

The Simulate menu offers only what the payment's status allows:

StatusActions
waiting for paymentSucceed, Decline (Insufficient funds, Expired card, Incorrect CVC, Generic decline, Fraud), Expire checkout
authorizedCapture, Void authorization
paidRefund... (full by default, never more than what is left), Open dispute
disputedResolve dispute > Won or Lost

Resend notification posts the last notification again, to test that your handler copes with duplicates. Every result shows at once in the status, timeline and notifications.

Test values

CardOutcome
4242 4242 4242 4242succeeds (Visa)
5555 5555 5555 4444succeeds (Mastercard)
4000 0000 0000 0002declined: generic decline
4000 0000 0000 9995declined: insufficient funds
4000 0000 0000 0069declined: expired card
4000 0000 0000 0127declined: incorrect CVC
4000 0025 0000 3155asks for 3-D Secure
4000 0000 0000 0259succeeds, then a dispute opens

Wallets (bKash, Nagad, Rocket) use test numbers such as 01770000001 (succeeds) and 01770000002 (insufficient balance), the OTP 123456 and the PIN 12121. Settings > Payments lists the test values of every enabled method. A real card number is refused with "Use a test card" and never stored or logged.

Every control and text, one by one: Payments in depth.

Customize

From your code

Create a test checkout, settle it from the test and read the payment.

The examples call SendMock's REST API with each language's usual HTTP client and test framework. JavaScript, Go, Java, Rust, Ruby and C# use the small call helper shown under Test helper on their page in Connect your app.

payment=$(sendmock payments checkout create --provider stripe --amount-minor 1999 --currency USD --json)

paid=$(sendmock payments simulate "$(jq -r '.id' <<<"$payment")" succeed --json)

jq -e '.status == "succeeded"' <<<"$paid" >/dev/null

From the CLI, API and AI

On this page