PHP中从异步HTTP POST请求获取参数问题
Hey there! Let's figure out why your bank's async payment webhook isn't passing the order ID to your PHP script, even when manual requests work. Here are the most likely issues and fixes to try:
Chances are the bank is sending a POST request instead of GET, but your script is only looking for $_GET parameters (which is why manual GET requests work). Let's debug this:
- First, log the request method to confirm:
error_log("Incoming request method: " . $_SERVER['REQUEST_METHOD']); - If it's POST, check the payload format:
- For form-encoded payloads (
application/x-www-form-urlencoded), use$_POST['order_id']to grab the ID. - For JSON payloads (
application/json), PHP won't auto-populate$_POST—you need to read the raw input:$rawPayload = file_get_contents('php://input'); $payloadData = json_decode($rawPayload, true); $orderId = $payloadData['order_id'] ?? null; // Use null coalescing to avoid errors error_log("Parsed order ID: " . $orderId);
- For form-encoded payloads (
Banks often use specific parameter names (not always order_id—could be merchant_order_ref, transaction_order_id, etc.). Plus, many require signature validation to ensure the request is legitimate:
- Dig into the bank's official docs to confirm the exact parameter name for your order ID.
- Log the full incoming payload to see what's actually being sent:
error_log("Full webhook payload: " . file_get_contents('php://input')); - If signature validation is required, make sure your script isn't failing early (e.g., invalid signature) before it gets to parsing the order ID.
Your server's firewall, security plugins (like ModSecurity), or CDN (e.g., Cloudflare) might be blocking or truncating the bank's request:
- Check your server's access logs (Apache:
access.log, Nginx:error.log) to see if the bank's IP is returning 4xx/5xx errors. - Temporarily disable security plugins or add the bank's IP range to your whitelist to test if that fixes it.
Most payment systems require callback URLs to use HTTPS. If your SSL certificate is expired, self-signed, or untrusted, the bank's request might fail silently:
- Verify your certificate is valid using standard SSL checking tools.
- Make sure your server isn't redirecting HTTP to HTTPS in a way that strips the payload (some misconfigurations can do this).
Use a tool to mimic the bank's request format and see if your script works:
- Expose your local script to the public with a tool like ngrok, then send a test POST request (with the correct payload format) to your callback URL.
- This will help you confirm if the issue is with the bank's request or your script's handling.
内容的提问来源于stack exchange,提问作者Eric Mitjans

