Troubleshooting
Troubleshooting common issues across payment methods and features — symptoms, likely causes, and how to resolve them. Covers failed payments, webhook delivery issues, redirect problems, and deep link errors.
For a complete list of error codes, see the API Reference.
Failed payments
Payment Intent stuck at awaiting_payment_method
After attaching a Payment Method, the status returns to awaiting_payment_method instead of moving forward.
Read last_payment_error.failed_message on the Payment Intent for the specific reason. Common causes:
- Validation error on the Payment Method — the details provided were invalid or incomplete
- Incorrect Payment Method type — verify that the
typematches a method inpayment_method_allowed - Expired Payment Intent — Payment Intents expire after a set period; create a new one
- Incorrect
client_key— theclient_keymust come from the same Payment Intent you're attaching to
Correct the issue and retry with a new Payment Method.
Card declined
A card payment fails with an error in last_payment_error.
| Error message | Likely cause | Resolution |
|---|---|---|
| Insufficient funds | Customer's card balance is too low | Customer uses a different card |
| Invalid card number | Typographical error | Customer re-enters card details |
| Expired card | Card expiry date has passed | Customer uses a non-expired card |
| CVC mismatch | Wrong CVV/CVC entered | Customer re-enters CVC |
| Card not supported | Card type not enabled on your account | Contact PayMongo support |
| Card declined by issuer | Bank declined without specific reason | Customer contacts their bank or uses a different card |
3D Secure authentication failed
The customer was redirected to 3DS, failed or cancelled authentication, and the payment didn't complete.
The customer may have cancelled, entered the wrong OTP, or their bank rejected the authentication. When the customer returns to your return_url, retrieve the Payment Intent server-side. If the status is awaiting_payment_method, show an error and let them retry. Don't retry the attachment automatically — create a new Payment Method.
E-wallet redirect not working
The customer is not being redirected to the e-wallet app, or the redirect URL doesn't open correctly.
- Confirm the
return_urlis a valid, reachable HTTPS URL - Confirm you're redirecting to
next_action.redirect.url— not your own URL - For mobile apps, implement deep link handling for GCash (see Integrating GCash on mobile applications)
Webhook issues
Webhooks not being received
Payments succeed but your server isn't receiving webhook events.
- Verify webhook endpoints are registered in the Webhooks section of your PayMongo dashboard
- Check that test webhooks use test API keys and live webhooks use live API keys — test webhooks only fire for test mode payments
- Check your server logs for incoming requests and any processing errors
- Ensure your endpoint returns
200 OKquickly — process webhooks asynchronously if the handler takes time
Redirect and return URL issues
Payment status unclear after customer returns
The customer lands on your return page but you don't know if the payment succeeded.
Never trust the redirect alone. When the customer returns:
- Extract the
payment_intent_idfrom the query parameters - Retrieve the Payment Intent from your server using the secret key
- Check
status—succeededmeans paid;awaiting_payment_methodmeans something went wrong
QR Ph issues
QR code not displaying
The QR code is not visible after the attach response.
The value at next_action.code.image_url is a Base64 data URI. Set it directly as the src of an <img> tag:
<img src="data:image/png;base64,..." alt="Scan to pay" />If the value already includes the data:image/...;base64, prefix, use it as-is.
QR code expired before customer scanned
You received a qrph.expired webhook and the customer didn't pay in time.
Notify the customer and generate a new QR code by creating a new Payment Method and attaching it to the same Payment Intent.
Updated about 4 hours ago