paytrail/api-documentation

The example HMAC calculation does not work !!

MiesSuomesta opened this issue · 2 comments

Following code does not provide same hash that exmaple should produce?

Code to test:

package main
import(
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"sort"
"fmt"
)

var PaytrailOfficialRequestSignature = "3708f6497ae7cc55a2e6009fc90aa10c3ad0ef125260ee91b19168750f6d74f6"

func headersToBytesSorted(headers map[string]string) (sortedHeaders []byte) {
var keys []string
for key := range headers {
fmt.Println("headersToBytesSorted/for :", key)
if len(key) >= 9 {
if key[:9] == "checkout-" {
fmt.Println("headersToBytesSorted/added :", key)
keys = append(keys, key)
}
}
}
sort.Strings(keys)
for _, key := range keys {
sortedHeaders = append(sortedHeaders, []byte(key+":"+headers[key]+"\n")...)
}
return sortedHeaders
}

func CalculateHmac(secret, body []byte, headers map[string]string) string {

payload := headersToBytesSorted(headers)
payload = append(payload, body...)
hash := hmac.New(sha256.New, secret)
hash.Write(payload)
return hex.EncodeToString(hash.Sum(nil))

}

var PaytrailOfficialRequestHeaders = map[string]string{
"checkout-account": "375917",
"checkout-algorithm": "sha256",
"checkout-method": "POST",
"checkout-nonce": "564635208570151",
"checkout-timestamp": "2018-07-06T10:01:31.904Z",
}

var PaytrailOfficialRequestBody = []byte({ "stamp": "unique-identifier-for-merchant", "reference": "3759170", "amount": 1525, "currency": "EUR", "language": "FI", "items": [ { "unitPrice": 1525, "units": 1, "vatPercentage": 24, "productCode": "#1234", "deliveryDate": "2018-09-01" } ], "customer": { "email": ["test.customer@example.com"](mailto:test.customer@example.com) }, "redirectUrls": { "success": ["https://ecom.example.com/cart/success"](https://ecom.example.com/cart/success), "cancel": ["https://ecom.example.com/cart/cancel"](https://ecom.example.com/cart/cancel) } })

func main() {
signatureStrOut := CalculateHmac([]byte("SAIPPUAKAUPPIAS"), PaytrailOfficialRequestBody, PaytrailOfficialRequestHeaders)
fmt.Println("Const :", PaytrailOfficialRequestSignature)
fmt.Println("Got :", signatureStrOut)
}

Output for me:

Const : 3708f6497ae7cc55a2e6009fc90aa10c3ad0ef125260ee91b19168750f6d74f6
Got : c7340510147ab5fe988fcf27f755b374f370aba2c612484f0fe3878936f961d6

The function would be bit better as:

func CalculateHmac(secret, body []byte, headers map[string]string) string {
	
	bufBody := new(bytes.Buffer)
        json.Compact(bufBody, body)

	payload := headersToBytesSorted(headers)
	payload = append(payload, bufBody.Bytes() ...)
	hash := hmac.New(sha256.New, secret)
	hash.Write(payload)
	return hex.EncodeToString(hash.Sum(nil))
}

.. Just for future refrence :D

I assume the problem was solved.