Webhooks enable real-time updates from Maple to your application. Webhooks can be setup in the Maple web application by specifying a URL endpoint in your application to receive the relevant webhook payload when events you have subscribed to occur.

We currently use Convoy Service to send webhooks to your servers.

Setting up webhooks

Webhooks can be enabled and configured through the Maple web application under the Developers section. You can subscribe to specific events or all events.

  1. Go to the Webhooks sub-section under Developers.
  2. Click on New Webhook button
  3. Add a Target URL, Description and select the events you want to listen to. Then click Add Webhook
  4. Copy the secret.

Once you create the webhook, a secret will be provided that can be used to verify the events received. Make sure to copy the secret since you will not be able to retrieve it again.

Once you set up a webhook, you can continue to subscribe to a number of webhook event types to perform actions in your application. We continue to add more webhook event types, so feel free to reach out to us if you need a specific webhook event type.

Security

Maple will only send webhooks via a POST request to an HTTPS endpoint. Each request will also contain X-Maple-Signature header that represents the signature of the request. This signature can be verified to ensure that the webhook came from our servers, prevent replay attacks and ensure a zero downtime key rotation. See this blog post for more details.

A sample header may look something like this:

X-Maple-Signature:
t=1492774577,
v1=ansdoj213e98jqd928u3eudh239eu2j9d2jd8ejd238eu23ei2d9j23e8u23eue3,
v0=6ffbb59b2300aae63f272406069a9788598b792a944a07aba816edb039989a39

Receiving webhooks

Verifying webhook signature

We recommend using Convoy SDKs to verify the signature. They have support for a few common programming languages (Go, Ruby, Python, Javascript, PHP). The following code will verify the code and a 200status code as the response

func handleWebhook(w http.ResponseWriter, r *http.Request) {
	body, err := io.ReadAll(r.Body)
	webhooks := convoy.NewWebhook(
		&convoy.WebhookOpts{
			Secret:   os.Getenv("WEBHOOKS_SECRET"),
			Hash:     "SHA512",
			Encoding: convoy.Base64Encoding,
		},
	)

	err = webhooks.VerifyPayload(body, r.Header.Get("X-Maple-Signature"))
	if err != nil {
		log.Errorf("webhooks not verified err = %s", err)
		return
	}

	log.Debugf("received body: %s", body)
	// Do something with the body
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	w.WriteHeader(200)
}

Understanding webhook data

Your endpoint must be configured to read the webhook event object. Each event has a event_type, created_at, data_type and data.

{
  event_type: "customer.updated",
  data_type: "customer",
  created_at: 1681498548,
  data: {
      object: {
          id: "cus_2OQfabsJ8GIBwetfIRQLeCewrtBO",
          ...
      }
  }
}

Responding to webhooks

Your endpoint must return a successful status code (2XX) within 30s. Maple webhooks have a built-in retry mechanism for any non-2xx(3XX,4XX, and 5XX) status codes. They will be retried 10 times with an exponential backoff strategy.