Webhook events not received (sandbox accounts)

I was told to post my question here, apologies if I’m in the wrong space. “payment.updated” webhooks have stopped sending to my sandbox accounts, causing a blocker in my development pipeline.

Welcome to the Developer Forum!

You posted your question in the right place. Could you please share the application id and an example of the payment id that didn’t trigger the expected webhook so that I can take a look?

Jaeha,

Thanks for the help, answers below:

application id: sandbox-sq0idb-N3-Yfxg3ERzyaSM_3cwg-w

payment id: N0nskpeD0SGw3937mPsMvR9GK8WZY

It seems like the payment was created with autocomplete: false and there was no later CompletePayment, CancelPayment, or other operation against this payment ID. Consequently, there was no subsequent state transition from APPROVED to COMPLETED or CANCELED to produce payment.updated. Is that the same behavior you see on your end?

yes, the payment is created with autocomplete false, but I call orders().pay(PayOrderRequest…{orderId}) as a final step. This works as expected (payment.updated webhook received) in my production account and has only recently stopped working in the sandbox accounts.

i can confirm that removing the line that sets autocomplete(false) temporarily fixes the payment.updated issue, however it will break (understandably) at the next step:

var finalPay = client.orders().pay(PayOrderRequest.builder() //
.orderId(orderId.get()) //
.idempotencyKey(idempotencyKey) //
.paymentIds(orders) //
.build());

log.debug("Final Pay {}", finalPay.get().getOrder().get().getClosedAt().get());

SquareClientApiException{message: Error with status code 400, statusCode: 400, body: {errors=[{code=BAD_REQUEST, detail=The order is already paid.,...

Thanks for flagging this with the additional details here. We’ve been experiencing some issues in sandbox where we located that there’s a parity gap between sandbox and prod, and this issue seems to be one of them as you’ve also noted that it works as expected in production.

While our team is looking into this, we always recommend testing in a separate free production account using CASH or EXTERNAL tender types where possible. Production accounts are free and unlimited, and the entire lifecycle transitions work correctly there.