Integrating PayU properly: the parts that break in production
5 August 2026
Taking a first PayU test payment is quick. Making the integration trustworthy — so that your order status is right even when the browser closes mid-payment — is the actual work.
Never trust the browser redirect alone
The success redirect is a convenience, not a source of truth. A customer can close the tab, lose signal or hit back. If your order only becomes paid because a browser returned to your success URL, you will eventually ship goods for a failed payment or vice versa.
- Treat the server-to-server webhook as authoritative.
- Verify the response hash on every callback before touching order state.
- Make webhook handling idempotent — the same event can arrive twice.
Hash generation belongs on the server
The request hash is built from your merchant key, transaction fields and your salt. The salt never appears in client-side code, in a repository or in a mobile bundle. If it has leaked, rotate it in the PayU dashboard immediately.
Amount handling
Compute the payable amount server-side from your own catalogue, never from a form field. A hidden input is editable by anyone with developer tools open, and a hash built from a tampered amount is a valid hash for the wrong price.
Every field that affects what you charge must be derived on your server. The client tells you what the customer wants to buy, never what it costs.
Reconciliation
Run a daily job that pulls settled transactions from PayU and matches them to your orders. Flag anything that is paid at PayU but not in your database, and anything marked paid locally with no matching settlement. Catching a mismatch the next morning is routine; catching it at the end of the quarter is an accounting project.
