Toss Payments: why the webhook, not the redirect, decides a sale

토스페이먼츠 연동 가이드: 결제 완료를 리다이렉트가 아닌 웹훅으로 처리해야 하는 이유

3 min read2 primary sources

Foreign founders integrating Toss Payments often rely on the client browser redirect to grant access. That pattern breaks on mobile drops, tab closes, and virtual accounts. Toss Payments developer documentation mandates webhook-driven fulfillment. How the retry policy works, HMAC signature verification, and building idempotent handlers.

Seoul city skyline illuminated at night with office high-rises and lights
On this page
  1. Why browser redirects fail
  2. The webhook delivery and retry mechanism
  3. Implementing signature verification and idempotency

Flowchart showing client redirect vulnerabilities versus server-to-server webhook reliability in Toss Payments

Korean payment gateways work differently from Stripe or PayPal checkout flows. When you integrate Toss Payments, the client browser widget executes user authentication and returns query parameters to your registered success URL.

Many engineering teams grant product entitlements immediately upon loading that success page. That design creates silent revenue losses and ghost orders.

Why browser redirects fail

A browser redirect depends entirely on client-side conditions. Three common scenarios prevent redirect-based fulfillment from executing:

ScenarioClient redirect behaviorWebhook behavior
User closes browser after paymentRedirect never reaches your serverServer receives webhook event normally
Cellular connection dropsBrowser shows connection errorServer receives webhook event directly
Virtual account (가상계좌) depositNo browser redirect occurs at deposit timeServer receives deposit notification instantly
Query parameter manipulationTampered payment parameters reach endpointCryptographic signature protects payload

Virtual accounts highlight the flaw clearly. When a buyer selects a virtual account, Toss Payments issues account details. The customer pays hours later at an ATM or through banking apps.

Because the buyer is not browsing your site when depositing funds, no redirect can fire. Only an asynchronous webhook informs your system that money arrived.

The webhook delivery and retry mechanism

Toss Payments sends payment notifications via HTTP POST requests to your designated webhook endpoint. The payload contains complete payment details under the PAYMENT_STATUS_CHANGED event.

Your server must acknowledge receipt by returning an HTTP 200 status code. If your server returns an error or times out, Toss Payments assumes delivery failed.

Delivery propertyToss Payments specificationDeveloper action
Target eventPAYMENT_STATUS_CHANGEDFilter on payment status (DONE, CANCELED)
Acknowledgment codeHTTP 200 OKReturn 200 before long-running tasks
Retry policyUp to 7 attemptsImplement idempotent transaction handling
Security headertosspayments-webhook-signatureVerify HMAC-SHA256 signature hash
Transmission trackingtosspayments-webhook-transmission-idDeduplicate incoming event IDs

Toss Payments retries failed webhook deliveries up to 7 times with increasing time intervals. If your backend suffers temporary downtime, the gateway automatically replays undelivered events once your servers recover.

Implementing signature verification and idempotency

Because webhooks trigger database updates and inventory deductions, you must secure your webhook receiver against spoofing.

Toss Payments signs webhook payloads using HMAC-SHA256 with your API Secret Key. Your handler must recalculate the signature using the raw payload and transmission timestamp header, then compare hashes in constant time.

Network retries also mean your server may receive the identical webhook twice. Track the transmission ID in your database to ensure payment handlers run exactly once.

Founders scaling Korean ventures can review technical architectures and go-to-market strategies in our Ventures Workspace.

Related on KBridge: Korean data sent to a foreign AI API and the PSST plan format.

Frequently asked questions

Can I fulfill customer orders using just the Toss Payments successUrl redirect?
No. The successUrl redirect is a client-side navigation. If the user loses internet connection or closes their browser before the page loads, your server never receives the confirmation. Webhooks guarantee reliable delivery.
What happens if my server fails to answer a Toss Payments webhook?
If your server does not return an HTTP 200 response, Toss Payments considers the delivery failed and retries up to 7 times with increasing intervals.
How do virtual accounts (가상계좌) work with redirects?
Virtual accounts do not trigger redirects upon payment because the customer transfers money hours or days later from their bank. Only the PAYMENT_STATUS_CHANGED webhook notifies your system when the deposit clears.
How should I handle duplicate webhook deliveries?
Store the unique transmission ID provided in the webhook headers. Check this ID against your database to ensure your business logic processes each transaction only once.
How do I secure the Toss Payments webhook endpoint?
Verify the HMAC-SHA256 signature header sent with each webhook against your Toss Payments Secret Key. Reject any request where the calculated hash does not match.
What HTTP status code must the webhook endpoint return?
Your endpoint must return HTTP 200 OK. Returning any 4xx or 5xx code signals a delivery failure to Toss Payments, triggering its automatic retry loop.

Sources

Everything above is the rule as published. See how it applies to your case.

Read next