Toss Payments
Emulated Toss Payments API for local development and testing.
A stateful emulator for the Toss Payments REST API.
Included now:
- Payment confirm / lookup (by paymentKey or orderId) / cancel (incl. partial)
- Checkout page simulation (
/checkout→/checkout/approve) - An
/internal/paymentshelper to create a payment without the widget PAYMENT_STATUS_CHANGEDwebhooks on confirm and cancel
# From this repo (after `bun install && bun run build`)bun packages/emulate/dist/index.js --service tosspayments
# Or from the published packagenpx @pleaseai/emulate --service tosspaymentsA single service starts on the base port (default 4000). Use -p <port> to
change it. When started alongside other services, ports are assigned
sequentially from the base port (tosspayments’ slot is 4002).
Payment API routes use HTTP Basic auth with the secret key as the username and
an empty password — Authorization: Basic base64("<secret_key>:") (note the
trailing colon). The checkout pages and /internal/payments helper need no auth.
# Build the header value for test_sk_exampleecho -n 'test_sk_example:' | base64 # → dGVzdF9za19leGFtcGxlOg==# 1. Create a payment (replaces the payment-widget step)curl -X POST http://localhost:4000/internal/payments \ -H "Content-Type: application/json" \ -d '{"orderId":"order-1","orderName":"Test order","amount":11000}'# → {"paymentKey":"<paymentKey>", ...}
# 2. Confirm itcurl -X POST http://localhost:4000/v1/payments/confirm \ -H "Authorization: Basic $(echo -n 'test_sk_example:' | base64)" \ -H "Content-Type: application/json" \ -d '{"paymentKey":"<paymentKey>","orderId":"order-1","amount":11000}'
# 3. Look it up (by paymentKey or by orderId)curl http://localhost:4000/v1/payments/<paymentKey> \ -H "Authorization: Basic $(echo -n 'test_sk_example:' | base64)"curl http://localhost:4000/v1/payments/orders/order-1 \ -H "Authorization: Basic $(echo -n 'test_sk_example:' | base64)"
# 4. Cancel it (omit cancelAmount for a full cancel)curl -X POST http://localhost:4000/v1/payments/<paymentKey>/cancel \ -H "Authorization: Basic $(echo -n 'test_sk_example:' | base64)" \ -H "Content-Type: application/json" \ -d '{"cancelReason":"User requested","cancelAmount":11000}'Confirm and cancel dispatch a PAYMENT_STATUS_CHANGED webhook to any configured
webhook URLs.
Seed Config
Section titled “Seed Config”Add a tosspayments: section to emulate.config.yaml (or pass --seed <file>):
tosspayments: merchants: - client_key: test_ck_example secret_key: test_sk_example