Paid invoice with Stripe FPX payment marked as 'Pending'

Hi,

My Invoice Ninja version is v5.5.20-C92, self-hosted.

A client paid and invoice using Stripe FPX. It’s been 2 days, and here are the observations:

  • Under Invoice, the status is ‘Paid’ but the payment is ‘Pending’ status.
  • In the Stripe portal, I can see that the payment is ‘Succeeded’.

Should the Payment be automatically marked as Paid upon the successful payment by the client?

Thank you.

Hi,

Have you configured the Stripe webhooks? It could explain this.

In my Stripe portal, the webhook is configured. There are log entries:

Hope it is correct?

@david do you have any suggestions?

Can you take a redacted screenshot showing the events you are listening to for the webhooks? it sounds like a configuration issue.

Are the following information what you are looking for in my Stripe dashboard?

POST /v1/webhook_endpoints
Status
200 OK
ID
xxxxxxxxxxxxxxxxxxxxx
Time
xxxxxxxxxxxxxxxxxxxxx
IP address
xxxxxxxxxxxxxxxxxxxxx (from server at xxxxxxxxxxxxxxxxxxxxx)
API version
2020-08-27
Source
Dashboard — xxxxxxxxxxxxxxxxxxxxx
Idempotency
Key — xxxxxxxxxxxxxxxxxxxxx

Origin
https://dashboard.stripe.com

Response body
{
“id”: “xxxxxxxxxxxxxxxxxxxxx”,
“object”: “webhook_endpoint”,
“api_version”: null,
“application”: null,
“created”: xxxxxxxxxxxxxxxxxxxxx,
“description”: null,
“enabled_events”: [
“account.updated”,
“account.external_account.created”,
“account.external_account.deleted”,
“account.external_account.updated”,
“balance.available”,
“billing_portal.configuration.created”,
“billing_portal.configuration.updated”,
“capability.updated”,
“charge.captured”,
“charge.expired”,
“charge.failed”,
“charge.pending”,
“charge.refunded”,
“charge.succeeded”,
“charge.updated”,
“charge.dispute.closed”,
“charge.dispute.created”,
“charge.dispute.funds_reinstated”,
“charge.dispute.funds_withdrawn”,
“charge.dispute.updated”,
“charge.refund.updated”,
“checkout.session.async_payment_failed”,
“checkout.session.async_payment_succeeded”,
“checkout.session.completed”,
“checkout.session.expired”,
“coupon.created”,
“coupon.deleted”,
“coupon.updated”,
“credit_note.created”,
“credit_note.updated”,
“credit_note.voided”,
“customer.created”,
“customer.deleted”,
“customer.updated”,
“customer.discount.created”,
“customer.discount.deleted”,
“customer.discount.updated”,
“customer.source.created”,
“customer.card.created”,
“customer.bank_account.created”,
“customer.source.deleted”,
“customer.card.deleted”,
“customer.bank_account.deleted”,
“customer.source.expiring”,
“customer.source.updated”,
“customer.card.updated”,
“customer.bank_account.updated”,
“customer.subscription.created”,
“customer.subscription.deleted”,
“customer.subscription.pending_update_applied”,
“customer.subscription.pending_update_expired”,
“customer.subscription.trial_will_end”,
“customer.subscription.updated”,
“customer.tax_id.created”,
“customer.tax_id.deleted”,
“customer.tax_id.updated”,
“file.created”,
“identity.verification_session.canceled”,
“identity.verification_session.created”,
“identity.verification_session.processing”,
“identity.verification_session.requires_input”,
“identity.verification_session.verified”,
“invoice.created”,
“invoice.deleted”,
“invoice.finalization_failed”,
“invoice.finalized”,
“invoice.marked_uncollectible”,
“invoice.paid”,
“invoice.payment_action_required”,
“invoice.payment_failed”,
“invoice.payment_succeeded”,
“invoice.sent”,
“invoice.upcoming”,
“invoice.updated”,
“invoice.voided”,
“invoiceitem.created”,
“invoiceitem.deleted”,
“invoiceitem.updated”,
“issuing_authorization.created”,
“issuing_authorization.updated”,
“issuing_card.created”,
“issuing_card.updated”,
“issuing_cardholder.created”,
“issuing_cardholder.updated”,
“issuing_dispute.closed”,
“issuing_dispute.created”,
“issuing_dispute.funds_reinstated”,
“issuing_dispute.submitted”,
“issuing_dispute.updated”,
“issuing_transaction.created”,
“issuing_transaction.updated”,
“mandate.updated”,
“order.created”,
“order.payment_failed”,
“order.payment_succeeded”,
“order.updated”,
“order_return.created”,
“payment_intent.amount_capturable_updated”,
“payment_intent.canceled”,
“payment_intent.created”,
“payment_intent.payment_failed”,
“payment_intent.processing”,
“payment_intent.requires_action”,
“payment_intent.succeeded”,
“payment_link.created”,
“payment_link.updated”,
“payment_method.attached”,
“payment_method.automatically_updated”,
“payment_method.card_automatically_updated”,
“payment_method.detached”,
“payment_method.updated”,
“payout.canceled”,
“payout.created”,
“payout.failed”,
“payout.paid”,
“payout.updated”,
“person.created”,
“person.deleted”,
“person.updated”,
“plan.created”,
“plan.deleted”,
“plan.updated”,
“price.created”,
“price.deleted”,
“price.updated”,
“product.created”,
“product.deleted”,
“product.updated”,
“promotion_code.created”,
“promotion_code.updated”,
“quote.accepted”,
“quote.canceled”,
“quote.created”,
“quote.finalized”,
“radar.early_fraud_warning.created”,
“radar.early_fraud_warning.updated”,
“recipient.created”,
“recipient.deleted”,
“recipient.updated”,
“reporting.report_run.failed”,
“reporting.report_run.succeeded”,
“review.closed”,
“review.opened”,
“setup_intent.canceled”,
“setup_intent.created”,
“setup_intent.requires_action”,
“setup_intent.setup_failed”,
“setup_intent.succeeded”,
“sigma.scheduled_query_run.created”,
“sku.created”,
“sku.deleted”,
“sku.updated”,
“source.canceled”,
“source.chargeable”,
“source.failed”,
“source.mandate_notification”,
“source.refund_attributes_required”,
“source.transaction.created”,
“source.transaction.updated”,
“subscription_schedule.aborted”,
“subscription_schedule.canceled”,
“subscription_schedule.completed”,
“subscription_schedule.created”,
“subscription_schedule.expiring”,
“subscription_schedule.released”,
“subscription_schedule.updated”,
“tax_rate.created”,
“tax_rate.updated”,
“topup.canceled”,
“topup.created”,
“topup.failed”,
“topup.reversed”,
“topup.succeeded”,
“transfer.created”,
“transfer.failed”,
“transfer.paid”,
“transfer.reversed”,
“transfer.canceled”,
“transfer.updated”
],
“livemode”: true,
“metadata”: {
},
“secret”: “xxxxxxxxxxxxxxxxxxxxx”,
“status”: “enabled”,
“url”: “https://xxxxxxxxxxxxxxxxxxxxx/payment_webhook/xxxxxxxxxxxxxxxxxxxxx
}

Request query parameters
{
“include_only”: [
“id,livemode,metadata,object,secret,status,url,api_version,application,created,description,enabled_events”
]
}

Request POST body
{
“url”: “https://xxxxxxxxxxxxxxxxxxxxx/payment_webhook/xxxxxxxxxxxxxxxxxxxxx”,
“description”: “”,
“enabled_events”: [
“account.updated”,
“account.external_account.created”,
“account.external_account.deleted”,
“account.external_account.updated”,
“balance.available”,
“billing_portal.configuration.created”,
“billing_portal.configuration.updated”,
“capability.updated”,
“charge.captured”,
“charge.expired”,
“charge.failed”,
“charge.pending”,
“charge.refunded”,
“charge.succeeded”,
“charge.updated”,
“charge.dispute.closed”,
“charge.dispute.created”,
“charge.dispute.funds_reinstated”,
“charge.dispute.funds_withdrawn”,
“charge.dispute.updated”,
“charge.refund.updated”,
“checkout.session.async_payment_failed”,
“checkout.session.async_payment_succeeded”,
“checkout.session.completed”,
“checkout.session.expired”,
“coupon.created”,
“coupon.deleted”,
“coupon.updated”,
“credit_note.created”,
“credit_note.updated”,
“credit_note.voided”,
“customer.created”,
“customer.deleted”,
“customer.updated”,
“customer.discount.created”,
“customer.discount.deleted”,
“customer.discount.updated”,
“customer.source.created”,
“customer.source.deleted”,
“customer.source.expiring”,
“customer.source.updated”,
“customer.subscription.created”,
“customer.subscription.deleted”,
“customer.subscription.pending_update_applied”,
“customer.subscription.pending_update_expired”,
“customer.subscription.trial_will_end”,
“customer.subscription.updated”,
“customer.tax_id.created”,
“customer.tax_id.deleted”,
“customer.tax_id.updated”,
“file.created”,
“identity.verification_session.canceled”,
“identity.verification_session.created”,
“identity.verification_session.processing”,
“identity.verification_session.requires_input”,
“identity.verification_session.verified”,
“invoice.created”,
“invoice.deleted”,
“invoice.finalization_failed”,
“invoice.finalized”,
“invoice.marked_uncollectible”,
“invoice.paid”,
“invoice.payment_action_required”,
“invoice.payment_failed”,
“invoice.payment_succeeded”,
“invoice.sent”,
“invoice.upcoming”,
“invoice.updated”,
“invoice.voided”,
“invoiceitem.created”,
“invoiceitem.deleted”,
“invoiceitem.updated”,
“issuing_authorization.created”,
“issuing_authorization.updated”,
“issuing_card.created”,
“issuing_card.updated”,
“issuing_cardholder.created”,
“issuing_cardholder.updated”,
“issuing_dispute.closed”,
“issuing_dispute.created”,
“issuing_dispute.funds_reinstated”,
“issuing_dispute.submitted”,
“issuing_dispute.updated”,
“issuing_transaction.created”,
“issuing_transaction.updated”,
“mandate.updated”,
“order.created”,
“order.payment_failed”,
“order.payment_succeeded”,
“order.updated”,
“order_return.created”,
“payment_intent.amount_capturable_updated”,
“payment_intent.canceled”,
“payment_intent.created”,
“payment_intent.payment_failed”,
“payment_intent.processing”,
“payment_intent.requires_action”,
“payment_intent.succeeded”,
“payment_link.created”,
“payment_link.updated”,
“payment_method.attached”,
“payment_method.automatically_updated”,
“payment_method.detached”,
“payment_method.updated”,
“payout.canceled”,
“payout.created”,
“payout.failed”,
“payout.paid”,
“payout.updated”,
“person.created”,
“person.deleted”,
“person.updated”,
“plan.created”,
“plan.deleted”,
“plan.updated”,
“price.created”,
“price.deleted”,
“price.updated”,
“product.created”,
“product.deleted”,
“product.updated”,
“promotion_code.created”,
“promotion_code.updated”,
“quote.accepted”,
“quote.canceled”,
“quote.created”,
“quote.finalized”,
“radar.early_fraud_warning.created”,
“radar.early_fraud_warning.updated”,
“recipient.created”,
“recipient.deleted”,
“recipient.updated”,
“reporting.report_run.failed”,
“reporting.report_run.succeeded”,
“review.closed”,
“review.opened”,
“setup_intent.canceled”,
“setup_intent.created”,
“setup_intent.requires_action”,
“setup_intent.setup_failed”,
“setup_intent.succeeded”,
“sigma.scheduled_query_run.created”,
“sku.created”,
“sku.deleted”,
“sku.updated”,
“source.canceled”,
“source.chargeable”,
“source.failed”,
“source.mandate_notification”,
“source.refund_attributes_required”,
“source.transaction.created”,
“source.transaction.updated”,
“subscription_schedule.aborted”,
“subscription_schedule.canceled”,
“subscription_schedule.completed”,
“subscription_schedule.created”,
“subscription_schedule.expiring”,
“subscription_schedule.released”,
“subscription_schedule.updated”,
“tax_rate.created”,
“tax_rate.updated”,
“topup.canceled”,
“topup.created”,
“topup.failed”,
“topup.reversed”,
“topup.succeeded”,
“transfer.created”,
“transfer.failed”,
“transfer.paid”,
“transfer.reversed”,
“transfer.updated”
],
“connect”: “false”,
“enumeratively_enabled_all_events_during_creation”: “true”
}

Here’re the entries of the webhook when the client made the payment using FPX:

@myinvoice

Can you inspect the system_logs database table and search for entries on this date (of the webhook)

you’ll want to filter by

type_id = 301
category_id = 1
event_id = 21

If the webhook did hit the server, the webhook contents will be in the system logs table.

@david

I ran a search in the system_logs database, and there are 2 records:

Is this expected?

It may be logging the response in two different areas. so you are definitely receiving the webhooks.

Was the payment archived by chance?

The payment seems to be in the Stripe, just awaiting it for the payout into our bank account:

The payment was not archived before. It was auto-generated once customer completed the FPX payment, and it’s been in the ‘Active’ tab.

The ‘Pending’ status can’t seem to be updated in any part of the menu. Is there a potential bug happening here?

Is there a way to fix this?

Its not a bug, we rely on the webhook completing successfully for the payment to be marked as completed. you can manually force this by setting the status_id of the payment to 4.

The question is why has this not completed as expected given the webhook has hit the server correctly.