Module: NOWPayments::Webhook

Defined in:
lib/nowpayments/webhook.rb

Overview

Webhook verification utilities for IPN (Instant Payment Notifications)

Class Method Summary collapse

Class Method Details

.verify!(raw_body, signature, secret) ⇒ Hash

Verify IPN signature

Parameters:

  • raw_body (String)

    Raw POST body from webhook

  • signature (String)

    x-nowpayments-sig header value

  • secret (String)

    IPN secret key from dashboard

Returns:

  • (Hash)

    Verified, parsed payload

Raises:



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/nowpayments/webhook.rb', line 16

def verify!(raw_body, signature, secret)
  raise ArgumentError, "raw_body required" if raw_body.nil? || raw_body.empty?
  raise ArgumentError, "signature required" if signature.nil? || signature.empty?
  raise ArgumentError, "secret required" if secret.nil? || secret.empty?

  # Compute HMAC directly on raw body - NOWPayments already sends keys in sorted order.
  # DO NOT parse and re-serialize! Ruby's JSON.generate may change number formatting
  # (e.g., scientific notation "1e-7" becomes "0.0000001"), breaking the signature.
  expected_sig = OpenSSL::HMAC.hexdigest("SHA512", secret, raw_body)

  raise SecurityError, "Invalid IPN signature - webhook verification failed" unless secure_compare(expected_sig, signature)

  # Only parse after verification succeeds
  JSON.parse(raw_body)
end