UNPKG

mpesajs

Version:

A Node.js SDK for seamless integration with M-Pesa payment gateway, providing easy-to-use methods for handling transactions, payments, and API interactions

163 lines 8.27 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RegisterUrl = void 0; const axios_1 = __importStar(require("axios")); const ErrorHandlers_1 = require("./errors/ErrorHandlers"); const RateLimiter_1 = require("./utils/RateLimiter"); const env_1 = require("./utils/env"); /** * Class to handle M-Pesa URL registration functionality * Allows businesses to register their confirmation and validation URLs */ class RegisterUrl { /** * Creates an instance of RegisterUrl * @param apiKey - M-Pesa API key for authentication * @param sandbox - Whether to use sandbox environment */ constructor(apiKey = (0, env_1.getEnvVar)('MPESA_CONSUMER_KEY', ''), sandbox = (0, env_1.getEnvVar)('MPESA_SANDBOX', 'true').toLowerCase() === 'true') { this.apiKey = apiKey; this.baseUrl = sandbox ? 'https://apisandbox.safaricom.et/v1/c2b-register-url/register' : 'https://api.safaricom.et/v1/c2b-register-url/register'; this.rateLimiter = RateLimiter_1.RateLimiter.getInstance(); } /** * Validates that both URLs use HTTPS protocol * @param confirmationUrl - URL for successful transaction notifications * @param validationUrl - URL for transaction validation * @throws Error if URLs don't use HTTPS */ validateUrls(confirmationUrl, validationUrl) { if (!confirmationUrl.startsWith('https://') || !validationUrl.startsWith('https://')) { throw new ErrorHandlers_1.MpesaError('Both confirmation and validation URLs must use HTTPS protocol'); } } /** * Builds the payload for URL registration request * @param shortCode - Business short code * @param responseType - Type of response expected * @param commandId - Command identifier * @param confirmationUrl - URL for confirmations * @param validationUrl - URL for validations * @returns Formatted payload object */ buildPayload(shortCode, responseType, commandId, confirmationUrl, validationUrl) { return { ShortCode: shortCode, ResponseType: responseType, CommandID: commandId, ConfirmationURL: confirmationUrl, ValidationURL: validationUrl }; } /** * Parses and validates the API response * @param response - Raw API response * @returns Formatted RegisterUrlResponse object * @throws Error if response format is invalid */ parseResponse(response) { var _a; if (!((_a = response.data) === null || _a === void 0 ? void 0 : _a.header)) { ErrorHandlers_1.RegisterUrlErrorHandler.handle(response.data); } const { responseCode, responseMessage, customerMessage, timestamp } = response.data.header; return { responseCode, responseMessage, customerMessage, timestamp }; } /** * Registers validation and confirmation URLs with M-Pesa * @param shortCode - Business short code or PayBill number * @param responseType - Type of response expected (default: 'Completed') * @param commandId - Command identifier (default: 'RegisterURL') * @param confirmationUrl - HTTPS URL to receive successful transaction confirmations * @param validationUrl - HTTPS URL to validate transactions before processing * @returns Promise containing registration response details * @throws RegisterUrlError if registration fails * @throws NetworkError if network connection fails * @throws ValidationError if URLs are invalid * @throws MpesaError for other API errors */ register() { return __awaiter(this, arguments, void 0, function* (shortCode = (0, env_1.getEnvVar)('MPESA_BUSINESS_SHORTCODE', ''), responseType = (0, env_1.getEnvVar)('MPESA_REGISTER_URL_RESPONSE_TYPE', 'Completed'), commandId = (0, env_1.getEnvVar)('MPESA_REGISTER_URL_COMMAND_ID', 'RegisterURL'), confirmationUrl = (0, env_1.getEnvVar)('MPESA_CONFIRMATION_URL', ''), validationUrl = (0, env_1.getEnvVar)('MPESA_VALIDATION_URL', '')) { return this.rateLimiter.execute(() => __awaiter(this, void 0, void 0, function* () { var _a; try { this.validateUrls(confirmationUrl, validationUrl); const payload = this.buildPayload(shortCode, responseType, commandId, confirmationUrl, validationUrl); const response = yield axios_1.default.post(this.baseUrl, payload, { params: { apikey: this.apiKey } }); return this.parseResponse(response); } catch (error) { if (error instanceof ErrorHandlers_1.ValidationError) { throw error; } if (error instanceof axios_1.AxiosError) { // Handle API response errors if ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) { return ErrorHandlers_1.RegisterUrlErrorHandler.handle(error.response.data); } // Handle network errors (no response received) if (error.request || error.code === 'ECONNABORTED') { throw new ErrorHandlers_1.NetworkError('No response received from the API. Please check your network connection.'); } // Handle request setup errors throw new ErrorHandlers_1.MpesaError(`Failed to register URLs: ${error.message}`); } // If it's already a RegisterUrlError, rethrow it if (error instanceof ErrorHandlers_1.RegisterUrlError) { throw error; } // For any other error, wrap it in MpesaError throw new ErrorHandlers_1.MpesaError(`Failed to register URLs: ${error instanceof Error ? error.message : 'Unknown error occurred'}`); } })); }); } } exports.RegisterUrl = RegisterUrl; //# sourceMappingURL=registerUrl.js.map