Webhooks

Use webhooks to integrate MonetizeNow with with your platform or other external service.

Configuring Events

  • Go to Settings > Webhooks > and click New
  • Provide an HTTP endpoint that accepts POST events where messages will be sent
  • Click "Select Events" and choose the events that you would like to subscribe to

Webhook Events

The following webhook events are supported and will be sent using a POST request to the endpoint you configure.

EntityEventOccurs When
Accountaccount.createdan account is created
account.updatedan account is updated
Contactcontact.createda contact is created
contact.updateda contact is updated
Quotequote.createda quote is created
quote.updateda quote is updated
quote.accepteda quote is accepted
quote.processeda quote is processed
quote.cancelleda quote is cancelled
quote.offering.createdan offering is added to a quote
quote.offering.updatedan offering on a quote is updated
quote.offering.deletedan offering is deleted from a quote
Opportunityopportunity.createdan opportunity is created
opportunity.updatedan opportunity is updated
Offeringoffering.createdan offering is created
offering.updatedan offering is updated
Contractcontract.createda contract is created
contract.updateda contract is updated
Raterate.createda rate is created
rate.updateda rate is updated
rate.deleteda rate is deleted
price.deleteda rate's price is deleted
Bill Groupdunning.step.tiggereda dunning step is triggered
Invoiceinvoice.createdan invoice is created
invoice.paidan invoice is paid
Subscriptionsubscription.createda subscription is created
subscription.created.summarya subscription is created, with a smaller payload
subscription.updateda subscription is updated
subscription.updated.summarya subscription is updated, with a smaller payload
subscription.status.changeda subscription status is changed

Request Payload

Events follow the structure listed below. You are expected to respond with a 200 response code to acknowledge that the event was successfully received.

Review the full list of Payload Examples

{
    "eventId": "whevt_YqhTdhCn55LXqkMsZ8Hb3fdv",
    "userId": "usr_qDf2afaOyHShW2oGZ",
    "sentTime": "2023-01-01T00:00:00.956607265Z",
    "eventType": "subscription.updated",
    "data": { ... }
}

Request Headers

Each webhook event will have the following headers included in the request

NameDescriptionExample
x-monetizenow-signatureSignature generated with webhooks secret and event payloadPDDVvixLI7g/Vs89Rkzv7hSfOHhW+tk0YvTPD03e66E="
x-tenant-idTenant ID of MonetizeNow tenant where the event originated.tennt_tydX1aEVHymLYoDs
x-user-idUser ID of the MonetizeNow user triggering the webhook event.usr_qDfP1rOyHShW2oGZ

Signature Verification

MonetizeNow signs the webhook events it sends to your registered endpoints by including a header X-MonetizeNow-Signature with each request. This allows you to verify that the request to your endpoint came from MonetizeNow and not a third-party. To verify the signature:

  1. Extract the signature from the header X-MonetizeNow-Signature.
  2. Extract the UTF-8 text payload as bytes.
  3. Compute a HMAC with the SHA256 hash function, using your webhook entry's secret as the key and the request payload bytes as the message.
  4. Base64-encode the HMAC digest and compare this value to the signature header to check for equivalence.

Verifying the request will vary depending on your programming language.

const sig = Buffer.from(req.get('x-monetizenow-signature'), 'base64');
const hmac = crypto.createHmac('sha256', secret);
const digest = Buffer.from(hmac.update(req.rawBody).digest('base64'), 'base64');
const verified = crypto.timingSafeEqual(digest, sig);
bytes = request.get_data();
sentHash = request.headers.get('x-monetizenow-signature');
computedHash = hmac.new(secret, msg=bytes, digestmod=hashlib.sha256)
verified = sentHash == base64.b64encode(computedHash.digest())
fun base64Encode(bytes: ByteArray) = Base64.getEncoder().encodeToString(bytes)

fun hmac256(
  key: String,
  data: String,
): ByteArray {
  val digest = "HmacSHA256"
  val mac = Mac.getInstance(digest)
  mac.init(
    SecretKeySpec(
      key.toByteArray(Charsets.UTF_8),
      digest
    )
  )
  return mac.doFinal(data.toByteArray(Charsets.UTF_8))
}

fun isSignatureValid(
  requestSignature: String,
  webhookSecret: String,
  stringifiedPayload: String,
): Boolean {
	val generatedSignature = base64Encode(
    bytes = hmac256(
      key = webhookSecret,
      data = stringifiedPayload,
    ),
  )
  return generatedSignature == requestSignature
}

Delivery attempts and retries

In the event that MonetizeNow receives a non-2xx response status from an endpoint, the delivery will be tried up to 3 times, with a minimum backoff of 5 seconds in between attempts.