Services and API

Hey everyone, hope you’re all doing well! I’m using the CMS and trying to bring the registered Services data to the Front End, but I’ve barely touched the API. Through Postman it pulls the registered data: [
{
“serviceId”: 6,
“valueId”: 3,
“fetchUrl”: “https://lucashome.vtexcommercestable.com.br/api/catalog/pvt/skuservicevalue/3”,
“status”: 200,
“Name”: “Vitalícia”,
“Price”: 500
},
{
“serviceId”: 7,
“valueId”: 2,
“fetchUrl”: “https://lucashome.vtexcommercestable.com.br/api/catalog/pvt/skuservicevalue/2”,
“status”: 200,
“Name”: “24 Meses”,
“Price”: 190
},
{
“serviceId”: 8,
“valueId”: 1,
“fetchUrl”: “https://lucashome.vtexcommercestable.com.br/api/catalog/pvt/skuservicevalue/1”,
“status”: 200,
“Name”: “12 Meses”,
“Price”: 99.99
}
]
On the product page I added the control vtex.cmc:stockKeepingUnitService/ It brings me information I don’t need, but I wanted it to display the warranty name, price, and a button that goes together with the product + warranty, but I can’t get it to work. The example product is: Cama Box com Colchão de Molas Ensacadas Ortobom ISO SuperPocket Casal 138cm - lucashome
I’m also using https://dash.cloudflare.com/ which gave me access to the API data since it’s PRIVATE. Not sure if that’s the best approach either.
LINK: https://vtes-services.guilherme-barbeiro.workers.dev/?skuId=819

If anyone can help me out!!!
Thanks

Hey @guilherme.lucashome, how’s it going?

Since you can already access service data via a custom API (.workers.dev), you can create a custom component in the CMS (JS/HTML), hide the native vtex.cmc:stockKeepingUnitService/ control, and use plain JavaScript or jQuery in the CMS to fetch your .workers.dev endpoint and render the services.

Working script example:

This is a test example and you’ll need to adapt it to your version.

<div id="vtex-services-box"></div>

<script>
  const skuId = skuJson_0.skus[0].sku; // Gets the SKU ID from the product page
  const container = document.getElementById('vtex-services-box');

  fetch(`https://vtes-services.guilherme-barbeiro.workers.dev/?skuId=${skuId}`)
    .then(response => response.json())
    .then(data => {
      if (data.length === 0) {
        container.innerHTML = '<p>No services available.</p>';
        return;
      }

      let html = '<h3>Additional services</h3><ul>';

      data.forEach(service => {
        html += `
          <li style="margin-bottom: 12px;">
            <strong>${service.Name}</strong> - R$ ${service.Price.toFixed(2)}
            <button onclick="addServiceToCart(${skuId}, ${service.serviceId}, ${service.valueId})">
              Add
            </button>
          </li>
        `;
      });

      html += '</ul>';
      container.innerHTML = html;
    });

  function addServiceToCart(skuId, serviceId, valueId) {
    vtexjs.checkout.addToCart([
      {
        id: skuId,
        quantity: 1,
        seller: '1',
        attachments: [
          {
            name: 'services',
            content: {
              [serviceId]: valueId
            }
          }
        ]
      }
    ]).then(() => {
      alert('Product with service added to cart!');
    });
  }
</script>

Hiding the native VTEX control (optional)

If you don’t want to show the default control, add the following CSS in the CMS to hide it:

.vtexSkuServicesContainer {
  display: none !important;
}

Let us know if this makes sense. If it helped in any way, mark it as the SOLUTION to support others in the community.

Cheers,
Four2One Team

Good afternoon. Thank you for the help. I added the script and made the corrections, but the div comes up empty, not fetching the service data. This is the link I’m using: Cama Box com Colchão de Molas Ensacadas Ortobom ISO SuperPocket Casal 138cm - lucashome

Hey @guilherme.lucashome

Is the service structure actually saved in the product data?

Services need to be properly registered on the product in VTEX, via:

  • Catalog > Products > SKU > Attachments (Services)
  • Or via spreadsheet/API, with Attachments linked to the SKU.

You can confirm this by opening the browser console on the page and running:

vtexjs.catalog.getProductWithVariations(20000000).then(console.log)

Replace 20000000 with the correct productId. Check if something like this exists:

product.skus[0].attachments

2. Are you listening at the right moment to inject the services?

In VTEX, the page HTML is rendered dynamically. So scripts that run before the content loads won’t capture anything.

Use something like:

$(window).on('load', function() {
  vtexjs.catalog.getCurrentProductWithVariations().then(function(product) {
    console.log(product)
    const sku = product.skus[0];

    if (sku.attachments && sku.attachments.length) {
      $('#your-target-div').html('Available services: ' + sku.attachments.map(a => a.name).join(', '));
    } else {
      $('#your-target-div').html('No services available');
    }
  });
});

3. Make sure your <div> has the correct ID

If your script looks for #your-target-div, but your div looks like this:

<div id="servicos-box"></div>

…then your selector needs to match the exact name:

$('#servicos-box').html(...);

4. You might be using a SKU that has no services

The product you shared (Ortobom mattress) may not have any services linked to it.

If you’re trying to display services like assembly, extended warranty, etc., check in the Admin whether they’re registered and attached to that SKU.


Quick tip to test right now:

Open the page console and run:

vtexjs.catalog.getCurrentProductWithVariations().then(p => console.log(p.skus[0].attachments))

If the result is undefined or [], then the SKU has no registered services.

Can you confirm these points?

The product is showing the services through the native control, so it is registered. Now the data appeared, but it doesn’t add to the cart or comes selected in the cart.


In SERVICES & SKU I only selected it, but didn’t enter any information — can you tell me if that section needs to be filled in?

Here I exported the services spreadsheet and it is linked:

And when testing in the console to check whether the SKU has services registered, it is returning UNDEFINED.

Hey @guilherme.lucashome, I forgot to ask if you checked the Offering parameter.

I dug into the orderform and found the services.

:pushpin: How to check offerings in the orderForm

To confirm that the services appear in the cart, run this in the browser console:

vtexjs.checkout.getOrderForm().then(orderForm => {
  console.log(orderForm.items[0].offerings);
});

It returned:

You might need to pull from it directly rather than from attachments.

How to integrate this into your script to display and add services

Here’s an improved example that fetches the offerings from the orderForm and allows adding the service to the cart:

<div id="service-container"></div>

<script>
  vtexjs.checkout.getOrderForm().then(of => {
    const item = of.items[0];
    if (item.offerings && item.offerings.length) {
      let html = '<h3>Available services</h3><ul>';
      item.offerings.forEach(o => {
        html += `
          <li>
            <strong>${o.name}</strong> – R$ ${ (o.price/100).toFixed(2) }
            <button onclick="vtexjs.checkout.addOffering(${o.id}, 0)">Add</button>
          </li>`;
      });
      html += '</ul>';
      document.getElementById('service-container').innerHTML = html;
    }
  });
</script>
  • item.offerings shows the services available in the cart.
  • addOffering(offeringId, itemIndex) adds the service to the item at the specified index.

See if it works for you.

Good afternoon, Master. Man, I came back to this issue now and in all consoles it’s not returning any information anymore. The service and the attachment are linked to the mentioned product, but now nothing comes through :frowning:

Did you use the latest one I sent?

It looks like VTEX is populating the Offerings.

@guilherme.lucashome Very strange. Are you on the same product?

I’m looking at this one: Cama Box com Colchão de Molas Ensacadas Ortobom ISO SuperPocket Casal 138cm - lucashome

Here it shows up like this:

Is there something on your computer locally, on the network, or in your devtools settings blocking the debug there?

If anything, check through the Orderform and then build it on your end. For example:

Good afternoon @four2one
Now it brought the data. The JS I’m currently using is: https://lucashome.vteximg.com.br/arquivos/garantia-vtex.js
It’s at the same link I shared… but it’s still having issues…