# Quick Integration Guide

#### ✅ Step 1: Add Webhook URL to Your Payment Link

When creating a Payment Link:

* Go to **Step 3: Advanced >> Select Webhook**
* Paste your backend URL (e.g., `https://yourdomain.com/webhook`)
* Choose which events you want to receive

#### ✅ Step 2: Verify Signature of Incoming Webhook Request

When a payment occurred, Paymento sends a `POST` request to your endpoint with:

* `Content-Type: application/json`
* `x-signature: <HMAC signature>`

To secure your endpoint:

* Get your `webhook secretkey` from Paymento settings
* Generate HMAC-SHA256 hash of the raw body
* Compare it to the `x-signature` header

**Node.js Example:**

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

const signature = req.headers['x-paymento-signature'];
const secretKey = 'YOUR_MERCHANT_SECRET_KEY'; // From Paymento dashboard

const computed = crypto
  .createHmac('sha256', secretKey)
  .update(req.rawBody)
  .digest('hex');

if (signature !== computed) {
  return res.status(401).send('Invalid signature');
}
```

#### ✅ Step 3: Handle Events

#### Use Events to Automate Logic

Example use cases:

* `payment_link.paid`: Subscribe user to your service
* `subscription.renewed`: Extend subscription
* `subscription.grace_expired`: Revoke access
* `payment_link.failed`: Alert user or retry flow

**Node.js Example:**

```javascript
const event = req.body;

switch (event.event.type) {
  case 'payment_link.paid':
    // Customer paid successfully
    activateSubscription(event.customer.email);
    break;
    
  case 'payment_link.deferred':
    // Payment was not made on time
    suspendSubscription(event.customer.email);
    break;
}

res.status(200).json({ received: true });
```

### Checklist ✅

Before going live, Make sure:

* [ ] &#x20;Endpoint uses HTTPS
* [ ] &#x20;Signature verification implemented
* [ ] &#x20;Returns 200 OK within 5 seconds
* [ ] &#x20;Handles idempotency (checks `event.id`)
* [ ] &#x20;Logs all webhook requests
* [ ] &#x20;Secret key stored securely (environment variable)
* [ ] &#x20;Error handling implemented
* [ ] &#x20;Tested with Paymento test webhook feature<br>

#### Headers Reference

```http
X-Paymento-Signature: <hmac-sha256-hex>
X-Paymento-Timestamp: <unix-timestamp>
X-Paymento-Event-Id: evt_<unique-id>
X-Paymento-Event-Type: payment_link.paid
```

### Body Structure

```json
{
  "event": {
    "id": "evt_...",
    "type": "payment_link.paid | payment_link.deferred",
    "createdAt": "ISO-8601",
    "apiVersion": "v1"
  },
  "paymentLink": {
    "id": "pl_...",
    "title": "string",
    "description": "string",
    "status": "paid | deferred",
    "type": "one_time | scheduled",
    "createdAt": "ISO-8601",
    "paidAt": "ISO-8601 | null",
    "url": "string"
  },
  "customer": {
    "email": "string",
    "name": "string",
    "metadata": {
      "order_id": "string?",
      "payment_id": "string?"
    }
  },
  "merchant": {
    "id": "string",
    "name": "string"
  }
}
```

#### 🔍 Available Events

| Event                        | Description                       |
| ---------------------------- | --------------------------------- |
| `payment_link.paid`          | Payment completed                 |
| `payment_link.failed`        | Payment failed                    |
| `payment_link.expired`       | Link expired without payment      |
| `subscription.renewed`       | Subscription renewed by user      |
| `subscription.reminder_sent` | Reminder sent (email or Telegram) |
| `subscription.grace_expired` | User did not pay, grace ended     |

### Signature Verification (Code Samples)

#### Node.js

```javascript
const crypto = require('crypto');
const signature = crypto
  .createHmac('sha256', secretKey)
  .update(rawBody)
  .digest('hex');
```

#### Python

```python
import hmac
import hashlib
signature = hmac.new(
    secret_key.encode('utf-8'),
    raw_body.encode('utf-8'),
    hashlib.sha256
).hexdigest()
```

#### PHP

```php
$signature = hash_hmac('sha256', $rawBody, $secretKey);
```

#### C\#

```csharp
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(rawBody));
var signature = BitConverter.ToString(hash).Replace("-", "").ToLower();
```

#### Ruby

```ruby
require 'openssl'
signature = OpenSSL::HMAC.hexdigest('sha256', secret_key, raw_body)
```

#### Go

```go
import "crypto/hmac"
import "crypto/sha256"
import "encoding/hex"

mac := hmac.New(sha256.New, []byte(secretKey))
mac.Write([]byte(rawBody))
signature := hex.EncodeToString(mac.Sum(nil))
```

#### Java

```java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;

Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(rawBody.getBytes());
String signature = Hex.encodeHexString(hash);
```


---

# 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.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide.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.
