Webhooks
Razorpay Webhook
Receive and process webhook events from Razorpay.
POST
/
webhooks
/
razorpay
Razorpay webhook receiver
curl --request POST \
--url https://billing.example.com/webhooks/razorpay \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'X-Razorpay-Signature: <x-razorpay-signature>' \
--data '{}'import requests
url = "https://billing.example.com/webhooks/razorpay"
payload = {}
headers = {
"X-Razorpay-Signature": "<x-razorpay-signature>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Razorpay-Signature': '<x-razorpay-signature>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({})
};
fetch('https://billing.example.com/webhooks/razorpay', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://billing.example.com/webhooks/razorpay",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"X-Razorpay-Signature: <x-razorpay-signature>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://billing.example.com/webhooks/razorpay"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Razorpay-Signature", "<x-razorpay-signature>")
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://billing.example.com/webhooks/razorpay")
.header("X-Razorpay-Signature", "<x-razorpay-signature>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://billing.example.com/webhooks/razorpay")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Razorpay-Signature"] = '<x-razorpay-signature>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"status": "ok",
"reason": "<string>"
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}This endpoint receives webhook events from Razorpay when payment-related events
occur, such as successful payments, failed payments, and refunds.
This endpoint verifies the webhook signature using your Razorpay webhook secret.
Configure this URL in your Razorpay Dashboard under Settings > Webhooks with
the URL
https://api.recurso.dev/webhooks/razorpay.Example Request
Razorpay sends a POST request with event data:curl -X POST https://api.recurso.dev/webhooks/razorpay \
-H "Content-Type: application/json" \
-H "X-Razorpay-Signature: sha256_hmac_signature_here" \
-d '{
"entity": "event",
"event": "payment.captured",
"payload": {
"payment": {
"entity": {
"id": "pay_RzpABC123",
"amount": 249900,
"currency": "INR",
"status": "captured",
"order_id": "order_RzpDEF456"
}
}
}
}'
Response
Returns200 OK on successful processing.
{
"status": "ok"
}
If signature verification fails, the endpoint returns
400 Bad Request and the
event is not processed. Ensure your Razorpay webhook secret in Recurso matches
the one configured in the Razorpay Dashboard.Authorizations
Headers
HMAC-SHA256 signature of the raw request body.
Body
application/json
Raw Razorpay event payload.
⌘I
Razorpay webhook receiver
curl --request POST \
--url https://billing.example.com/webhooks/razorpay \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--header 'X-Razorpay-Signature: <x-razorpay-signature>' \
--data '{}'import requests
url = "https://billing.example.com/webhooks/razorpay"
payload = {}
headers = {
"X-Razorpay-Signature": "<x-razorpay-signature>",
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Razorpay-Signature': '<x-razorpay-signature>',
Authorization: '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({})
};
fetch('https://billing.example.com/webhooks/razorpay', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://billing.example.com/webhooks/razorpay",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json",
"X-Razorpay-Signature: <x-razorpay-signature>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://billing.example.com/webhooks/razorpay"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Razorpay-Signature", "<x-razorpay-signature>")
req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://billing.example.com/webhooks/razorpay")
.header("X-Razorpay-Signature", "<x-razorpay-signature>")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://billing.example.com/webhooks/razorpay")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Razorpay-Signature"] = '<x-razorpay-signature>'
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"status": "ok",
"reason": "<string>"
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}{
"error": {
"code": "BAD_REQUEST",
"message": "<string>"
}
}