package heleket import ( "crypto/md5" "encoding/base64" "encoding/hex" "encoding/json" "strings" ) // encodeBody matches PHP json_encode default (slashes escaped, unicode unescaped). func encodeBody(v any) ([]byte, error) { b, err := json.Marshal(v) if err != nil { return nil, err } return []byte(strings.ReplaceAll(string(b), "/", `\/`)), nil } func SignBody(body []byte, apiKey string) string { escaped := strings.ReplaceAll(string(body), "/", `\/`) sum := md5.Sum([]byte(base64.StdEncoding.EncodeToString([]byte(escaped)) + apiKey)) return hex.EncodeToString(sum[:]) } func VerifyWebhook(body []byte, apiKey string) (map[string]any, bool) { var raw map[string]json.RawMessage if err := json.Unmarshal(body, &raw); err != nil { return nil, false } signRaw, ok := raw["sign"] if !ok { return nil, false } var sign string if err := json.Unmarshal(signRaw, &sign); err != nil { return nil, false } delete(raw, "sign") payload, err := encodeBody(raw) if err != nil { return nil, false } if SignBody(payload, apiKey) != sign { return nil, false } var data map[string]any if err := json.Unmarshal(body, &data); err != nil { return nil, false } delete(data, "sign") return data, true }