Module: Jamm::Webhook

Defined in:
lib/jamm/webhook.rb

Class Method Summary collapse

Class Method Details

.parse(json) ⇒ Object

Parse command is for parsing the received webhook message. It does not call anything remotely, instead returns the suitable object.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/jamm/webhook.rb', line 13

def self.parse(json)
  out = Jamm::OpenAPI::MerchantWebhookMessage.new(json)

  case json[:event_type]
  when Jamm::OpenAPI::EventType::CHARGE_CREATED
    out.content = Jamm::OpenAPI::ChargeMessage.new(json[:content])
    return out

  when Jamm::OpenAPI::EventType::CHARGE_UPDATED
    out.content = Jamm::OpenAPI::ChargeMessage.new(json[:content])
    return out

  when Jamm::OpenAPI::EventType::CHARGE_CANCEL
    out.content = Jamm::OpenAPI::ChargeMessage.new(json[:content])
    return out

  when Jamm::OpenAPI::EventType::CHARGE_SUCCESS
    out.content = Jamm::OpenAPI::ChargeMessage.new(json[:content])
    return out

  when Jamm::OpenAPI::EventType::CHARGE_FAIL
    out.content = Jamm::OpenAPI::ChargeMessage.new(json[:content])
    return out

  when Jamm::OpenAPI::EventType::CONTRACT_ACTIVATED
    out.content = Jamm::OpenAPI::ContractMessage.new(json[:content])
    return out
  end

  raise 'Unknown event type'
end

.secure_compare(a, b) ⇒ Object

Securely compare two strings of equal length. This method is a port of ActiveSupport::SecurityUtils.secure_compare which works on non-Rails platforms.



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/jamm/webhook.rb', line 64

def self.secure_compare(a, b)
  return false unless a.bytesize == b.bytesize

  # Unpack strings into arrays of bytes
  a_bytes = a.unpack('C*')
  b_bytes = b.unpack('C*')
  result = 0

  # XOR each byte and accumulate the result
  a_bytes.zip(b_bytes) { |x, y| result |= x ^ y }
  result.zero?
end

.verify(data:, signature:) ⇒ Object

Verify message

Raises:

  • (ArgumentError)


46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/jamm/webhook.rb', line 46

def self.verify(data:, signature:)
  raise ArgumentError, 'data cannot be nil' if data.nil?
  raise ArgumentError, 'signature cannot be nil' if signature.nil?

  # Convert the JSON to a string
  json = JSON.dump(data)

  digest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), Jamm.client_secret, json)
  given = "sha256=#{digest}"

  return if secure_compare(given, signature)

  raise Jamm::InvalidSignatureError, 'Digests do not match'
end