post
https://uat.herepay.org/api/herepay/callback
Herepay sends this to you. You don't call it.
After the customer pays (or the payment fails), Herepay sends the result to your callback_url. Your system uses it to mark the order as paid or failed.
The customer is also brought back to your redirect_url with the same details. Only use that to show a "thank you" page. Always update the order from the callback, because the customer may close the browser before they get back.
Testing in Postman: set callback_url in the collection variables to your own address and send this sample.
What you receive
| Field | What it is |
|---|---|
payment_code | Your order number |
reference_code | Herepay's invoice number |
status / status_code | Success (00), Pending (29) or Failed (30) |
amount | Amount in RM |
bank_name | Customer's bank |
transaction_id | FPX transaction number |
message | Note from the bank |
currency, payment_method, fpx_type | Extra details, e.g. MYR, FPX |
checksum | Security code |
Keep it safe: 5 rules
- Check the checksum first. Anyone can send fake data to your callback address. Only trust it if the checksum matches. Make it the same way as in the collection overview, with your Private Key.
- Check the amount matches your order.
- Update each order only once. The same result can arrive more than once.
- Reply fast with
OK(HTTP 200). Herepay waits about 5 seconds. - No callback? Use Get Transaction by Payment Code to check.
For developers
// Laravel
public function herepayCallback(Request $request)
{
$fields = $request->except('checksum');
ksort($fields);
$expected = hash_hmac('sha256', implode(',', $fields), config('services.herepay.private_key'));
if (! hash_equals($expected, (string) $request->input('checksum'))) {
return response('Invalid checksum', 401);
}
// Find the order by payment_code, check the amount, then update it (only once).
return response('OK', 200);
}
Recent Requests
Log in to see full request history
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
Loading…

