npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mpesa-mz-sdk

v1.2.1

Published

SDK para integração com a API M-Pesa de Moçambique

Readme

M-Pesa SDK para Moçambique

Um SDK robusto e completo para integração com a API M-Pesa da Vodacom em Moçambique, desenvolvido em TypeScript/JavaScript. Suporta todas as operações principais: C2B, B2C, B2B, Query e Reversal.

🚀 Características

  • Autenticação Segura: Criptografia RSA do apiKey com a publicKey
  • Seleção de Ambiente: Suporte automático para sandbox e produção
  • Tratamento de Erros Robusto: Classe MpesaError personalizada
  • Logging Detalhado: Para depuração e monitoramento
  • TypeScript: Tipagem completa para melhor experiência de desenvolvimento
  • Testes Unitários: Cobertura completa com Jest
  • API Simplificada: Métodos curtos e intuitivos
  • Respostas Legíveis: Formato de resposta limpo e organizado

📦 Instalação

npm install mpesa-mz-sdk

⚙️ Configuração

Variáveis de Ambiente

Crie um arquivo .env na raiz do seu projeto:

# Credenciais M-Pesa
MPESA_API_KEY=sua_api_key_aqui
MPESA_PUBLIC_KEY=sua_public_key_aqui
MPESA_SERVICE_PROVIDER_CODE=seu_service_provider_code
MPESA_ORIGIN=seu_origin_aqui

# Ambiente (sandbox ou live)
MPESA_ENV=sandbox

Configuração do SDK

import { MpesaService } from 'mpesa-sdk-mozambique';

const mpesa = new MpesaService({
  apiKey: process.env.MPESA_API_KEY!,
  publicKey: process.env.MPESA_PUBLIC_KEY!,
  serviceProviderCode: process.env.MPESA_SERVICE_PROVIDER_CODE!,
  origin: process.env.MPESA_ORIGIN!,
  env: process.env.MPESA_ENV as 'sandbox' | 'live', // Define automaticamente o host
  timeout: 60000 // Timeout opcional em ms
});

📚 Uso

Formato de Resposta

Todos os métodos retornam um objeto padronizado com a seguinte estrutura:

{
  status: 'success' | 'error',
  message: string,
  data?: T, // Dados específicos da operação
  code?: string, // Código de resposta da M-Pesa
  httpStatus?: number,
  transactionId?: string,
  conversationId?: string,
  thirdPartyReference?: string,
  timestamp?: string
}

C2B (Customer to Business)

try {
  const response = await mpesa.c2b({
    amount: 100.00,
    number: '25884xxxxxxx', // MSISDN (número) do cliente
    transactionReference: 'TXN123',
    thirdPartyReference: 'REF456'
  });
  
  if (response.status === 'success') {
    console.log('Transação realizada com sucesso!');
    console.log('Transaction ID:', response.data?.transactionId);
    console.log('Amount:', response.data?.amount);
    console.log('Customer:', response.data?.customerMsisdn);
  } else {
    console.error('Erro na transação:', response.message);
  }
} catch (error) {
  console.error('C2B Error:', error.message);
}

B2C (Business to Customer)

try {
  const response = await mpesa.b2c({
    amount: 50.00,
    number: '25884xxxxxxx', // MSISDN (número) do destinatário
    transactionReference: 'TXN789',
    thirdPartyReference: 'REF101',
    paymentServices: 'BusinessPayBill' // Opcional, padrão: BusinessPayBill
  });
  
  if (response.status === 'success') {
    console.log('Pagamento enviado com sucesso!');
    console.log('Transaction ID:', response.data?.transactionId);
    console.log('Recipient:', `${response.data?.recipientFirstName || ''} ${response.data?.recipientLastName || ''}`.trim());
    console.log('Settlement Amount:', response.data?.settlementAmount);
  }
} catch (error) {
  console.error('B2C Error:', error.message);
}

B2B (Business to Business)

try {
  const response = await mpesa.b2b({
    amount: 1000.00,
    primaryPartyCode: 'COMPANY001', // Código da empresa que envia
    recipientPartyCode: 'COMPANY002', // Código da empresa que recebe
    transactionReference: 'TXN202',
    thirdPartyReference: 'REF303',
    paymentServices: 'BusinessToBusinessTransfer' // Opcional, padrão: BusinessToBusinessTransfer
  });
  
  if (response.status === 'success') {
    console.log('Transferência B2B realizada!');
    console.log('From:', response.data?.primaryPartyCode);
    console.log('To:', response.data?.recipientPartyCode);
    console.log('Amount:', response.data?.amount);
    console.log('Settlement:', response.data?.settlementAmount);
  }
} catch (error) {
  console.error('B2B Error:', error.message);
}

Query (Consulta de Status)

try {
  const response = await mpesa.query({
    queryReference: 'TXN123', // Transaction ID ou Conversation ID
    thirdPartyReference: 'REF456'
  });
  
  if (response.status === 'success') {
    console.log('Status da transação consultado!');
    console.log('Transaction Status:', response.data?.transactionStatus);
    console.log('Payment Status:', response.data?.paymentStatusDesc);
    console.log('Payment Code:', response.data?.paymentStatusCode);
  }
} catch (error) {
  console.error('Query Error:', error.message);
}

Reversal (Reversão)

try {
  const response = await mpesa.reversal({
    originalTransactionId: 'MPA_TRANS_ID_FROM_PREVIOUS_SUCCESSFUL_C2B',
    reversalAmount: 50.00,
    thirdPartyReference: 'REF789'
  });
  
  if (response.status === 'success') {
    console.log('Reversão realizada com sucesso!');
    console.log('Original Transaction:', response.data?.originalTransactionId);
    console.log('Reversal Amount:', response.data?.reversalAmount);
    console.log('New Transaction ID:', response.data?.transactionId);
  }
} catch (error) {
  console.error('Reversal Error:', error.message);
}

🔐 Autenticação

O SDK utiliza criptografia RSA para gerar o token Bearer:

  1. Criptografia: O apiKey é criptografado usando a publicKey com RSA PKCS1_PADDING
  2. Formatação: A publicKey é automaticamente formatada no padrão PEM
  3. Token: O resultado criptografado é usado como Bearer token
// O SDK faz isso automaticamente:
// 1. Formata a publicKey para PEM
// 2. Criptografa o apiKey com a publicKey
// 3. Usa o resultado como Bearer token

🌍 Ambientes

Sandbox

  • Host: api.sandbox.vm.co.mz:18352
  • Uso: Para testes e desenvolvimento
  • Configuração: env: 'sandbox'

Produção

  • Host: api.vm.co.mz:18352
  • Uso: Para operações reais
  • Configuração: env: 'live'

🛡️ Tratamento de Erros

O SDK inclui tratamento robusto de erros com mensagens descritivas baseadas na documentação oficial da M-Pesa API. Todos os códigos de erro oficiais estão mapeados para mensagens claras e compreensíveis.

Classe MpesaError

class MpesaError extends Error {
  constructor(
    message: string,
    public code: string,
    public statusCode: number,
    public details?: any
  ) {
    super(message);
    this.name = 'MpesaError';
  }
}

Códigos de Erro Suportados

O SDK inclui todos os códigos de erro oficiais da documentação da M-Pesa API:

  • INS-0: Request processed successfully
  • INS-1: Internal Error
  • INS-2: Invalid API Key
  • INS-4: User is not active
  • INS-5: Transaction cancelled by customer
  • INS-6: Transaction Failed
  • INS-9: Request timeout
  • INS-10: Duplicate Transaction
  • INS-13: Invalid Shortcode Used
  • INS-14: Invalid Reference Used
  • INS-15: Invalid Amount Used
  • INS-16: Unable to handle the request due to a temporary overloading
  • INS-17: Invalid Transaction Reference. Length Should Be Between 1 and 20.
  • INS-18: Invalid TransactionID Used
  • INS-19: Invalid ThirdPartyReference Used
  • INS-20: Not All Parameters Provided. Please try again.
  • INS-21: Parameter validations failed. Please try again.
  • INS-22: Invalid Operation Type
  • INS-23: Unknown Status. Contact M-Pesa Support
  • INS-24: Invalid InitiatorIdentifier Used
  • INS-25: Invalid SecurityCredential Used
  • INS-26: Not authorized
  • INS-993: Direct Debit Missing
  • INS-994: Direct Debit Already Exists
  • INS-995: Customer's Profile Has Problems
  • INS-996: Customer Account Status Not Active
  • INS-997: Linking Transaction Not Found
  • INS-998: Invalid Market
  • INS-2001: Initiator authentication error.
  • INS-2002: Receiver invalid.
  • INS-2006: Insufficient balance
  • INS-2051: Invalid number
  • INS-2057: Language code invalid.

Exemplos de Tratamento de Erros

🧪 Testes

Execute os testes unitários:

npm test

Cobertura de Testes

  • ✅ C2B (Customer to Business)
  • ✅ B2C (Business to Customer)
  • ✅ B2B (Business to Business)
  • ✅ Query (Consulta de Status)
  • ✅ Reversal (Reversão)
  • ✅ Tratamento de Erros
  • ✅ Autenticação
  • ✅ Formato de Resposta Simplificado

🔧 Configuração Avançada

Timeout Personalizado

const mpesa = new MpesaService({
  // ... outras configurações
  timeout: 120000 // 2 minutos
});

Host Personalizado

const mpesa = new MpesaService({
  // ... outras configurações
  apiHost: 'api.custom.vm.co.mz:18352' // Host personalizado
});

🚨 Troubleshooting

Erro INS-1 (Falha de Autenticação)

  1. Verifique as credenciais:

    echo $MPESA_API_KEY
    echo $MPESA_PUBLIC_KEY
  2. Confirme o ambiente:

    echo $MPESA_ENV
  3. Teste a criptografia:

    import { generateBearerToken, formatPublicKey } from 'mpesa-sdk-mozambique';
       
    const token = generateBearerToken(apiKey, formatPublicKey(publicKey));
    console.log('Generated Token:', token);

Erro de Timeout

  1. Aumente o timeout:

    const mpesa = new MpesaService({
      // ... outras configurações
      timeout: 120000 // 2 minutos
    });
  2. Verifique a conectividade:

    ping api.sandbox.vm.co.mz

Erro de Formato da Public Key

O SDK formata automaticamente a public key, mas se houver problemas:

import { formatPublicKey } from 'mpesa-sdk-mozambique';

const formattedKey = formatPublicKey(publicKey);
console.log('Formatted Key:', formattedKey);

📄 Licença

MIT License - veja o arquivo LICENSE para detalhes.

🤝 Contribuição

Contribuições são bem-vindas! Por favor:

  1. Fork o projeto
  2. Crie uma branch para sua feature (git checkout -b feature/AmazingFeature)
  3. Commit suas mudanças (git commit -m 'Add some AmazingFeature')
  4. Push para a branch (git push origin feature/AmazingFeature)
  5. Abra um Pull Request

📞 Suporte

Para suporte e dúvidas:


Desenvolvido com ❤️ para a comunidade M-Pesa em Moçambique