# Product Update Notification API

This API allows customers with a custom e-commerce integration plugin to send product update notifications by signing the request payload with HMAC authentication.

### **Endpoint**

```http
POST https://ingest.hello-lisa.com/plugin-notifications/{id}/updates
```

***

### **Headers**

<table><thead><tr><th valign="top">Header</th><th>Description</th></tr></thead><tbody><tr><td valign="top"><code>X-Hmac-Signature</code></td><td>HMAC-SHA256 signature of the request body</td></tr><tr><td valign="top"><code>Authorization</code></td><td><p>API key for authentication</p><pre class="language-http"><code class="lang-http">ApiKey &#x3C;API_KEY>
</code></pre></td></tr><tr><td valign="top"><code>Content-Type</code></td><td><code>application/json</code></td></tr></tbody></table>

***

### **Parameters**

{% hint style="info" %}
The `id` parameter value can be obtained form the plugins page in the LiSA Console.
{% endhint %}

<table><thead><tr><th valign="top">Parameter</th><th>Description</th></tr></thead><tbody><tr><td valign="top"><code>id</code></td><td>The distinct identifier of the e-commerce plugin integration.</td></tr></tbody></table>

### **Payload Requirements**

* JSON format
* Maximum size: **192 KB**
* Must be signed using **HMAC-SHA256** with the secret provided upon registration.

***

### **How to Sign the Request**

Use the **HMAC-SHA256** algorithm to sign the JSON payload with the provided secret key. The resulting hex-encoded digest should be sent in the `X-Hmac-Signature` header.

#### **Code Samples**

{% tabs %}
{% tab title="Node.js" %}

```javascript
const crypto = require('crypto');
const axios = require('axios');

const apiKey = 'your-api-key';
const secret = 'your-secret-key';
const url = 'https://ingest.hello-lisa.com/plugin-notifications/{id}/updates';
const payload = JSON.stringify({ productId: "123", price: 19.99 });

const signature = crypto.createHmac('sha256', secret)
                        .update(payload)
                        .digest('hex');

axios.post(url, payload, {
    headers: {
        'Authorization': `ApiKey ${apiKey}`,
        'Content-Type': 'application/json',
        'X-Hmac-Signature': signature
    }
}).then(response => console.log(response.data))
  .catch(error => console.error(error.response?.data || error));
```

{% endtab %}

{% tab title="Python" %}

```python
import hashlib
import hmac
import json
import requests

api_key = b'your-api-key'
secret = b'your-secret-key'
url = 'https://ingest.hello-lisa.com/plugin-notifications/{id}/updates'
payload = json.dumps({"productId": "123", "price": 19.99})

signature = hmac.new(secret, payload.encode(), hashlib.sha256).hexdigest()

headers = {
    'Authorization': f'ApiKey {api_key}',
    'Content-Type': 'application/json',
    'X-Hmac-Signature': signature
}

response = requests.post(url, data=payload, headers=headers)
print(response.json())
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	apiKey := []byte("your-api-key")
	secret := []byte("your-secret-key")
	url := "https://ingest.hello-lisa.com/plugin-notifications/{id}/updates"

	payload, _ := json.Marshal(map[string]interface{}{
		"productId": "123",
		"price":     19.99,
	})

	h := hmac.New(sha256.New, secret)
	h.Write(payload)
	signature := hex.EncodeToString(h.Sum(nil))

	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))
	req.Header.Set("Authorization", "ApiKey " + apiKey)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-Hmac-Signature", signature)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer resp.Body.Close()
	fmt.Println("Response Status:", resp.Status)
}
```

{% endtab %}

{% tab title="Rust" %}

```rust
use hmac::{Hmac, Mac};
use reqwest::blocking::Client;
use serde_json::json;
use sha2::Sha256;

fn main() {
    let api_key = "your-api-key";
    let secret = "your-secret-key";
    let url = "https://ingest.hello-lisa.com/plugin-notifications/{id}/updates";

    let payload = json!({
        "productId": "123",
        "price": 19.99
    }).to_string();

    let mut mac = Hmac::<Sha256>::new_from_slice(secret.as_bytes()).expect("HMAC can take key of any size");
    mac.update(payload.as_bytes());
    let signature = hex::encode(mac.finalize().into_bytes());

    let client = Client::new();
    let res = client.post(url)
        .header("Authorization", format!("ApiKey {}", api_key))
        .header("Content-Type", "application/json")
        .header("X-Hmac-Signature", signature)
        .body(payload)
        .send()
        .expect("Failed to send request");

    println!("Response: {:?}", res.text().unwrap());
}
```

{% endtab %}

{% tab title="Scala" %}

```scala
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import scala.util.Try
import scalaj.http._

object HmacSignatureExample extends App {
  val apiKey = "your-api-key".getBytes("UTF-8")
  val secret = "your-secret-key".getBytes("UTF-8")
  val url = "https://ingest.hello-lisa.com/plugin-notifications/{id}/updates"

  val payload = """{"productId":"123","price":19.99}"""

  def signHmacSHA256(data: String, key: Array[Byte]): String = {
    val mac = Mac.getInstance("HmacSHA256")
    mac.init(new SecretKeySpec(key, "HmacSHA256"))
    mac.doFinal(data.getBytes("UTF-8")).map("%02x".format(_)).mkString
  }

  val signature = signHmacSHA256(payload, secret)

  val response = Http(url)
    .postData(payload)
    .header("Authorization", s"ApiKey $apiKey")
    .header("Content-Type", "application/json")
    .header("X-Hmac-Signature", signature)
    .asString

  println(response.body)
}
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        string apiKey = "your-api-key";
        string secret = "your-secret-key";
        string url = "https://ingest.hello-lisa.com/plugin-notifications/{id}/updates";
        string payload = "{\"productId\":\"123\",\"price\":19.99}";

        using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
        string signature = BitConverter.ToString(hmac.ComputeHash(Encoding.UTF8.GetBytes(payload))).Replace("-", "").ToLower();

        using var client = new HttpClient();
        var request = new HttpRequestMessage(HttpMethod.Post, url)
        {
            Content = new StringContent(payload, Encoding.UTF8, "application/json")
        };
        request.Headers.Add("Authorization", $"ApiKey {apiKey}");
        request.Headers.Add("X-Hmac-Signature", signature);

        HttpResponseMessage response = await client.SendAsync(request);
        string responseBody = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseBody);
    }
}
```

{% endtab %}
{% endtabs %}

***

### **Error Handling**

<table><thead><tr><th width="280">HTTP Status Code</th><th>Meaning</th></tr></thead><tbody><tr><td><code>202 Accepted</code></td><td>Request received and processing asynchronously</td></tr><tr><td><code>400 Bad Request</code></td><td>Invalid or missing signature</td></tr><tr><td><code>401 Unauthorized</code></td><td>Invalid secret or signature</td></tr><tr><td><code>413 Payload Too Large</code></td><td>Payload exceeds 192 KB limit</td></tr></tbody></table>
