Webhook Signature Verification

MeSomb signs every webhook request sent to your endpoint. This allows your application to verify that the webhook was really sent by MeSomb and that the payload was not modified in transit.

Webhook signature verification is strongly recommended for all production integrations.

How it works

When you create a webhook endpoint in MeSomb, a unique webhook signing secret is generated for that endpoint.

Example:

<span><span style="color: undefined">whsec_8d7f2c9a4b6e1...</span></span>
<span><span style="color: undefined"></span></span>

You must store this secret securely on your server. MeSomb will only show it once when the webhook endpoint is created.

For every webhook delivery, MeSomb sends signature information in HTTP headers.

Example:

<span><span style="color: undefined">X-MeSomb-Webhook-Event-Id: evt_01HX9K7Y6N4V2X8QJ4K2M9ZP3A</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Request-Timestamp: 1778192130</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Signature: t=1778192130,v1=6f1a0c8e8d7f2c9a4b6e1...</span></span>
<span><span style="color: undefined"></span></span>

Your server must use these headers, the raw request body, and your webhook signing secret to verify the request.

Signature headers

MeSomb includes the following headers in each webhook request.

HeaderDescription
X-MeSomb-Webhook-Event-IdUnique ID of the webhook event. Use it for deduplication.
X-MeSomb-Webhook-Request-TimestampUnix timestamp indicating when the webhook was signed.
X-MeSomb-Webhook-SignatureSignature header containing the timestamp and HMAC signature.

Example:

<span><span style="color: undefined">X-MeSomb-Webhook-Event-Id: evt_01HX9K7Y6N4V2X8QJ4K2M9ZP3A</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Request-Timestamp: 1778192130</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Signature: t=1778192130,v1=6f1a0c8e8d7f2c9a4b6e1...</span></span>
<span><span style="color: undefined"></span></span>

Signature format

The X-MeSomb-Webhook-Signature header has the following format:

<span><span style="color: undefined">t=&lt;timestamp&gt;,v1=&lt;signature&gt;</span></span>
<span><span style="color: undefined"></span></span>

Example:

<span><span style="color: undefined">t=1778192130,v1=6f1a0c8e8d7f2c9a4b6e1...</span></span>
<span><span style="color: undefined"></span></span>

Where:

PartDescription
tUnix timestamp used when generating the signature.
v1HMAC-SHA256 signature of the webhook payload.

How to verify a webhook

To verify a webhook request, your server must:

  1. Extract the X-MeSomb-Webhook-Signature header.
  2. Extract the timestamp t.
  3. Extract the signature value v1.
  4. Get the raw request body exactly as received.
  5. Build the signed payload using this format:
<span><span style="color: undefined">&lt;timestamp&gt;.&lt;raw_body&gt;</span></span>
<span><span style="color: undefined"></span></span>
  1. Compute the HMAC-SHA256 signature using your webhook signing secret.
  2. Compare your computed signature with the v1 signature from the header.
  3. Reject the webhook if the signature does not match.
  4. Reject the webhook if the timestamp is too old.

Signed payload format

The signed payload is created by joining the timestamp, a dot, and the raw request body.

<span><span style="color: undefined">timestamp + &quot;.&quot; + raw_body</span></span>
<span><span style="color: undefined"></span></span>

Example:

<span><span style="color: undefined">1778192130.{&quot;id&quot;:&quot;evt_01HX...&quot;,&quot;object&quot;:&quot;event&quot;,&quot;type&quot;:&quot;payment.transaction.succeeded&quot;}</span></span>
<span><span style="color: undefined"></span></span>

Important: use the raw request body, not a parsed and re-serialized JSON object.

This is important because small changes in spaces, line breaks, or field ordering will produce a different signature.

Signature algorithm

MeSomb uses HMAC with SHA-256.

<span><span style="color: undefined">HMAC-SHA256(webhook_signing_secret, signed_payload)</span></span>
<span><span style="color: undefined"></span></span>

The result is encoded as a lowercase hexadecimal string.

Timestamp tolerance

To help protect against replay attacks, your server should reject webhook requests with an old timestamp.

Recommended tolerance:

<span><span style="color: undefined">5 minutes</span></span>
<span><span style="color: undefined"></span></span>

For example, if the timestamp in the webhook is older than 5 minutes compared to your server time, reject the request.

Your server time should be synchronized using NTP or another reliable time source.

Deduplication

MeSomb may send the same webhook event more than once.

This can happen when:

  • your server does not respond with a 2xx status code;
  • the network fails before MeSomb receives your response;
  • the webhook is manually replayed;
  • MeSomb retries a failed delivery.

Your integration must be idempotent.

Use the X-MeSomb-Webhook-Event-Id header or the id field in the webhook body to detect duplicate events.

Example:

<span><span style="color: undefined">X-MeSomb-Webhook-Event-Id: evt_01HX9K7Y6N4V2X8QJ4K2M9ZP3A</span></span>
<span><span style="color: undefined"></span></span>

Store processed event IDs in your database. If the same event ID is received again, return a successful 2xx response without processing the business action again.

flowchart TD A[Receive webhook request] --> B[Read raw request body] B --> C[Read X-MeSomb-Webhook-Signature header] C --> D[Extract timestamp and v1 signature] D --> E[Check timestamp tolerance] E --> F[Compute expected HMAC-SHA256 signature] F --> G[Compare signatures securely] G --> H[Check event ID for duplicates] H --> I[Process event] I --> J[Return 2xx response]

Example webhook request

<span><span style="color: undefined">POST /webhooks/mesomb HTTP/1.1</span></span>
<span><span style="color: undefined">Host: merchant.example.com</span></span>
<span><span style="color: undefined">Content-Type: application/json</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Event-Id: evt_01HX9K7Y6N4V2X8QJ4K2M9ZP3A</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Request-Timestamp: 1778192130</span></span>
<span><span style="color: undefined">X-MeSomb-Webhook-Signature: t=1778192130,v1=6f1a0c8e8d7f2c9a4b6e1...</span></span>
<span><span style="color: undefined"></span></span>
<span><span style="color: undefined">{</span></span>
<span><span style="color: undefined">  &quot;id&quot;: &quot;evt_01HX9K7Y6N4V2X8QJ4K2M9ZP3A&quot;,</span></span>
<span><span style="color: undefined">  &quot;object_type&quot;: &quot;event&quot;,</span></span>
<span><span style="color: undefined">  &quot;event_type&quot;: &quot;payment.transaction.succeeded&quot;,</span></span>
<span><span style="color: undefined">  &quot;api_version&quot;: &quot;2026-05-01&quot;,</span></span>
<span><span style="color: undefined">  &quot;created_at&quot;: &quot;2026-05-07T22:15:30Z&quot;,</span></span>
<span><span style="color: undefined">  &quot;livemode&quot;: true,</span></span>
<span><span style="color: undefined">  &quot;data&quot;: {</span></span>
<span><span style="color: undefined">    &quot;object&quot;: {</span></span>
<span><span style="color: undefined">      &quot;id&quot;: &quot;txn_01HX9K7A1R6F8MZK2Q9V7N4P5B&quot;,</span></span>
<span><span style="color: undefined">      &quot;object&quot;: &quot;payment_transaction&quot;,</span></span>
<span><span style="color: undefined">      &quot;status&quot;: &quot;succeeded&quot;,</span></span>
<span><span style="color: undefined">      &quot;amount&quot;: 15000,</span></span>
<span><span style="color: undefined">      &quot;currency&quot;: &quot;XAF&quot;,</span></span>
<span><span style="color: undefined">      &quot;reference&quot;: &quot;ORDER-10045&quot;</span></span>
<span><span style="color: undefined">    }</span></span>
<span><span style="color: undefined">  }</span></span>
<span><span style="color: undefined">}</span></span>
<span><span style="color: undefined"></span></span>

Code examples

Example

<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">crypto</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">require</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;crypto&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">verifyMeSombWebhook</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">rawBody</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">signatureHeader</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">webhookSecret</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">toleranceSeconds </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">300</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">}) {</span></span>
<span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">signatureHeader) {</span></span>
<span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Missing X-MeSomb-Webhook-Signature header&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">parts</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">signatureHeader</span><span style="color: var(--shiki-token-function)">.split</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;,&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">timestampPart</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">parts</span><span style="color: var(--shiki-token-function)">.find</span><span style="color: var(--shiki-color-text)">((part) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">part</span><span style="color: var(--shiki-token-function)">.startsWith</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;t=&quot;</span><span style="color: var(--shiki-color-text)">));</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">signaturePart</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">parts</span><span style="color: var(--shiki-token-function)">.find</span><span style="color: var(--shiki-color-text)">((part) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">part</span><span style="color: var(--shiki-token-function)">.startsWith</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;v1=&quot;</span><span style="color: var(--shiki-color-text)">));</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">timestampPart </span><span style="color: var(--shiki-token-keyword)">||</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-color-text)">signaturePart) {</span></span>
<span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Invalid X-MeSomb-Webhook-Signature header format&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">timestamp</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">timestampPart</span><span style="color: var(--shiki-token-function)">.slice</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">2</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">receivedSignature</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">signaturePart</span><span style="color: var(--shiki-token-function)">.slice</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">3</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">timestampNumber</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Number</span><span style="color: var(--shiki-color-text)">(timestamp);</span></span>
<span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-token-constant)">Number</span><span style="color: var(--shiki-token-function)">.isFinite</span><span style="color: var(--shiki-color-text)">(timestampNumber)) {</span></span>
<span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Invalid signature timestamp&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">now</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Math</span><span style="color: var(--shiki-token-function)">.floor</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">Date</span><span style="color: var(--shiki-token-function)">.now</span><span style="color: var(--shiki-color-text)">() </span><span style="color: var(--shiki-token-keyword)">/</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">1000</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">age</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Math</span><span style="color: var(--shiki-token-function)">.abs</span><span style="color: var(--shiki-color-text)">(now </span><span style="color: var(--shiki-token-keyword)">-</span><span style="color: var(--shiki-color-text)"> timestampNumber);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (age </span><span style="color: var(--shiki-token-keyword)">&gt;</span><span style="color: var(--shiki-color-text)"> toleranceSeconds) {</span></span>
<span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Webhook timestamp is outside the allowed tolerance&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">signedPayload</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-color-text)">timestamp</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">.</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-color-text)">rawBody</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">expectedSignature</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> crypto</span></span>
<span><span style="color: var(--shiki-token-function)">.createHmac</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;sha256&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> webhookSecret)</span></span>
<span><span style="color: var(--shiki-token-function)">.update</span><span style="color: var(--shiki-color-text)">(signedPayload</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;utf8&quot;</span><span style="color: var(--shiki-color-text)">)</span></span>
<span><span style="color: var(--shiki-token-function)">.digest</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;hex&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">receivedBuffer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Buffer</span><span style="color: var(--shiki-token-function)">.from</span><span style="color: var(--shiki-color-text)">(receivedSignature</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;hex&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">expectedBuffer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">Buffer</span><span style="color: var(--shiki-token-function)">.from</span><span style="color: var(--shiki-color-text)">(expectedSignature</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;hex&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">if</span><span style="color: var(--shiki-color-text)"> (</span></span>
<span><span style="color: var(--shiki-token-constant)">receivedBuffer</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">!==</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">expectedBuffer</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">length</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">||</span></span>
<span><span style="color: var(--shiki-token-keyword)">!</span><span style="color: var(--shiki-token-constant)">crypto</span><span style="color: var(--shiki-token-function)">.timingSafeEqual</span><span style="color: var(--shiki-color-text)">(receivedBuffer</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> expectedBuffer)</span></span>
<span><span style="color: var(--shiki-color-text)">) {</span></span>
<span><span style="color: var(--shiki-token-keyword)">throw</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Error</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Invalid webhook signature&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>