# After Sell Webhook

With webhook you can build custom integration or logic after each sale of a digital product

Setup webhook to your API endpoint

<figure><img src="https://3534572108-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkbSgpG4ocaSynFBlJ9Qt%2Fuploads%2FpC10E6wE40E1AFTOo6N3%2Fimage.png?alt=media&#x26;token=3fb903e9-8033-4f59-985f-cccb544fffde" alt=""><figcaption></figcaption></figure>

**Go to Store page -> Settings**

1. Paste webhook url to which you would like to recieve after sell notifications and click **Apply**
2. Now after sell you will receive notifications in JSON format to your webhook url

Example of JSON which you receive after sell:

```json

{
    "uuid": "4f45e140", // Unique transaction UUID
    "amount": 40,
    "total_amount": 37.74,
    "commission": 2.26,
    "vat": 3.75,
     "metadata" : { 
        "order_id": "559472095N",
        "name": "Alex Brown",
        "shop_url": "https://google.com/"
    },
    "additional_fields": {
        "text_0": { // text_0 is field name
            "text": "Your telegram username", // field title
            "type": "text", // field type
            "value": "@eva.melstore" // value which user fill out on checkout
        },
         "text_1": {  // text_1 is field name
            "text": "Your website url", // Field title
            "type": "text", // field type
            "value": "https://mel.store/eva" // value which user fill out on checkout
        }
    },
    "exchange_rate": 1, // Exchange rate for this payment if the currency is not USD
    "currency": "USD", // Currency of the payment
    "customer_name": "Eva Choo", // Customer's name
    "customer_phone": "+45454286940", // customer phone
    "customer_email": "eva.choo@mel.store", // Customer's email
    "created_at": "1687278245", // Timestamp when the payment was processed
    "product_id": 15, // ID of your product on mel.store
    "product_title": "Individual service for you!", // Title of the product
    "product_type": "CustomService"
}
```

```markup
product_type may has several values:
  
RecurringMembership - Recurring Membership
CustomService - Custom Service
OneToOneCall - 1:1 Call book on calendar
PdfGuideEbook - Pdf Guide Or EBook
```

<table><thead><tr><th width="286"></th><th width="447"></th></tr></thead><tbody><tr><td>uuid</td><td>unique uuid string which identify your transaction</td></tr><tr><td>amount</td><td>Amount paid by the customer in the transaction currency, will include vat amount if VAT applied to this transaction</td></tr><tr><td>total_amount</td><td>amount which credited to your balance, most frequently it would be converted to USD using exchange rate </td></tr><tr><td>exchange_rate</td><td>int or float, it is exchange rate which was applied when total_amount credited to your balance, if it's equal 1 then transaction and wallet where it was credited has the same currency</td></tr><tr><td>commission</td><td>service or platform fee which was applied to process and credit this sell to your wallet, it always has the same currency as wallet where total_amount was credited to your balance, for example: your was credited $100.00 to your balance then fee would be also in USD</td></tr><tr><td>vat</td><td>VAT which was applied to transaction if customer selected country where VAT must be applied: for e.g European Union or UK. If customer paid VAT then platform commission would be calculated from all transaction amount. VAT always has the same currency as original transaction currency, if customer was paid in EUR then VAT amount will be in EUR</td></tr><tr><td>metadata</td><td>arbitrary objects, contains data which you specified while creating a new payment link, please reffer to Restfull API -> Payment Links</td></tr><tr><td>additional_fields</td><td>optional object with additional fields which you've added to checkout page inside product settings (5. Collected customer information), if your customer was fill out additional fields on form while checkout you will get it</td></tr><tr><td>currency</td><td>currency of customer transaction, for e.g USD, EUR, AED</td></tr><tr><td>customer_name</td><td>name of the customer that was filled out on the sales form.</td></tr><tr><td>customer_phone</td><td>phone number of the customer that was filled out on the sales form.</td></tr><tr><td>customer_email</td><td>email of the customer that was filled out on the sales form.</td></tr><tr><td>created_at</td><td>Timestamp when the payment was processed in UTC timezone</td></tr><tr><td>product_id</td><td>Unique id of your product </td></tr><tr><td>product_title</td><td>Title of your product</td></tr><tr><td>product_type</td><td><p>The type of your product may have the following values: </p><pre><code>RecurringMembership - Recurring Subscription
CustomService - Custom Service
OneToOneCall - 1:1 Call book on calendar
PdfGuideEbook - Pdf Guide Or EBook
</code></pre></td></tr></tbody></table>

{% hint style="success" %}
If you needeed more fields, don't hestitate to ask us, some fields we can add rapid for your
{% endhint %}

### Webhook delivery mechanism

* **Your server must return a response code of 200**:

  Your server must acknowledge receipt of webhook notifications by responding with a HTTP 200 status code. Any other response codes indicate a failure in processing the notification correctly.
* **Retry mechanism for unsuccessful deliveries**:
* If your server doesn't return a 200 status code (maybe due to a temporary issue or server downtime), the webhook service will retry sending the notification every hour to ensure successful delivery.
* **Retries will occur for a duration of 1 day**:

  The webhook service will give it another go to send the notification, trying once every hour for a whole day. If at any time during that day your server gives a thumbs up with a 200 status code, the service will stop the retries, happy that the message got through. But if the day ends without a positive response, the service will give up on sending that specific notification.

### Sending test event and check webhook setup

By clicking "check status" button you can see if your webhook setup correctly and returns 200 status code, also it would trigger sending a test event to your webhook url&#x20;

<figure><img src="https://3534572108-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkbSgpG4ocaSynFBlJ9Qt%2Fuploads%2FuOwQVtQUvHUarS8fyrkQ%2Fimage.png?alt=media&#x26;token=e52df783-1652-478c-b572-296647eeb0f8" alt=""><figcaption></figcaption></figure>

### Signing each request

For enhanced security, you can set up a special webhook key that will be attached to the headers of each request as "webhook-key: \<your\_api\_key>". This helps verify that the current request was genuinely sent by mel.store. To generate new key you should click refresh button next to webhook key field.

On your side you can compare key with what what received&#x20;

<figure><img src="https://3534572108-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkbSgpG4ocaSynFBlJ9Qt%2Fuploads%2FN6GoRJh4IrQ99cQ8TjW3%2Fimage.png?alt=media&#x26;token=9ae24a6e-de2c-44f3-b7d1-7fe24ae6ebb4" alt=""><figcaption></figcaption></figure>

### Example of checking and handling webhook on your side

```
Function handleWebhookRequest(request): 
// Extract the webhook-key from request headers
 webhookKeyFromHeaders = request.headers['webhook-key']
 
// Compare the received key with your stored API key
if webhookKeyFromHeaders !== <stored_api_key>:
    // API key mismatch error
    return Response(401, "Unauthorized: Invalid webhook key.")
else:
    // Further process the webhook data
    webhookData = request.body

    // Let's say you want to check the product type and handle it accordingly
    if webhookData.product_type == "RecurringMembership":
        // Handle recurring membership
        processRecurringMembership(webhookData)
    elif webhookData.product_type == "CustomService":
        // Handle custom service
        processCustomService(webhookData)
    // ... Handle other product types similarly ...

    // Return a successful response to acknowledge the receipt of the webhook
    return Response(200, "Webhook processed successfully.")
End Function    
```

###

<br>
