OrahKokos / coinpayments-ipn

Module for verifing Coinpaymets Instant Payment notifications.
MIT License
7 stars 4 forks source link

Is there a TypeScript version for this Package #9

Closed anasbenyaiche closed 3 years ago

anasbenyaiche commented 3 years ago

Here is my problem, what I went to ask is about is a TypeScript version for this Package, in fact, I'll explain more: I made the config ipn_url and I am testing with Ngrok:

app.post(
  `/notify`,
  (req, res, next) => {
    console.log('------------------------------ipn--------------------------------------');
    console.log('body', req.body);
    console.log('------------------------------ipn--------------------------------------');
    if (
      !req.get(`HMAC`) ||
      !req.body.ipn_mode ||
      req.body.ipn_mode !== `hmac` ||
      MERCHANT_ID !== req.body.merchant
    ) {
      return next(new Error(`Invalid request`));
    }

    let isValid;
    let error;

    try {
      isValid = verify(req.get(`HMAC`), IPN_SECRET, req.body);
    } catch (e) {
      error = e;
    }

    if (error && error) {
      return next(error);
    }

    if (!isValid) {
      return next(new Error(`Hmac calculation does not match`));
    }

    return next();
  },

and here is what I got an empty body

------------------------------ipn--------------------------------------
 body {}
------------------------------ipn--------------------------------------
Hmac calculation does not match

my point are :

OrahKokos commented 3 years ago

https://github.com/OrahKokos/coinpayments-ipn/issues/8#issuecomment-858495725

Yes it is out of date. Will be doing this soon enough, would really like to re-visit the entire flow and note all possible exceptions.

anasbenyaiche commented 3 years ago

Thank you for your responsive answer @OrahKokos

anasbenyaiche commented 3 years ago

I hope I can help with TypeScript Developers I got this and it works perfectly

import crypto from 'crypto';

import qs from 'querystring';

interface Dictionary<T> {
  [index: string]: T;
}
export const coinPaymentVerify = (
  hmac = ``,
  ipnSecret = ``,
  payload: Dictionary<
    | string
    | number
    | boolean
    | readonly string[]
    | readonly number[]
    | readonly boolean[]
    | null
  >,
) => {
  if (!hmac || typeof hmac !== `string`) throw new Error('hmac');
  if (!ipnSecret || typeof ipnSecret !== `string`) throw new Error('ipnSecret');
  if (typeof payload !== `object`) throw new Error('payload');

  const paramString = qs.stringify(payload).replace(/%20/g, '+');

  const calcHmac = crypto.createHmac('sha512', ipnSecret).update(paramString).digest('hex');

  if (hmac !== calcHmac) return false;

  return true;
};