Failed Webhook Behavior
When a terminal action fails:- Webhook Triggered: HitPay automatically sends a webhook to your configured webhook URL with status=failed
- Payment Request Status Updated: The payment request status is automatically updated to failedin HitPay’s system
- Error Information: The webhook includes error details that should be presented to the user
Failed Webhook Payload
When a payment fails on the terminal, HitPay will send a webhook in one of two formats depending on your webhook configuration:Format 1: Form-Encoded (Webhook v1)
If you’re using thewebhook parameter in the Payment Request API (webhook v1), you’ll receive a form-encoded payload with status=failed and includes an error message:
Format 2: JSON Event (Webhook Events)
If you’re using registered webhook events (as described in Webhooks documentation), you’ll receive a JSON payload with thepayment_request.failed event:
Example JSON Event for payment_request.failed
Example JSON Event for payment_request.failed
- status: Will be- "failed"for failed payment requests
- payments[].status: Will be- "failed"for failed payments
- payments[].status_reason: Human-readable error message explaining the failure
- payments[].status_reason_code: Machine-readable error code (e.g.,- "withdrawal_count_limit_exceeded")
- Hitpay-Event-Type: Will be- "failed"for failed events
- Hitpay-Event-Object: Will be- "payment_request"for payment request events
- Hitpay-Signature: SHA-256 HMAC signature for validation (see Webhook Validation)
Implementation Guidelines
To properly handle failed payment requests in your application, you need to handle both webhook formats:Handling Form-Encoded Webhooks (Webhook v1)
Handling JSON Event Webhooks
Displaying Error Messages
Always present the error message from the webhook to your users. This helps them understand why the payment failed:- For Form-Encoded Webhooks: Use the error_messagefield
- For JSON Event Webhooks: Use the payments[].status_reasonfield (orstatus_reason_codeas fallback)
- Card Declined: “Your card was declined. Please try a different payment method.”
- Insufficient Funds: “Insufficient funds. Please check your account balance.”
- Timeout: “Payment processing timed out. Please try again.”
- Terminal Error: “Terminal error occurred. Please contact staff.”
- Limit Exceeded: “Withdrawal or limit exceeded. Please use another card.”
Best Practices
- Update Payment Request Status: Mark the payment request as failed in your system when you receive the failed webhook.
- 
User Experience:
- Display a clear error message to the user on your POS/kiosk interface
- Optionally allow the user to retry the payment
- Update any pending transaction indicators
 
- Security: Always validate webhooks using HMAC verification before processing failed status updates. Never trust unverified webhook payloads.
Common Failure Scenarios
Failed webhooks can be triggered by various terminal errors:- Card Declined: Customer’s card was declined by the bank
- Insufficient Funds: Customer’s account doesn’t have enough balance
- Transaction Timeout: Payment took too long to process
- Card Reader Error: Physical issue with the card reader
- Network Issues: Terminal lost connection during payment
- Cancelled by User: Customer cancelled the payment on the terminal
- Invalid Card: Card details are invalid or expired
Important Notes
Always validate webhooks using HMAC verification before processing failed status updates. Never trust unverified webhook payloads.
The failed webhook is sent automatically by HitPay whenever a terminal action fails. You do not need to poll the API for payment status - simply listen to the webhook and handle the response accordingly.
Related Documentation
- In-Person Payments Overview - Learn the basics of in-person payments
- Testing in Sandbox - Test failed payment scenarios in Sandbox
- Webhook Validation - Learn how to validate webhook signatures