# Note: You need to encrypt the payload first using a script/tool
# See the Encryption Guide for JWE token creation
# 1. Create encrypted JWE token containing: {"webhookStatus": "DISABLED"}
ENCRYPTED_TOKEN="eyJhbGciOiJBMjU2S1ciL..."
# 2. Make API request
curl -X PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/a78efd32-de3b-4854-b599-11ae9f98f97e \
-u sk_your_secret_key: \
-H "Content-Type: application/json" \
-d "{\"request\": {\"Token\": \"$ENCRYPTED_TOKEN\"}}"
# 1. Create encrypted JWE token containing: {"callbackUrl": "https://new-domain.com/webhooks/modulus"}
ENCRYPTED_TOKEN="eyJhbGciOiJBMjU2S1ciL..."
# 2. Make API request
curl -X PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/a78efd32-de3b-4854-b599-11ae9f98f97e \
-u sk_your_secret_key: \
-H "Content-Type: application/json" \
-d "{\"request\": {\"Token\": \"$ENCRYPTED_TOKEN\"}}"
const axios = require('axios');
const jose = require('jose');
const SECRET_KEY = process.env.MODULUS_SECRET_KEY;
const ENCRYPTION_KEY = process.env.MODULUS_ENCRYPTION_KEY;
async function updateWebhook(webhookId, updates) {
// 1. Encrypt payload into JWE token
const key = Buffer.from(ENCRYPTION_KEY, 'base64');
const jweToken = await new jose.CompactEncrypt(
new TextEncoder().encode(JSON.stringify(updates))
)
.setProtectedHeader({ alg: 'A256KW', enc: 'A256CBC-HS512' })
.encrypt(key);
// 2. Make API request
const response = await axios.put(
`https://webhooks.sbx.moduluslabs.io/v1/webhooks/${webhookId}`,
{ request: { Token: jweToken } },
{
auth: { username: SECRET_KEY, password: '' },
headers: { 'Content-Type': 'application/json' }
}
);
const result = response.data;
console.log('Webhook updated successfully');
console.log('Webhook ID:', result.id);
console.log('New URL:', result.callbackUrl);
console.log('New Status:', result.webhookStatus);
return result;
}
// Example: Disable webhook
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', { webhookStatus: 'DISABLED' })
.catch(error => {
console.error('Error:', error.response?.data || error.message);
});
// Example: Change URL
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
callbackUrl: 'https://new-domain.com/webhooks/modulus'
});
// Example: Update multiple fields
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
callbackUrl: 'https://api.example.com/webhooks/success',
webhookAction: 'QRPH_SUCCESS',
webhookStatus: 'ENABLED'
});
import os
import json
import requests
from jose import jwe
SECRET_KEY = os.getenv('MODULUS_SECRET_KEY')
ENCRYPTION_KEY = os.getenv('MODULUS_ENCRYPTION_KEY')
def update_webhook(webhook_id, updates):
# 1. Encrypt payload into JWE token
jwe_token = jwe.encrypt(
json.dumps(updates),
ENCRYPTION_KEY,
algorithm='A256KW',
encryption='A256CBC-HS512'
)
# 2. Make API request
response = requests.put(
f'https://webhooks.sbx.moduluslabs.io/v1/webhooks/{webhook_id}',
json={'request': {'Token': jwe_token}},
auth=(SECRET_KEY, ''),
headers={'Content-Type': 'application/json'}
)
response.raise_for_status()
result = response.json()
print('Webhook updated successfully')
print(f"Webhook ID: {result['id']}")
print(f"New URL: {result['callbackUrl']}")
print(f"New Status: {result['webhookStatus']}")
return result
# Example: Disable webhook
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {'webhookStatus': 'DISABLED'})
# Example: Change URL
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
'callbackUrl': 'https://new-domain.com/webhooks/modulus'
})
# Example: Update multiple fields
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
'callbackUrl': 'https://api.example.com/webhooks/success',
'webhookAction': 'QRPH_SUCCESS',
'webhookStatus': 'ENABLED'
})
<?php
require 'vendor/autoload.php';
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A256KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\Serializer\CompactSerializer;
$secretKey = getenv('MODULUS_SECRET_KEY');
$encryptionKey = getenv('MODULUS_ENCRYPTION_KEY');
function updateWebhook($webhookId, $updates) {
global $secretKey, $encryptionKey;
// 1. Encrypt payload (simplified - use proper JWE library)
// See encryption documentation for full implementation
$jweToken = encryptToJWE(json_encode($updates), $encryptionKey);
// 2. Make API request
$ch = curl_init("https://webhooks.sbx.moduluslabs.io/v1/webhooks/{$webhookId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['request' => ['Token' => $jweToken]]));
curl_setopt($ch, CURLOPT_USERPWD, $secretKey . ':');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
echo "Webhook updated successfully\n";
echo "Webhook ID: {$result['id']}\n";
echo "New URL: {$result['callbackUrl']}\n";
echo "New Status: {$result['webhookStatus']}\n";
return $result;
} else {
echo "Error: HTTP $httpCode\n";
echo "Details: $response\n";
return null;
}
}
// Example: Disable webhook
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', ['webhookStatus' => 'DISABLED']);
// Example: Change URL
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', [
'callbackUrl' => 'https://new-domain.com/webhooks/modulus'
]);
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwe"
)
type TokenWrapper struct {
Token string `json:"Token"`
}
type TokenRequest struct {
Request TokenWrapper `json:"request"`
}
type WebhookResponse struct {
ID string `json:"id"`
WebhookAction string `json:"webhookAction"`
WebhookStatus string `json:"webhookStatus"`
CallbackUrl string `json:"callbackUrl"`
}
func updateWebhook(webhookID string, updates map[string]interface{}) (*WebhookResponse, error) {
secretKey := os.Getenv("MODULUS_SECRET_KEY")
encryptionKey := os.Getenv("MODULUS_ENCRYPTION_KEY")
// 1. Encrypt payload into JWE token
payloadJSON, err := json.Marshal(updates)
if err != nil {
return nil, fmt.Errorf("failed to marshal payload: %w", err)
}
keyBytes, err := base64.RawURLEncoding.DecodeString(encryptionKey)
if err != nil {
return nil, fmt.Errorf("failed to decode encryption key: %w", err)
}
encrypted, err := jwe.Encrypt(payloadJSON,
jwe.WithKey(jwa.A256KW, keyBytes),
jwe.WithContentEncryption(jwa.A256CBC_HS512),
)
if err != nil {
return nil, fmt.Errorf("failed to encrypt payload: %w", err)
}
jweToken := string(encrypted)
// 2. Make API request with Basic Auth
reqBody := TokenRequest{Request: TokenWrapper{Token: jweToken}}
jsonData, _ := json.Marshal(reqBody)
url := fmt.Sprintf("https://webhooks.sbx.moduluslabs.io/v1/webhooks/%s", webhookID)
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.SetBasicAuth(secretKey, "")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode == 200 {
var result WebhookResponse
json.Unmarshal(body, &result)
fmt.Println("Webhook updated successfully")
fmt.Printf("Webhook ID: %s\n", result.ID)
fmt.Printf("New URL: %s\n", result.CallbackUrl)
fmt.Printf("New Status: %s\n", result.WebhookStatus)
return &result, nil
}
return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
}
func main() {
// Example: Disable webhook
_, err := updateWebhook("a78efd32-de3b-4854-b599-11ae9f98f97e", map[string]interface{}{
"webhookStatus": "DISABLED",
})
if err != nil {
fmt.Printf("Failed to update webhook: %v\n", err)
}
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Jose;
namespace ModulusWebhooks;
class Program
{
static async Task Main(string[] args)
{
await UpdateWebhook("a78efd32-de3b-4854-b599-11ae9f98f97e", new
{
callbackUrl = "https://api.yourcompany.com/webhooks/modulus",
webhookAction = "QRPH_SUCCESS",
webhookStatus = "DISABLED"
});
}
static byte[] Base64UrlDecode(string base64Url)
{
var base64 = base64Url
.Replace('-', '+')
.Replace('_', '/');
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
static async Task UpdateWebhook(string webhookId, object updates)
{
var secretKey = Environment.GetEnvironmentVariable("MODULUS_SECRET_KEY");
var encryptionKey = Environment.GetEnvironmentVariable("MODULUS_ENCRYPTION_KEY");
if (string.IsNullOrEmpty(secretKey) || string.IsNullOrEmpty(encryptionKey))
{
Console.WriteLine("Error: MODULUS_SECRET_KEY and MODULUS_ENCRYPTION_KEY must be set");
return;
}
try
{
// 1. Encrypt payload into JWE token
var key = Base64UrlDecode(encryptionKey);
var payloadJson = JsonSerializer.Serialize(updates);
var jweToken = JWT.Encode(
payloadJson,
key,
JweAlgorithm.A256KW,
JweEncryption.A256CBC_HS512
);
// 2. Make API request with Basic Auth
using var client = new HttpClient();
var authBytes = Encoding.ASCII.GetBytes($"{secretKey}:");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authBytes));
var requestBody = new { request = new { Token = jweToken } };
var content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json"
);
var response = await client.PutAsync(
$"https://webhooks.sbx.moduluslabs.io/v1/webhooks/{webhookId}",
content
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<WebhookResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine("Webhook updated successfully");
Console.WriteLine($"Webhook ID: {result?.Id}");
Console.WriteLine($"Webhook URL: {result?.CallbackUrl}");
Console.WriteLine($"Action: {result?.WebhookAction}");
Console.WriteLine($"Status: {result?.WebhookStatus}");
}
else
{
Console.WriteLine($"Error: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
public class WebhookResponse
{
public string? Id { get; set; }
public string? CallbackUrl { get; set; }
public string? WebhookAction { get; set; }
public string? WebhookStatus { get; set; }
}
{
"id": "a78efd32-de3b-4854-b599-11ae9f98f97e",
"webhookAction": "QRPH_SUCCESS",
"webhookStatus": "DISABLED",
"callbackUrl": "https://api.yourcompany.com/webhooks/success",
}
{
"code": "20000002",
"error": "Invalid callbackUrl: must be a valid HTTPS URL",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000013",
"error": "Invalid API Key",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "20000004",
"error": "Webhook not found",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "20000003",
"error": "Webhook URL already exists",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000001",
"error": "An unexpected error occurred. Please try again later.",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
QR PH Webhooks
Update Webhook
Modify an existing webhook endpoint configuration
PUT
/
v1
/
webhooks
/
{id}
# Note: You need to encrypt the payload first using a script/tool
# See the Encryption Guide for JWE token creation
# 1. Create encrypted JWE token containing: {"webhookStatus": "DISABLED"}
ENCRYPTED_TOKEN="eyJhbGciOiJBMjU2S1ciL..."
# 2. Make API request
curl -X PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/a78efd32-de3b-4854-b599-11ae9f98f97e \
-u sk_your_secret_key: \
-H "Content-Type: application/json" \
-d "{\"request\": {\"Token\": \"$ENCRYPTED_TOKEN\"}}"
# 1. Create encrypted JWE token containing: {"callbackUrl": "https://new-domain.com/webhooks/modulus"}
ENCRYPTED_TOKEN="eyJhbGciOiJBMjU2S1ciL..."
# 2. Make API request
curl -X PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/a78efd32-de3b-4854-b599-11ae9f98f97e \
-u sk_your_secret_key: \
-H "Content-Type: application/json" \
-d "{\"request\": {\"Token\": \"$ENCRYPTED_TOKEN\"}}"
const axios = require('axios');
const jose = require('jose');
const SECRET_KEY = process.env.MODULUS_SECRET_KEY;
const ENCRYPTION_KEY = process.env.MODULUS_ENCRYPTION_KEY;
async function updateWebhook(webhookId, updates) {
// 1. Encrypt payload into JWE token
const key = Buffer.from(ENCRYPTION_KEY, 'base64');
const jweToken = await new jose.CompactEncrypt(
new TextEncoder().encode(JSON.stringify(updates))
)
.setProtectedHeader({ alg: 'A256KW', enc: 'A256CBC-HS512' })
.encrypt(key);
// 2. Make API request
const response = await axios.put(
`https://webhooks.sbx.moduluslabs.io/v1/webhooks/${webhookId}`,
{ request: { Token: jweToken } },
{
auth: { username: SECRET_KEY, password: '' },
headers: { 'Content-Type': 'application/json' }
}
);
const result = response.data;
console.log('Webhook updated successfully');
console.log('Webhook ID:', result.id);
console.log('New URL:', result.callbackUrl);
console.log('New Status:', result.webhookStatus);
return result;
}
// Example: Disable webhook
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', { webhookStatus: 'DISABLED' })
.catch(error => {
console.error('Error:', error.response?.data || error.message);
});
// Example: Change URL
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
callbackUrl: 'https://new-domain.com/webhooks/modulus'
});
// Example: Update multiple fields
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
callbackUrl: 'https://api.example.com/webhooks/success',
webhookAction: 'QRPH_SUCCESS',
webhookStatus: 'ENABLED'
});
import os
import json
import requests
from jose import jwe
SECRET_KEY = os.getenv('MODULUS_SECRET_KEY')
ENCRYPTION_KEY = os.getenv('MODULUS_ENCRYPTION_KEY')
def update_webhook(webhook_id, updates):
# 1. Encrypt payload into JWE token
jwe_token = jwe.encrypt(
json.dumps(updates),
ENCRYPTION_KEY,
algorithm='A256KW',
encryption='A256CBC-HS512'
)
# 2. Make API request
response = requests.put(
f'https://webhooks.sbx.moduluslabs.io/v1/webhooks/{webhook_id}',
json={'request': {'Token': jwe_token}},
auth=(SECRET_KEY, ''),
headers={'Content-Type': 'application/json'}
)
response.raise_for_status()
result = response.json()
print('Webhook updated successfully')
print(f"Webhook ID: {result['id']}")
print(f"New URL: {result['callbackUrl']}")
print(f"New Status: {result['webhookStatus']}")
return result
# Example: Disable webhook
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {'webhookStatus': 'DISABLED'})
# Example: Change URL
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
'callbackUrl': 'https://new-domain.com/webhooks/modulus'
})
# Example: Update multiple fields
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
'callbackUrl': 'https://api.example.com/webhooks/success',
'webhookAction': 'QRPH_SUCCESS',
'webhookStatus': 'ENABLED'
})
<?php
require 'vendor/autoload.php';
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A256KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\Serializer\CompactSerializer;
$secretKey = getenv('MODULUS_SECRET_KEY');
$encryptionKey = getenv('MODULUS_ENCRYPTION_KEY');
function updateWebhook($webhookId, $updates) {
global $secretKey, $encryptionKey;
// 1. Encrypt payload (simplified - use proper JWE library)
// See encryption documentation for full implementation
$jweToken = encryptToJWE(json_encode($updates), $encryptionKey);
// 2. Make API request
$ch = curl_init("https://webhooks.sbx.moduluslabs.io/v1/webhooks/{$webhookId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['request' => ['Token' => $jweToken]]));
curl_setopt($ch, CURLOPT_USERPWD, $secretKey . ':');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
echo "Webhook updated successfully\n";
echo "Webhook ID: {$result['id']}\n";
echo "New URL: {$result['callbackUrl']}\n";
echo "New Status: {$result['webhookStatus']}\n";
return $result;
} else {
echo "Error: HTTP $httpCode\n";
echo "Details: $response\n";
return null;
}
}
// Example: Disable webhook
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', ['webhookStatus' => 'DISABLED']);
// Example: Change URL
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', [
'callbackUrl' => 'https://new-domain.com/webhooks/modulus'
]);
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwe"
)
type TokenWrapper struct {
Token string `json:"Token"`
}
type TokenRequest struct {
Request TokenWrapper `json:"request"`
}
type WebhookResponse struct {
ID string `json:"id"`
WebhookAction string `json:"webhookAction"`
WebhookStatus string `json:"webhookStatus"`
CallbackUrl string `json:"callbackUrl"`
}
func updateWebhook(webhookID string, updates map[string]interface{}) (*WebhookResponse, error) {
secretKey := os.Getenv("MODULUS_SECRET_KEY")
encryptionKey := os.Getenv("MODULUS_ENCRYPTION_KEY")
// 1. Encrypt payload into JWE token
payloadJSON, err := json.Marshal(updates)
if err != nil {
return nil, fmt.Errorf("failed to marshal payload: %w", err)
}
keyBytes, err := base64.RawURLEncoding.DecodeString(encryptionKey)
if err != nil {
return nil, fmt.Errorf("failed to decode encryption key: %w", err)
}
encrypted, err := jwe.Encrypt(payloadJSON,
jwe.WithKey(jwa.A256KW, keyBytes),
jwe.WithContentEncryption(jwa.A256CBC_HS512),
)
if err != nil {
return nil, fmt.Errorf("failed to encrypt payload: %w", err)
}
jweToken := string(encrypted)
// 2. Make API request with Basic Auth
reqBody := TokenRequest{Request: TokenWrapper{Token: jweToken}}
jsonData, _ := json.Marshal(reqBody)
url := fmt.Sprintf("https://webhooks.sbx.moduluslabs.io/v1/webhooks/%s", webhookID)
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.SetBasicAuth(secretKey, "")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode == 200 {
var result WebhookResponse
json.Unmarshal(body, &result)
fmt.Println("Webhook updated successfully")
fmt.Printf("Webhook ID: %s\n", result.ID)
fmt.Printf("New URL: %s\n", result.CallbackUrl)
fmt.Printf("New Status: %s\n", result.WebhookStatus)
return &result, nil
}
return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
}
func main() {
// Example: Disable webhook
_, err := updateWebhook("a78efd32-de3b-4854-b599-11ae9f98f97e", map[string]interface{}{
"webhookStatus": "DISABLED",
})
if err != nil {
fmt.Printf("Failed to update webhook: %v\n", err)
}
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Jose;
namespace ModulusWebhooks;
class Program
{
static async Task Main(string[] args)
{
await UpdateWebhook("a78efd32-de3b-4854-b599-11ae9f98f97e", new
{
callbackUrl = "https://api.yourcompany.com/webhooks/modulus",
webhookAction = "QRPH_SUCCESS",
webhookStatus = "DISABLED"
});
}
static byte[] Base64UrlDecode(string base64Url)
{
var base64 = base64Url
.Replace('-', '+')
.Replace('_', '/');
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
static async Task UpdateWebhook(string webhookId, object updates)
{
var secretKey = Environment.GetEnvironmentVariable("MODULUS_SECRET_KEY");
var encryptionKey = Environment.GetEnvironmentVariable("MODULUS_ENCRYPTION_KEY");
if (string.IsNullOrEmpty(secretKey) || string.IsNullOrEmpty(encryptionKey))
{
Console.WriteLine("Error: MODULUS_SECRET_KEY and MODULUS_ENCRYPTION_KEY must be set");
return;
}
try
{
// 1. Encrypt payload into JWE token
var key = Base64UrlDecode(encryptionKey);
var payloadJson = JsonSerializer.Serialize(updates);
var jweToken = JWT.Encode(
payloadJson,
key,
JweAlgorithm.A256KW,
JweEncryption.A256CBC_HS512
);
// 2. Make API request with Basic Auth
using var client = new HttpClient();
var authBytes = Encoding.ASCII.GetBytes($"{secretKey}:");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authBytes));
var requestBody = new { request = new { Token = jweToken } };
var content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json"
);
var response = await client.PutAsync(
$"https://webhooks.sbx.moduluslabs.io/v1/webhooks/{webhookId}",
content
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<WebhookResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine("Webhook updated successfully");
Console.WriteLine($"Webhook ID: {result?.Id}");
Console.WriteLine($"Webhook URL: {result?.CallbackUrl}");
Console.WriteLine($"Action: {result?.WebhookAction}");
Console.WriteLine($"Status: {result?.WebhookStatus}");
}
else
{
Console.WriteLine($"Error: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
public class WebhookResponse
{
public string? Id { get; set; }
public string? CallbackUrl { get; set; }
public string? WebhookAction { get; set; }
public string? WebhookStatus { get; set; }
}
{
"id": "a78efd32-de3b-4854-b599-11ae9f98f97e",
"webhookAction": "QRPH_SUCCESS",
"webhookStatus": "DISABLED",
"callbackUrl": "https://api.yourcompany.com/webhooks/success",
}
{
"code": "20000002",
"error": "Invalid callbackUrl: must be a valid HTTPS URL",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000013",
"error": "Invalid API Key",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "20000004",
"error": "Webhook not found",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "20000003",
"error": "Webhook URL already exists",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000001",
"error": "An unexpected error occurred. Please try again later.",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
Overview
The Update Webhook endpoint allows you to modify an existing webhook’s URL, actions, or status. Use this to change where notifications are sent, adjust which events you receive, or temporarily disable a webhook during maintenance.Endpoint
PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/{id}
Authentication
This endpoint requires HTTP Basic Authentication using your Secret Key.Authorization: Basic {base64(secret_key:)}
Request
Path Parameters
string
required
The unique identifier of the webhook to update. You can get this ID from the Get Webhooks API or from the response when you created the webhook.Example:
"a78efd32-de3b-4854-b599-11ae9f98f97e"Headers
| Header | Value | Required | Description |
|---|---|---|---|
Authorization | Basic {base64(secret_key:)} | Yes | HTTP Basic Auth with your secret key |
Content-Type | application/json | Yes | Request body format |
Prerequisites
Before updating a webhook, ensure you have:- Your Secret Key for HTTP Basic Authentication
- The webhook ID of the webhook you want to update
See the Encryption Guide to understand how JWE tokens work — you’ll need this to decrypt incoming webhook notifications, not for the Update Webhook API request itself.
Body Parameters (Encrypted Payload)
The following parameters describe the payload that must be JWE-encrypted into the
Token field. See the Encryption Guide for details on creating JWE tokens.All body parameters are optional. Include only the fields you want to update. Fields you don’t include will remain unchanged.
| Field | Type | Required | Description |
|---|---|---|---|
callbackUrl | string | No | New HTTPS URL where Modulus Labs sends webhook notifications |
webhookAction | string | No | Updated transaction events: QRPH_SUCCESS, QRPH_DECLINED |
webhookStatus | string | No | New status: ENABLED or DISABLED |
callbackUrl
callbackUrl
The new HTTPS URL where Modulus Labs sends webhook notifications. Must be publicly accessible and use HTTPS.
- Format: Valid HTTPS URL
- Example:
"https://api.yourcompany.com/webhooks/success"
webhookStatus
webhookStatus
New webhook status:
ENABLED- Webhook receives notificationsDISABLED- Webhook stops receiving notifications (useful during maintenance)
"DISABLED"Use
DISABLED during server maintenance instead of deleting the webhook. This preserves your configuration and makes it easy to resume.Example Payloads (Before Encryption)
{
"callbackUrl": "https://api.yourcompany.com/webhooks/success",
"webhookStatus": "DISABLED"
}
{
"webhookStatus": "DISABLED"
}
{
"webhookAction": "QRPH_SUCCESS"
}
{
"callbackUrl": "https://new-domain.com/webhooks/modulus",
"webhookAction": ["QRPH_SUCCESS", "QRPH_DECLINED"],
"webhookStatus": "ENABLED"
}
Response
Success Response
Status Code:200 OK
Returns the updated webhook object with all current values.
string
Unique identifier for the webhook (unchanged).Example:
"a78efd32-de3b-4854-b599-11ae9f98f97e"string
String of webhook actions (updated or unchanged).Example:
"QRPH_SUCCESS"string
Current webhook status (updated or unchanged).Example:
"DISABLED"string
The webhook URL (updated or unchanged).Example:
"https://api.yourcompany.com/webhooks/success"Response Example
{
"id": "a78efd32-de3b-4854-b599-11ae9f98f97e",
"webhookAction": "QRPH_SUCCESS",
"webhookStatus": "DISABLED",
"callbackUrl": "https://api.yourcompany.com/webhooks/success",
}
{
"id": "a78efd32-de3b-4854-b599-11ae9f98f97e",
"webhookAction": "QRPH_SUCCESS",
"webhookStatus": "DISABLED",
"callbackUrl": "https://api.yourcompany.com/webhooks/success",
}
{
"code": "20000002",
"error": "Invalid callbackUrl: must be a valid HTTPS URL",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000013",
"error": "Invalid API Key",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "20000004",
"error": "Webhook not found",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "20000003",
"error": "Webhook URL already exists",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
{
"code": "10000001",
"error": "An unexpected error occurred. Please try again later.",
"referenceNumber": "097bf60a-bdab-40bf-b615-3c0eae693b86"
}
Error Responses
400 Bad Request
400 Bad Request
Status Code: Solutions:
400Causes:- Invalid webhook URL format
- Empty actions array
- Invalid action values
- Invalid status value
{
"code": "20000002",
"error": "Invalid callbackUrl: must be a valid HTTPS URL",
"referenceNumber": "abc123-def456-ghi789"
}
- Ensure callbackUrl uses HTTPS protocol
- Include at least one valid action if updating actions
- Verify status is either
ENABLEDorDISABLED
401 Unauthorized
401 Unauthorized
Status Code:
401Cause: Invalid or missing authentication credentialsSolution:- Verify your secret key is correct
- Ensure Authorization header format:
Basic {base64(secret_key:)}
404 Not Found
404 Not Found
Status Code: Solutions:
404Cause: Webhook ID does not existResponse Example:{
"code": "20000004",
"error": "Webhook not found",
"referenceNumber": "abc123-def456-ghi789"
}
- Verify the webhook ID is correct
- Use Get Webhooks API to find valid webhook IDs
- Check if the webhook was deleted
409 Conflict
409 Conflict
Status Code: Solution:
409Cause: New webhook URL already registered for this merchantResponse Example:{
"code": "20000003",
"error": "Webhook URL already exists",
"referenceNumber": "abc123-def456-ghi789"
}
- Use a different webhook URL, or
- Delete the existing webhook using that URL first
500 Internal Server Error
500 Internal Server Error
Status Code:
500Cause: Unexpected server errorSolution:- Retry the request
- If the issue persists, contact Modulus Labs support
# Note: You need to encrypt the payload first using a script/tool
# See the Encryption Guide for JWE token creation
# 1. Create encrypted JWE token containing: {"webhookStatus": "DISABLED"}
ENCRYPTED_TOKEN="eyJhbGciOiJBMjU2S1ciL..."
# 2. Make API request
curl -X PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/a78efd32-de3b-4854-b599-11ae9f98f97e \
-u sk_your_secret_key: \
-H "Content-Type: application/json" \
-d "{\"request\": {\"Token\": \"$ENCRYPTED_TOKEN\"}}"
# 1. Create encrypted JWE token containing: {"callbackUrl": "https://new-domain.com/webhooks/modulus"}
ENCRYPTED_TOKEN="eyJhbGciOiJBMjU2S1ciL..."
# 2. Make API request
curl -X PUT https://webhooks.sbx.moduluslabs.io/v1/webhooks/a78efd32-de3b-4854-b599-11ae9f98f97e \
-u sk_your_secret_key: \
-H "Content-Type: application/json" \
-d "{\"request\": {\"Token\": \"$ENCRYPTED_TOKEN\"}}"
const axios = require('axios');
const jose = require('jose');
const SECRET_KEY = process.env.MODULUS_SECRET_KEY;
const ENCRYPTION_KEY = process.env.MODULUS_ENCRYPTION_KEY;
async function updateWebhook(webhookId, updates) {
// 1. Encrypt payload into JWE token
const key = Buffer.from(ENCRYPTION_KEY, 'base64');
const jweToken = await new jose.CompactEncrypt(
new TextEncoder().encode(JSON.stringify(updates))
)
.setProtectedHeader({ alg: 'A256KW', enc: 'A256CBC-HS512' })
.encrypt(key);
// 2. Make API request
const response = await axios.put(
`https://webhooks.sbx.moduluslabs.io/v1/webhooks/${webhookId}`,
{ request: { Token: jweToken } },
{
auth: { username: SECRET_KEY, password: '' },
headers: { 'Content-Type': 'application/json' }
}
);
const result = response.data;
console.log('Webhook updated successfully');
console.log('Webhook ID:', result.id);
console.log('New URL:', result.callbackUrl);
console.log('New Status:', result.webhookStatus);
return result;
}
// Example: Disable webhook
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', { webhookStatus: 'DISABLED' })
.catch(error => {
console.error('Error:', error.response?.data || error.message);
});
// Example: Change URL
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
callbackUrl: 'https://new-domain.com/webhooks/modulus'
});
// Example: Update multiple fields
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
callbackUrl: 'https://api.example.com/webhooks/success',
webhookAction: 'QRPH_SUCCESS',
webhookStatus: 'ENABLED'
});
import os
import json
import requests
from jose import jwe
SECRET_KEY = os.getenv('MODULUS_SECRET_KEY')
ENCRYPTION_KEY = os.getenv('MODULUS_ENCRYPTION_KEY')
def update_webhook(webhook_id, updates):
# 1. Encrypt payload into JWE token
jwe_token = jwe.encrypt(
json.dumps(updates),
ENCRYPTION_KEY,
algorithm='A256KW',
encryption='A256CBC-HS512'
)
# 2. Make API request
response = requests.put(
f'https://webhooks.sbx.moduluslabs.io/v1/webhooks/{webhook_id}',
json={'request': {'Token': jwe_token}},
auth=(SECRET_KEY, ''),
headers={'Content-Type': 'application/json'}
)
response.raise_for_status()
result = response.json()
print('Webhook updated successfully')
print(f"Webhook ID: {result['id']}")
print(f"New URL: {result['callbackUrl']}")
print(f"New Status: {result['webhookStatus']}")
return result
# Example: Disable webhook
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {'webhookStatus': 'DISABLED'})
# Example: Change URL
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
'callbackUrl': 'https://new-domain.com/webhooks/modulus'
})
# Example: Update multiple fields
update_webhook('a78efd32-de3b-4854-b599-11ae9f98f97e', {
'callbackUrl': 'https://api.example.com/webhooks/success',
'webhookAction': 'QRPH_SUCCESS',
'webhookStatus': 'ENABLED'
})
<?php
require 'vendor/autoload.php';
use Jose\Component\Core\AlgorithmManager;
use Jose\Component\Core\JWK;
use Jose\Component\Encryption\Algorithm\KeyEncryption\A256KW;
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
use Jose\Component\Encryption\JWEBuilder;
use Jose\Component\Encryption\Serializer\CompactSerializer;
$secretKey = getenv('MODULUS_SECRET_KEY');
$encryptionKey = getenv('MODULUS_ENCRYPTION_KEY');
function updateWebhook($webhookId, $updates) {
global $secretKey, $encryptionKey;
// 1. Encrypt payload (simplified - use proper JWE library)
// See encryption documentation for full implementation
$jweToken = encryptToJWE(json_encode($updates), $encryptionKey);
// 2. Make API request
$ch = curl_init("https://webhooks.sbx.moduluslabs.io/v1/webhooks/{$webhookId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['request' => ['Token' => $jweToken]]));
curl_setopt($ch, CURLOPT_USERPWD, $secretKey . ':');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
echo "Webhook updated successfully\n";
echo "Webhook ID: {$result['id']}\n";
echo "New URL: {$result['callbackUrl']}\n";
echo "New Status: {$result['webhookStatus']}\n";
return $result;
} else {
echo "Error: HTTP $httpCode\n";
echo "Details: $response\n";
return null;
}
}
// Example: Disable webhook
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', ['webhookStatus' => 'DISABLED']);
// Example: Change URL
updateWebhook('a78efd32-de3b-4854-b599-11ae9f98f97e', [
'callbackUrl' => 'https://new-domain.com/webhooks/modulus'
]);
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwe"
)
type TokenWrapper struct {
Token string `json:"Token"`
}
type TokenRequest struct {
Request TokenWrapper `json:"request"`
}
type WebhookResponse struct {
ID string `json:"id"`
WebhookAction string `json:"webhookAction"`
WebhookStatus string `json:"webhookStatus"`
CallbackUrl string `json:"callbackUrl"`
}
func updateWebhook(webhookID string, updates map[string]interface{}) (*WebhookResponse, error) {
secretKey := os.Getenv("MODULUS_SECRET_KEY")
encryptionKey := os.Getenv("MODULUS_ENCRYPTION_KEY")
// 1. Encrypt payload into JWE token
payloadJSON, err := json.Marshal(updates)
if err != nil {
return nil, fmt.Errorf("failed to marshal payload: %w", err)
}
keyBytes, err := base64.RawURLEncoding.DecodeString(encryptionKey)
if err != nil {
return nil, fmt.Errorf("failed to decode encryption key: %w", err)
}
encrypted, err := jwe.Encrypt(payloadJSON,
jwe.WithKey(jwa.A256KW, keyBytes),
jwe.WithContentEncryption(jwa.A256CBC_HS512),
)
if err != nil {
return nil, fmt.Errorf("failed to encrypt payload: %w", err)
}
jweToken := string(encrypted)
// 2. Make API request with Basic Auth
reqBody := TokenRequest{Request: TokenWrapper{Token: jweToken}}
jsonData, _ := json.Marshal(reqBody)
url := fmt.Sprintf("https://webhooks.sbx.moduluslabs.io/v1/webhooks/%s", webhookID)
req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.SetBasicAuth(secretKey, "")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
if resp.StatusCode == 200 {
var result WebhookResponse
json.Unmarshal(body, &result)
fmt.Println("Webhook updated successfully")
fmt.Printf("Webhook ID: %s\n", result.ID)
fmt.Printf("New URL: %s\n", result.CallbackUrl)
fmt.Printf("New Status: %s\n", result.WebhookStatus)
return &result, nil
}
return nil, fmt.Errorf("HTTP %d: %s", resp.StatusCode, string(body))
}
func main() {
// Example: Disable webhook
_, err := updateWebhook("a78efd32-de3b-4854-b599-11ae9f98f97e", map[string]interface{}{
"webhookStatus": "DISABLED",
})
if err != nil {
fmt.Printf("Failed to update webhook: %v\n", err)
}
}
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using Jose;
namespace ModulusWebhooks;
class Program
{
static async Task Main(string[] args)
{
await UpdateWebhook("a78efd32-de3b-4854-b599-11ae9f98f97e", new
{
callbackUrl = "https://api.yourcompany.com/webhooks/modulus",
webhookAction = "QRPH_SUCCESS",
webhookStatus = "DISABLED"
});
}
static byte[] Base64UrlDecode(string base64Url)
{
var base64 = base64Url
.Replace('-', '+')
.Replace('_', '/');
switch (base64.Length % 4)
{
case 2: base64 += "=="; break;
case 3: base64 += "="; break;
}
return Convert.FromBase64String(base64);
}
static async Task UpdateWebhook(string webhookId, object updates)
{
var secretKey = Environment.GetEnvironmentVariable("MODULUS_SECRET_KEY");
var encryptionKey = Environment.GetEnvironmentVariable("MODULUS_ENCRYPTION_KEY");
if (string.IsNullOrEmpty(secretKey) || string.IsNullOrEmpty(encryptionKey))
{
Console.WriteLine("Error: MODULUS_SECRET_KEY and MODULUS_ENCRYPTION_KEY must be set");
return;
}
try
{
// 1. Encrypt payload into JWE token
var key = Base64UrlDecode(encryptionKey);
var payloadJson = JsonSerializer.Serialize(updates);
var jweToken = JWT.Encode(
payloadJson,
key,
JweAlgorithm.A256KW,
JweEncryption.A256CBC_HS512
);
// 2. Make API request with Basic Auth
using var client = new HttpClient();
var authBytes = Encoding.ASCII.GetBytes($"{secretKey}:");
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authBytes));
var requestBody = new { request = new { Token = jweToken } };
var content = new StringContent(
JsonSerializer.Serialize(requestBody),
Encoding.UTF8,
"application/json"
);
var response = await client.PutAsync(
$"https://webhooks.sbx.moduluslabs.io/v1/webhooks/{webhookId}",
content
);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<WebhookResponse>(
responseBody,
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
);
Console.WriteLine("Webhook updated successfully");
Console.WriteLine($"Webhook ID: {result?.Id}");
Console.WriteLine($"Webhook URL: {result?.CallbackUrl}");
Console.WriteLine($"Action: {result?.WebhookAction}");
Console.WriteLine($"Status: {result?.WebhookStatus}");
}
else
{
Console.WriteLine($"Error: HTTP {(int)response.StatusCode}");
Console.WriteLine($"Details: {responseBody}");
}
}
catch (Exception e)
{
Console.WriteLine($"Error: {e.Message}");
}
}
}
public class WebhookResponse
{
public string? Id { get; set; }
public string? CallbackUrl { get; set; }
public string? WebhookAction { get; set; }
public string? WebhookStatus { get; set; }
}
Use Cases
Temporarily Disable During Maintenance
Temporarily Disable During Maintenance
Disable webhooks before server maintenance, enable after completion:
// Before maintenance
await updateWebhook(webhookId, { webhookStatus: 'DISABLED' });
console.log('Webhook disabled for maintenance');
// Perform maintenance...
await upgradeServer();
// After maintenance
await updateWebhook(webhookId, { webhookStatus: 'ENABLED' });
console.log('Webhook re-enabled');
Migrate to New Domain
Migrate to New Domain
Update webhook URL when changing domains or infrastructure:
// Update webhook to point to new domain
await updateWebhook(webhookId, {
callbackUrl: 'https://new-domain.com/webhooks/modulus'
});
console.log('Webhook migrated to new domain');
Adjust Event Subscriptions
Adjust Event Subscriptions
Change which events you want to receive:
// Only receive success events
await updateWebhook(webhookId, {
webhookAction: 'QRPH_SUCCESS'
});
// Later: re-enable declined events
await updateWebhook(webhookId, {
webhookAction: 'QRPH_SUCCESS', 'QRPH_DECLINED'
});
Switch to Versioned Endpoint
Switch to Versioned Endpoint
Update webhook URL to use a new API version:
await updateWebhook(webhookId, {
callbackUrl: 'https://api.example.com/v2/webhooks/modulus'
});
console.log('Webhook updated to v2 endpoint');
Enable After Testing
Enable After Testing
Create disabled webhook for testing, enable when ready:
// Create disabled webhook
const webhook = await createWebhook(
'https://api.example.com/webhooks/test',
['QRPH_SUCCESS', 'QRPH_DECLINED'],
'DISABLED'
);
// Test with Simulate API
await simulateWebhook('SUCCESS');
// Enable after successful test
await updateWebhook(webhook.id, { webhookStatus: 'ENABLED' });
console.log('Webhook enabled after successful testing');
Best Practices
Verify Before Updating
Check current webhook configuration before updating:
const webhooks = await getWebhooks();
const webhook = webhooks.find(w => w.id === webhookId);
console.log('Current config:', webhook);
await updateWebhook(webhookId, { webhookStatus: 'DISABLED' });
Test New URL First
Verify new webhook URL is accessible before updating:
// Test new endpoint
try {
await axios.post(newcallbackUrl, { test: true });
console.log('New endpoint is accessible');
// Update webhook
await updateWebhook(webhookId, { callbackUrl: newcallbackUrl });
} catch (error) {
console.error('New endpoint unreachable, skipping update');
}
Log All Changes
Track webhook configuration changes for audit purposes:
const oldConfig = await getWebhook(webhookId);
await updateWebhook(webhookId, updates);
const newConfig = await getWebhook(webhookId);
await db.webhookAudit.insert({
webhookId,
timestamp: new Date(),
oldConfig,
newConfig,
updates
});
Graceful Status Changes
Notify your team before disabling production webhooks:
async function disableWebhook(webhookId, reason) {
await alertTeam('Disabling webhook', { webhookId, reason });
await updateWebhook(webhookId, { webhookStatus: 'DISABLED' });
console.log(`Webhook ${webhookId} disabled: ${reason}`);
}
disableWebhook(123, 'Server maintenance scheduled');
Partial Updates
You only need to include fields you want to change:// Update only the status (URL and actions remain unchanged)
await updateWebhook(123, {
webhookStatus: 'DISABLED'
});
// Update only the URL (status and actions remain unchanged)
await updateWebhook(123, {
callbackUrl: 'https://new-domain.com/webhooks'
});
// Update everything
await updateWebhook(123, {
callbackUrl: 'https://new-domain.com/webhooks',
webhookAction: 'QRPH_SUCCESS',
webhookStatus: 'ENABLED'
});
Troubleshooting
404 Webhook Not Found
404 Webhook Not Found
Symptom: Receive 404 error when updatingPossible Causes:
- Wrong webhook ID
- Webhook was deleted
- Using wrong secret key (different merchant account)
- Call Get Webhooks API to find valid webhook IDs
- Verify you’re using the correct secret key
- Check if webhook was deleted
409 Conflict on URL Change
409 Conflict on URL Change
Symptom: Receive 409 error when changing webhook URLCause: New URL is already registered for another webhookSolutions:
- Use a different URL
- Delete the other webhook using that URL first
- Keep the current URL
Changes Not Taking Effect
Changes Not Taking Effect
Symptom: Webhook still receives old events or uses old URLPossible Causes:
- Update request failed silently
- Caching issue
- Looking at wrong webhook
- Verify update succeeded by checking response
- Call Get Webhooks API to confirm changes
- Clear any application caches
Next Steps
Delete Webhook
Permanently remove a webhook endpoint
Get Webhooks
View all registered webhooks
Test Webhook
Simulate webhooks to test your integration
Webhooks Overview
Learn about the Webhook API
Authorizations
HTTP Basic Authentication using your Secret Key as the username and an empty password
Path Parameters
The unique identifier of the webhook
Body
application/json
Show child attributes
Show child attributes
Response
Webhook updated successfully
Unique identifier for the webhook
List of transaction events this webhook receives
Available options:
QRPH_SUCCESS, QRPH_DECLINED Current status of the webhook
Available options:
ENABLED, DISABLED The HTTPS URL where notifications are sent
Was this page helpful?
⌘I