Invoice.payment_made webhook has tmp public_url

On our invoice webhook, we compare the public_url to confirm the payment. This morning we recieve a payload that had a tmp URL in it:

{
...
  "type": "invoice.payment_made",
  "event_id": "0f2893d5-a18c-5960-a198-03eb1bc48c5d",
  "created_at": "2025-05-22T13:14:21Z",
  "data": {
    "type": "invoice",
    "id": "inv:0-ChCwDuNr9W2Ui47ShnZOupwwEOAM",
    "object": {
      "invoice": {
        "accepted_payment_methods": {
          "bank_account": false,
          "buy_now_pay_later": false,
          "card": true,
          "cash_app_pay": false,
          "square_gift_card": false
        },
        "created_at": "2025-05-15T22:26:18Z",
        "delivery_method": "EMAIL",
        "id": "inv:0-ChCwDuNr9W2Ui47ShnZOupwwEOAM",
        "invoice_number": "027469",
        "location_id": "L3JCEEG6V6RQM",
        "order_id": "bUjEyJ9TEB4aUJPUxrrHJfPj56TZY",
...
        "public_url": "https://app.squareup.com/pay-invoice/invtmp:68d64ae9-244b-4aae-8845-6929132206be",
        "status": "PAID",
        "store_payment_method_enabled": false,
        "timezone": "America/Los_Angeles",
        "updated_at": "2025-05-22T13:14:12Z",
        "version": 4
      }
    }
  }
}

Is this expected?

:waving_hand: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Pay or Refund Invoices
Use Webhooks to Integrate with a Payroll System
Create and Publish Invoices

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

Are you referring to the tmp in the URL? Did this cause a problem? :slight_smile:

Yes, this is expected. The “public_url” field in the webhook payload is the URL of the Square-hosted invoice payment page. The URL can be a temporary URL (with “invtmp” in the path) or a permanent URL (with “inv” in the path). The temporary URL is generated when an invoice is first created and becomes a permanent URL when the invoice is published. In your case, it seems like the invoice was paid before it was published, hence the temporary URL in the payload.

This answer was reviewed by @Bryan-Square.

Exactly, I was expecting the URL to end with the same invoice id (and match the URL from the original invoice).

Are these tmp URLs always possible?

This invoice was already published, and we sent the published URL to the customer. The customer paid there and the webhook sends me the tmp URL. That doesn’t seem correct.

This was a change that was made in our 2025-04-16 version.

  • Invoice payment links are now temporary and expire after a certain period. Customers can provide the email address or phone number associated with the invoice and request a new link directly from the expired payment page, so no action is required from the developer. However, developers who need to share a payment link with the customer a few days or more after it was generated should retrieve the invoice first to automatically generate a new, up-to-date link. :slight_smile:

Thank you for the helpful pointer to the release notes!

One more question: is it possible to retrieve an Invoice object (or invoice_id) from a tmp URL?

It’s not possible to retrieve the invoice_id from a tmp URL. You’ll want to log the invoice_id when you get the webhook event. :slight_smile:

Yep, that’s what I’m changing it to now. Just thought I’d check for the ones I already have in my system

One more one more question: when will the sandbox start producing the tmp invoice URLs?

Checking with the team. :slight_smile: