A middleware for validating incoming Shopify webhooks.
It can be used with any framework which speaks to http.http.ResponseWriter, http.Request, and http.HandlerFunc. Can be used with Go's net/http, echo, `gin, and others.
This package provides ability to grab the shop's domain, the request HMAC, and POST body of a webhook request. Then, it will reproduce the HMAC locally with the POST body and the app's secret key to see if the data matches. Essentially (in pseudo code): base64(hmac("secret", body)) == req_hmac.
For more information see Shopify's article.
package main
import (
  "fmt"
  "log"
  "net/http"
  hsw "github.com/gnikyt/http_shopify_webhook"
)
// Handler. Handle your webhook here.
func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Ok")
}
func main() {
  secret := "key" // Your secret key for the app.
  http.HandleFunc("/webhook/order-create", hsw.WebhookVerify(key, handler))
  log.Fatal(http.ListenAndServe(":8080", nil))
}package main
import (
  "net/http"
  "github.com/labstack/echo/v4"
  "github.com/labstack/echo/v4/middleware"
  hsw "github.com/gnikyt/http_shopify_webhook/wrapper/echo"
)
// Handler. Handle your webhook here.
func hello(c echo.Context) error {
  return c.String(http.StatusOK, "Ok")
}
func main() {
  secret := "key" // Your secret key for the app.
  e := echo.New()
  e.Use(middleware.Logger())
  e.Use(middleware.Recover())
  e.Use(hsw.WebhookVerify(secret))
  e.POST("/webhook/order-create", handler)
  e.Logger.Fatal(e.Start(":1323"))
}package main
import (
  "github.com/gin-gonic/gin"
  hsw "github.com/gnikyt/http_shopify_webhook/wrapper/gin"
)
func main() {
  secret := "key" // Your secret key for the app.
  r := gin.Default()
  r.Use(hsw.WebhookVerify(secret))
  r.POST("/webhook/order-create", func(c *gin.Context) {
    // Handle your webhook here.
    c.Data(http.StatusOK, "text/plain", "Ok")
  })
  r.Run()
}go test ./..., fully tested.
// go doc -all
package http_shopify_webhook // import "github.com/gnikyt/http_shopify_webhook"
FUNCTIONS
func WebhookVerify(key string, fn http.HandlerFunc) http.HandlerFunc
    Public webhook verify wrapper. Can be used with any framework tapping into
    net/http. Simply pass in the secret key for the Shopify app. Example:
    `WebhookVerify("abc123", anotherHandler)`.
func WebhookVerifyRequest(key string, w http.ResponseWriter, r *http.Request) bool
    Webhook verify request from HTTP. Returns a usable handler. Pass in the
    secret key for the Shopify app and the next handler.`
Also available through godoc.org.
This project is released under the MIT license.