# Installing Upzelo

## 1. Insert the Upzelo JS Snippet

The following code will add the Upzelo client-side script and make itself available in the global JS namespace as `window.upzelo`. Place the following snippet into your `<head>` element.

```html
<script
  id="upzpdl"
  src="https://assets.upzelo.com/upzelo.min.js"
  appId="Upzelo App ID"
></script>
```

{% hint style="info" %}
You can find your App ID [here](https://upzelo.com/app/developer/api-keys)
{% endhint %}

## 2. Server-side authentication

{% hint style="warning" %}
This is only required if you wish for Upzelo to take action on your behalf with your payment provider.
{% endhint %}

Server-side authentication is in place to make sure that any requests Upzelo makes to your payment provider on your behalf are authorised and legitimate. This is achieved by you generating an HMAC hash (SHA256 algorithm) with the `customerId` and your `retentionAPI` key.

{% hint style="info" %}
You can find your retentionAPI key [here](https://upzelo.com/app/developer/api-keys)
{% endhint %}

When Upzelo makes a request, it will compare the HMAC hash sent with one that is generated on our servers to ensure that the request is legitimate. Below are some examples of how this hash can be generated in different backend languages.

{% tabs %}
{% tab title="PHP" %}

```php
<?php

declare(strict_types=1);

$retentionApiKey = 'upz_1234'; // Replace with retentionApi key.
$customerId = 'cus_1234'; // Replace with a real customer ID

echo hash_hmac('sha256', $customerId, $retentionApiKey);
// bd9d2eca979333103b3d93a80e8efcbd0f8421813fdb9feefffde2206b4115e8
```

{% endtab %}

{% tab title="Go" %}

```go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
)

func main() {
	// Set the retentionApi Key
	retentionApiKey := "upz_1234"
	// Set the customerId
	customerId := "cus_1234"

	// Generate an HMAC hash.
	hash := hmac.New(sha256.New, []byte(retentionApiKey))
	hash.Write([]byte(customerId))
	hmac := hex.EncodeToString(hash.Sum(nil))

	fmt.Println(hmac)
	// bd9d2eca979333103b3d93a80e8efcbd0f8421813fdb9feefffde2206b4115e8
}
```

{% endtab %}

{% tab title="Python" %}

```python
import hmac
import hashlib

retention_api_key = "upz_1234"
customer_id = "cus_1234"
hmac_hash = hmac.new(
    retention_api_key.encode(),
    customer_id.encode(),
    digestmod=hashlib.sha256
).hexdigest()

print("{}".format(hmac_hash))
# bd9d2eca979333103b3d93a80e8efcbd0f8421813fdb9feefffde2206b4115e8
```

{% endtab %}

{% tab title="Ruby" %}

```ruby
require 'openssl'

retentionApiKey = "upz_1234"
customerId = "cus_1234"

hmacHash = OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest.new('sha256'),
    retentionApiKey,
    customerId
)

print hmacHash
# bd9d2eca979333103b3d93a80e8efcbd0f8421813fdb9feefffde2206b4115e8
```

{% endtab %}

{% tab title="Node" %}

```javascript
const crypto = require("crypto");

const retentionApiKey = 'upz_1234';
const customerId = 'cus_1234';

const hmacHash = crypto.createHmac(
    'sha256',
    retentionApiKey
).update(customerId).digest('hex');

console.log(hmacHash);
// bd9d2eca979333103b3d93a80e8efcbd0f8421813fdb9feefffde2206b4115e8
```

{% endtab %}
{% endtabs %}

## 3. Link your cancel button

Once you have generated an HMAC hash and passed it along to your front end, you can initialise Upzelo and define how you'd like it to be displayed. If you are opting to not have Upzelo take action on your behalf, you may omit the `hash` and `type` parameters.

One typical way of implementing Upzelo would be to attach an event listener to a button.

```javascript
const cancelButton = document.getElementById('cancel-button');

cancelButton.addEventListener('click', () => {
    // Upzelo Config object.
    const config = {
        // The customer's ID from the subscription platform
        customerId: 'cus_1234',
        // The customer's subscription ID from the subscription platform
        subscriptionId: 'sub_1234',
        // The HMAC hash generated in step 2
        hash: 'bd9d2eca979333103b3d93a80e8efcbd0f8421813fdb9feefffde2206b4115e8',
        // The type of flow to serve
        type: 'full', 
        // The mode that we are working with.
        mode: 'live',
    };
    window.upzelo.open(config);
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.upzelo.com/developer-guide/installing-upzelo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
