Quick Integration Guide
For developers to automatePayment Link actions
✅ 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/jsonx-signature: <HMAC signature>
To secure your endpoint:
Get your
webhook secretkeyfrom Paymento settingsGenerate HMAC-SHA256 hash of the raw body
Compare it to the
x-signatureheader
Node.js Example:
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 servicesubscription.renewed: Extend subscriptionsubscription.grace_expired: Revoke accesspayment_link.failed: Alert user or retry flow
Node.js Example:
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:
Headers Reference
X-Paymento-Signature: <hmac-sha256-hex>
X-Paymento-Timestamp: <unix-timestamp>
X-Paymento-Event-Id: evt_<unique-id>
X-Paymento-Event-Type: payment_link.paidBody Structure
{
"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
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
const crypto = require('crypto');
const signature = crypto
.createHmac('sha256', secretKey)
.update(rawBody)
.digest('hex');Python
import hmac
import hashlib
signature = hmac.new(
secret_key.encode('utf-8'),
raw_body.encode('utf-8'),
hashlib.sha256
).hexdigest()PHP
$signature = hash_hmac('sha256', $rawBody, $secretKey);C#
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
require 'openssl'
signature = OpenSSL::HMAC.hexdigest('sha256', secret_key, raw_body)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
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);Last updated