Limit quantity of product per client

Hello! I currently adapting my snipcart solution for a real scenario and I have one doubt.
I know that I can limit the max quantity of a product in a cart so I can limit that one user can buy only one item of product XYZ per order but…

Can I limit that one client only can buy one XYZ? So I can prevent clients from buying it again in a new order if they bought it in a previous one?

Thank you!

Hey,

I believe you could do it using a custom js function that pokes the API for orders with the correct parameters to check if the client has ordered that item before. The payment template could be a good place to put it. Add a v-if somewhere, maybe directly in the <snipcart-form…> that calls your custom function (must return truthy value if the customer can buy). It would add a bit of load time right before payment.

edit: I’ve tested a bit the above theory. You will need to create a backend call for the call to Snipcart’s api, due to the key needing to stay secret. The code below is a quick mockup :

Add the window.checkCustomer function wherever you might already have the listener. Otherwise add the snipcart.ready listener somewhere before your snipcart configs code.
The comment is where you’ll call your new backend GET request. It should take the items and customer name. You can also send it an array of item ids instead, taking all ids from items variable.
I added a category for all my products I want restricted, so we check the cart items with that category.

const category = 'OnePerCustomer';

document.addEventListener('snipcart.ready', () => {
  window.checkCustomer = function () {
    const items = Snipcart.store
      .getState()
      .cart.items.items.filter((e) => e.categories.includes(category));

    const customer = Snipcart.store.getState().cart.billingAddress.fullname;

    // Backend function that checks call orders API https://docs.snipcart.com/v3/api-reference/orders#get-orders
    // with each items.id and customer.
    // Check your response from your API and change valid to appropriate value

    let valid = true;
    return valid;
  };
});

In my snipcart template overrides, I added a v-if with that function. Adding it there removes the whole payment part. It’s not really clean, but it’s just as an example. You might add a v-else after the form with an error message. Or do it some other way. I added it to payment due to the need of the customer’s name.

<div id="snipcart-templates">
  <payment>
    <snipcart-form
      v-if="window.checkCustomer()"
      @submit="confirmOrder"
      class="snipcart-payment snipcart__box"
    >
.....

Another way would be using webhooks. It’s far from optimal, but you could use a webhook on the order completed Webhooks: order events – Snipcart Documentation and just cancel the order automatically.
To update the order : API: orders – Snipcart Documentation
To add a comment to the order (for an email) : API: notifications – Snipcart Documentation
To issue a refund : API: refunds – Snipcart Documentation

Thank you! While reading your comment I got an idea based on your comment and it worked!

When someone adds a product to the cart i make a request to my own backend where Snipcart registers orders via webhook so I can know if it is registered or not :smiley: