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
44
45
46
47
# 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::REFUND_SUCCEEDED
    out.content = Jamm::OpenAPI::ChargeMessage.new(json[:content])
    return out

  when Jamm::OpenAPI::EventType::REFUND_FAILED
    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.



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/jamm/webhook.rb', line 69

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. This method will use client secret to verify the message.

Raises:

  • (ArgumentError)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/jamm/webhook.rb', line 51

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