Invalidating draft-state orders created from payment links quick_pay

I’m planning to use the quick_pay option when creating a payment link and simply redirecting customers from our site to that link for payment in browser (with redirect back to our site after payment, etc.)

But my issue is the following:

  1. Customer initiates order; payment URL and associated order are created; customer is redirected to URL.
  2. Customer does NOT complete payment but manages to preserve the payment URL somehow.
  3. Customer later initiates order again; new payment URL and new associated order are created; customer is redirected to new URL.
  4. Customer DOES complete payment for new order.
  5. Customer later inadvertently navigates to original payment URL and mistakenly completes payment for original order.
  6. Customer has now erroneously paid twice.

To avoid this, I’m thinking I could set the state of any orphaned orders in the draft state (and the associated fulfillments) to “cancelled” before creating a new quick_pay payment link.

But is this a good idea?

It would be nicer if I could use the idempotency key associated with the CreatePaymentLinkRequest to somehow invalidate the payment link such that it could not be used to pay the order. This way the order would stay in draft state and not look like a cancelled order (and Square could delete it after 30 days.) Is there some API for this that I’m not seeing?

If you know the customer prior to creating the link your database can keep track of any links the customer created prior and whether or not they’ve been paid for to avoid this. If the order hasn’t been paid for then you can call UpdateOrder for the existing link order_id to make any changes if needed and direct the customer to the previously abandoned link. :slightly_smiling_face:

The problem with re-using the original URL and order is that (according to the documentation) orders that are in the draft state can be deleted by Square. This introduces a race condition where, even if our servers validate the order is in a good state prior to re-issuing it, the order might be invalid when the customer tries to pay. This is the reasoning behind wanting new orders and URLs at each customer purchase request.