feat(gateway): VK payment callback signature verifier
Add the vkpay package: verify a VK Mini Apps payment ("голоса") callback
signature — MD5 (mandated by VK's payment protocol) of the sig-excluded
parameters, sorted by name and concatenated key=value, with the app secret
appended; case-insensitive over the hex digest. Unit-tested (valid / tampered /
wrong-secret / missing). First piece of the VK rail; the two-phase callback
handler, the VK order branch and the client bridge follow.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
// Package vkpay verifies VK Mini Apps payment ("голоса") callback signatures. VK signs each
|
||||
// payment notification (get_item / order_status_change) and expects the receiving server to verify
|
||||
// it with the app's secret before acting. The signature is MD5 — mandated by VK's payment protocol,
|
||||
// not a security choice on our part — so this package uses crypto/md5 deliberately.
|
||||
package vkpay
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Verify reports whether params carry a valid VK payment signature under secret. VK computes the
|
||||
// signature as the MD5 of the sig-excluded parameters, sorted alphabetically by name and
|
||||
// concatenated as key=value with no separators, with the app secret appended. The comparison is
|
||||
// case-insensitive over the hex digest.
|
||||
func Verify(params map[string]string, secret string) bool {
|
||||
got := params["sig"]
|
||||
if got == "" || secret == "" {
|
||||
return false
|
||||
}
|
||||
keys := make([]string, 0, len(params))
|
||||
for k := range params {
|
||||
if k == "sig" {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
var b strings.Builder
|
||||
for _, k := range keys {
|
||||
b.WriteString(k)
|
||||
b.WriteString("=")
|
||||
b.WriteString(params[k])
|
||||
}
|
||||
b.WriteString(secret)
|
||||
sum := md5.Sum([]byte(b.String()))
|
||||
return strings.EqualFold(hex.EncodeToString(sum[:]), got)
|
||||
}
|
||||
Reference in New Issue
Block a user