UNPKG

transact-payments

Version:

Node module to do payments using transact.io

295 lines (251 loc) 6.65 kB
const jwt = require('jsonwebtoken'); import { TransactIoError } from './TransactIoError'; import { TransactIoErrorCode } from './TransactIoErrorCode'; import { ITransactJWT } from './TransactToken'; /** * @description Transact.io message handler * * @class TransactIoMsg */ export class TransactIoMsg { /** * * * @param {string} token * @param {any} callback * @returns * @memberof TransactIoMsg */ public static verify(token: string, secret: string, callback?: (err, decoded: ITransactJWT) => void): Promise<object> { return new Promise((resolve, reject) => { const jwtOptions = { algorithm: 'HS256', }; if (!secret || secret.length < 1) { const transactIoError = new TransactIoError('Invalid secret', TransactIoErrorCode.INVALID_SECRET, null); if (callback) { callback(transactIoError, null); } else { reject(transactIoError); } return; } const jwtToken = jwt.verify(token, secret, jwtOptions, callback ? callback : undefined); resolve(jwtToken); }); } public static isFromTransactServer(token: ITransactJWT) { if (token.tid) { return true; } return false; } private token: ITransactJWT; private secret: string; constructor() { this.token = new ITransactJWT(); this.setMethodClose(); this.setClassProduction(); } public setMethodPost() { this.token.method = 'POST'; } public setMethodClose() { this.token.method = 'CLOSE'; } public setMethodGet() { this.token.method = 'GET'; } public setClassProduction() { this.token.tclass = 'PROD'; } public setClassTest() { this.token.tclass = 'DEV'; } /** * * * @param {string} secret Your secret key to sign the message * @memberof TransactIoMsg */ public setSecret(secret: string) { this.secret = secret; } /** * * * @param {string} url address of purchased item * @memberof TransactIoMsg */ public setURL(url: string) { this.token.url = url; } /** * * * @param {string} url address of purchased item * @memberof TransactIoMsg */ public isSubscription(isSubscription: boolean) { this.token.sub = isSubscription; } /** * * * @param {string} title name of what they are buying. * @memberof TransactIoMsg */ public setTitle(title: string) { this.token.title = title; } /** * * * @param {number} price in cents * @memberof TransactIoMsg */ public setPrice(price: number) { this.token.price = price; } /** * * * @param {string} item code to idntify the item they are buying * @memberof TransactIoMsg */ public setItem(item: string) { this.token.item = item; } /** * * * @param {string} item code to idntify the item they are buying * @memberof TransactIoMsg */ public setThumnailImageUrl(url: string) { this.token.img = url; } /** * * * @param {string} uid Unique transaction ID to track on your site. * @memberof TransactIoMsg */ public setUid(uid: string) { this.token.uid = uid; } /** * * * @param {number} recipient user ID on transact * @memberof TransactIoMsg */ public setRecipient(recipient: number) { this.token.rid = recipient; } /** * @description (Optional) Force the ID of the buyer. * If you don't specify it will be whoever logs in on transact.io * If you DO specify, payment will only be accepted from this buyer ID * * @param {number} buyerID User ID on transact, who is buying * @memberof TransactIoMsg */ public setBuyer(buyerID: number) { this.token.bid = buyerID; } /** * * * @param {[key: string]: number | string} meta * @memberof TransactIoMsg */ public setMeta(meta: {[key: string]: number | string}) { this.token.meta = meta; } public setMetaKeyValue(key: string, value: number | string) { if (!this.token.meta) { this.token.meta = {}; } this.token.meta.key = value; } /** * @description Check for presense of fields that transact server * sets. NOTE you still must call verify() * * @param {number} buyerID User ID on transact, who is buying * @memberof TransactIoMsg */ public isFromTransactServer(decoded: ITransactJWT) { if (this.token.tid) { return true; } return false; } /** * * * @param {(err, t: string) => void} [callback] * @returns * @memberof TransactIoMsg */ public getToken(callback?: (err: Error, signature: string) => void): Promise<string> { return new Promise((resolve, reject) => { const jwtOptions = { algorithm: 'HS256', }; let transactIoError = null; if (!this.secret || this.secret.length < 1) { transactIoError = new TransactIoError('Invalid secret', TransactIoErrorCode.INVALID_SECRET, null); } if (this.token.price === null || this.token.price < 0 || this.token.price === undefined || isNaN(this.token.price)) { transactIoError = new TransactIoError('Invalid Price', TransactIoErrorCode.PRICE_TOO_LOW, null); } if (!this.token.rid || isNaN(this.token.rid)) { transactIoError = new TransactIoError('Invalid recipient ID', TransactIoErrorCode.INVALID_RECIPIENT, null); } if (!this.token.title || this.token.title.length < 1) { transactIoError = new TransactIoError('Invalid title', TransactIoErrorCode.INVALID_RECIPIENT, null); } if (transactIoError != null) { if (callback) { callback(transactIoError, null); } else { reject(transactIoError); } return; } this.token.iat = Date.now(); const token = Object.assign({}, this.token); jwt.sign(token, this.secret, jwtOptions, (err: any, signature: string) => { if (err || !signature) { transactIoError = new TransactIoError('Signing error', TransactIoErrorCode.SIGNING_ERROR, err); if (callback) { callback(transactIoError, null); } else { reject(transactIoError); } return; } if (signature.length > 1000) { transactIoError = new TransactIoError( 'Signing error: too big, reduce meta-data. sig:' + signature, TransactIoErrorCode.SIGNATURE_TOO_BIG, null); if (callback) { callback(transactIoError, null); } else { reject(transactIoError); } return; } if (callback) { callback(null, signature); } else { resolve(signature); } }); }); } }