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 requestspayments[].status: Will be"failed"for failed paymentspayments[].status_reason: Human-readable error message explaining the failurepayments[].status_reason_code: Machine-readable error code (e.g.,"withdrawal_count_limit_exceeded")
Hitpay-Event-Type: Will be"failed"for failed eventsHitpay-Event-Object: Will be"payment_request"for payment request eventsHitpay-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
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