UNPKG

daraja

Version:

A NodeJS library to simplify integration with Safaricom's Daraja M-Pesa API

312 lines (311 loc) 6.86 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const constants = require('constants'); const crypto = require('crypto'); const fs = require('fs'); const path = require('path'); const moment = require('moment'); const api = require('./api'); exports.generateToken = async ( environment, consumerKey, consumerSecret, accessToken, expiryDate ) => { try { if (moment().isBefore(expiryDate)) { return { accessToken, expiryDate }; } const { access_token, expires_in } = await api.generateToken( environment, consumerKey, consumerSecret ); return { accessToken: access_token, expiryDate: moment().add(expires_in, 'seconds') }; } catch (error) { throw error; } }; exports.mpesaExpressRequest = async ( environment, accessToken, shortcode, passkey, transactionType, amount, sender, recipient, callbackUrl, accountReference, transactionDescription ) => { const timestamp = moment().format('YYYYMMDDHHmmss'); try { const { MerchantRequestID: merchantRequestId, CheckoutRequestID: checkoutRequestId } = await api.mpesaExpressRequest( environment, accessToken, shortcode, Buffer.from(`${shortcode}${passkey}${timestamp}`).toString('base64'), timestamp, transactionType, amount, sender, recipient, sender, callbackUrl, accountReference, transactionDescription ); return { merchantRequestId, checkoutRequestId }; } catch (error) { throw error; } }; exports.mpesaExpressQuery = async ( environment, accessToken, shortcode, passkey, checkoutRequestId ) => { const timestamp = moment().format('YYYYMMDDHHmmss'); try { const { ResultCode: resultCode, ResultDesc: resultDescription } = await api.mpesaExpressQuery( environment, accessToken, shortcode, Buffer.from(`${shortcode}${passkey}${timestamp}`).toString('base64'), timestamp, checkoutRequestId ); return { resultCode, resultDescription }; } catch (error) { throw error; } }; exports.c2bRegisterUrl = async ( environment, accessToken, shortcode, validationUrl, confirmationUrl, responseType ) => { try { const { ResponseDescription: responseDescription } = await api.c2bRegisterUrl( environment, accessToken, validationUrl, confirmationUrl, responseType, shortcode ); return { responseDescription }; } catch (error) { throw error; } }; exports.c2bSimulateTransaction = async ( environment, accessToken, shortcode, sender, amount, billReference ) => { if (environment !== 'sandbox') { throw new Error('Cannot simulate on production environment'); } try { const { ConversationID: conversationId, OriginatorCoversationID: originatorConversationId, ResponseDescription: responseDescription } = await api.c2bSimulateTransaction( accessToken, 'CustomerPayBillOnline', amount, sender, billReference, shortcode ); return { conversationId, originatorConversationId, responseDescription }; } catch (error) { throw error; } }; exports.b2cPaymentRequest = async ( environment, accessToken, shortcode, recipient, amount, commandId, initiatorName, initiatorPassword, remarks, occassion, timeoutUrl, resultUrl ) => { try { const { ConversationID: conversationId, OriginatorConversationID: originatorConversationId, ResponseDescription: responseDescription } = await api.b2cPaymentRequest( environment, accessToken, initiatorName, generateSecurityCredential(environment, initiatorPassword), commandId, amount, shortcode, recipient, remarks, timeoutUrl, resultUrl, occassion ); return { conversationId, originatorConversationId, responseDescription }; } catch (error) { throw error; } }; exports.accountBalanceRequest = async ( environment, accessToken, shortcode, identifierType, initiatorName, initiatorPassword, remarks, timeoutUrl, resultUrl ) => { try { const { ConversationID: conversationId, OriginatorConversationID: originatorConversationId, ResponseDescription: responseDescription } = await api.accountBalanceRequest( environment, accessToken, 'AccountBalance', shortcode, identifierType, remarks, initiatorName, generateSecurityCredential(environment, initiatorPassword), timeoutUrl, resultUrl ); return { conversationId, originatorConversationId, responseDescription }; } catch (error) { throw error; } }; exports.transactionStatusRequest = async ( environment, accessToken, shortcode, identifierType, initiatorName, initiatorPassword, transactionId, remarks, occassion, timeoutUrl, resultUrl ) => { try { const { ConversationID: conversationId, OriginatorConversationID: originatorConversationId, ResponseDescription: responseDescription } = await api.transactionStatusRequest( environment, accessToken, 'TransactionStatusQuery', shortcode, identifierType, remarks, initiatorName, generateSecurityCredential(environment, initiatorPassword), timeoutUrl, resultUrl, transactionId, occassion ); return { conversationId, originatorConversationId, responseDescription }; } catch (error) { throw error; } }; exports.reversalRequest = async ( environment, accessToken, shortcode, initiatorName, initiatorPassword, transactionId, remarks, occassion, timeoutUrl, resultUrl ) => { try { const { ConversationID: conversationId, OriginatorConversationID: originatorConversationId, ResponseDescription: responseDescription } = await api.reversalRequest( environment, accessToken, 'TransactionReversal', shortcode, 11, remarks, initiatorName, generateSecurityCredential(environment, initiatorPassword), timeoutUrl, resultUrl, transactionId, occassion ); return { conversationId, originatorConversationId, responseDescription }; } catch (error) { throw error; } }; const generateSecurityCredential = (environment, password) => crypto .publicEncrypt( { key: fs.readFileSync( path.join( __dirname, '..', '..', 'certificates', `${environment}.cer` ), 'utf8' ), padding: constants.RSA_PKCS1_PADDING }, Buffer.from(password) ) .toString('base64');