paytrail / api-documentation

Paytrail Payment API documentation
MIT License
6 stars 11 forks source link

Unable to verify redirect url signature #41

Closed Jiia closed 2 years ago

Jiia commented 2 years ago

Describe the bug

After a succesfull payment, the client is sent to the redirectUrls.success along with query parameters containing payment details and the signature. Despite following the guide I'm unable to verify the signature with the public test account.

const PAYTRAIL_SIGNATURE_ALGORITHM = 'sha512'

export const verifyPaytrailSignature = ({
  signature,
  ...queryParams
}: ConfirmPaytrailParams & object): true => {
  const signaturePayload = Object.keys(queryParams)
    .filter(key => key.indexOf('checkout-') === 0)
    .sort()
    .map(key => [key, params[key]].join(':'))
    .join('\n')

  const secret = getMerchantSecretForMerchantId(queryParams['checkout-account'])
  const correctSignature = createHmac(PAYTRAIL_SIGNATURE_ALGORITHM, secret)
    .update(signaturePayload)
    .digest('hex')

  if (timingSafeEqual(Buffer.from(correctSignature), Buffer.from(signature))) {
    return true
  }

  console.log(queryParams)
  console.log(signaturePayload)
  console.log(secret)
  console.log(signature)
  console.log(correctSignature)

  throw new ResponseError(401, 'Invalid signature')
}

queryParams:

{
  'checkout-account': '375917',
  'checkout-algorithm': 'sha512',
  'checkout-amount': '49573',
  'checkout-stamp': '90623',
  'checkout-reference': '90623XR1719177',
  'checkout-status': 'ok',
  'checkout-provider': 'nordea',
  'checkout-transaction-id': '8d2673d0-fd1c-11ec-8bc5-b7bc95ff46f2'
}

signaturePayload:

checkout-account:375917
checkout-algorithm:sha512
checkout-amount:49573
checkout-provider:nordea
checkout-reference:90623XR1719177
checkout-stamp:90623
checkout-status:ok
checkout-transaction-id:8d2673d0-fd1c-11ec-8bc5-b7bc95ff46f2

secret:

SAIPPUAKAUPPIAS

signature:

ff20a8dcee2b912a29f5645eea95f95d2cbf0f9706fa0231ee7d0ed8dff9ebfa1e845ec493e8adc2d962e9a1ffaade9643aa4c0185b437e02f707685a334dd66

correctSignature:

18a3382e291ff89c34d6ae132c2718a8463b205b2da96c91e4fdc03d73c808ff343821d28142dbccb2ae5dd5ed51f6c3e209552cc1180038f20d1b236f7490cd
Jiia commented 2 years ago

Turns out I was missing a trailing \n in the signature payload, since I wasn't adding an empty string (the body) as the last element of the array.

jfrojd-paytrail commented 2 years ago

Great to hear that you found a solution!