for developers · October 28, 2026

Payment not verified

I had my assistant quickly write a PayTR (Turkish payment provider) callback. The code worked, but a fake request also approved the order.

The real problem: the code only checks status. Anyone who knows the URL can send the same request.

In short

If a PayTR callback only checks status, anyone who knows the URL can confirm an order with a fake request. Compute the incoming hash yourself and reject mismatches; confirm orders in the callback, not on the success page, and take the amount from your database, not the browser.

Today's script

I had my assistant quickly write a PayTR callback. The code worked, but a fake request also approved the order. The real problem: the code only checks status. Anyone who knows the URL can send the same request. Without a hash check, an unpaid order ships. With a digital product, the code goes out instantly. The PayTR docs are clear: compute the incoming hash yourself. If it doesn't match, reject the request. The second common mistake: approving the order on the success page. According to PayTR, no data ever reaches that page. The third: don't take the amount from the browser. Calculate the price yourself from the database. If PayTR gets no response, it sends the same notification again. Approve the order only on the first notification. Same rule with iyzico. Use the token sent to the callback to query the result from your server. Try it yourself: in the test environment, send a request without a hash. If the order gets approved, your door is open. Give this prompt to your assistant and save the video. Tomorrow: a message says your package is stuck at the address. This time it's not SMS.