IMaliWay Gateway API

A API IMaliWay é organizada em torno de REST. Aceita corpos de pedido em JSON, devolve respostas em JSON e utiliza códigos de resposta HTTP padrão. Integre pagamentos M-Pesa, e-Mola, mKesh e iMali na sua aplicação em minutos.

Métodos de Pagamento Disponíveis

M-Pesa
e-Mola
mKesh
iMali

Fluxos de Pagamento

01
Push Payment
Cria uma transação e envia notificação push ao cliente para confirmar.
02
Pay-By-Link
Gera link e envia SMS. Cliente escolhe método ao clicar.
03
QR Code
Gera QR Code dinâmico para pagamento com conta iMali.

Autenticação

A IMaliWay utiliza encriptação RSA-ES-PKCS1 para gerar uma chave privada a partir do api_key e publicKey fornecidos pela Paytek. Este token deve ser enviado em cada pedido.

1
Receber credenciais da Paytek
Após registo como parceiro, a Paytek fornece api_key e publicKey para o ambiente Sandbox.
2
Gerar a privateKey
Encripte o api_key com RSA-ES-PKCS1 usando a publicKey para obter a privateKey.
3
Incluir em cada pedido
Envie Authorization: Bearer {privateKey} e X-Client-ID em todos os headers.
Nunca exponha a privateKey em código do lado do cliente. Gere-a sempre no servidor.

Headers obrigatórios em todos os pedidos

HeaderValor
AuthorizationBearer <privateKey>
X-Client-ID<your_client_id>
Content-Typeapplication/json
Acceptapplication/json

Códigos de Resposta

A API usa códigos no estilo HTTP para indicar sucesso ou falha.

Sucesso
200Success
201Success — Created
Erros
400partner_transaction_id com menos de 12 caracteres
401Pagamento não aceite / transação expirada
402Valor inválido (negativo ou zero)
404Cliente/loja/conta inválida
405Método não permitido
406partner_transaction_id já em uso
407Saldo insuficiente
408Conta/loja bloqueada
409Valor não disponível
422Pedido mal formatado
500Token inválido
501Limite KYC do cliente atingido
502Limite KYC da loja atingido

Push Payment

POST /payments

Cria uma transação de pagamento Push (C2B) para qualquer método disponível no gateway: M-Pesa, e-Mola, mKesh ou conta digital iMali. O cliente recebe uma notificação push no seu telemóvel para confirmar o pagamento.

Parâmetros

ParâmetroTipoEstadoDescrição
client_account_numberstringobrigatórioNúmero de telefone da carteira (M-Pesa: 84xxxxxxx) ou conta iMali (9 dígitos)
amountdecimalobrigatórioValor a pagar. Mínimo 10 MT. Ex: 1000.00
store_account_numberstringobrigatórioNúmero da conta iMali da loja (conta STORE, 9 dígitos)
partner_transaction_idstringobrigatórioID único da transação gerado pelo parceiro. Exatamente 12 caracteres alfanuméricos. Ex: MPS25KLHLIKA
payment_methodenum
mpesa | emola | mkesh | imali
obrigatórioMétodo de pagamento em minúsculas
payment_typeenum
push
fixoFixo: "push"
transaction_typeenum
C2B
fixoFixo: "C2B"
expiration_datetimestringopcionalData/hora de expiração. Formato: Y-m-d H:i:s. Padrão: 2 minutos
curl -X POST 'https://paytek-africa.net:11901/api/partners/imaliway/v2/payments' \
                        -H 'Authorization: Bearer {privateKey}' \
                        -H 'X-Client-ID: {client_id}' \
                        -H 'Content-Type: application/json' \
                        -H 'Accept: application/json' \
                        --data '{"client_account_number":"842592349","amount":"1000.00","store_account_number":"290000001","partner_transaction_id":"MPS25KLHLIKA","payment_method":"mpesa","payment_type":"push","transaction_type":"C2B"}'
Resposta (200 OK)
{
                                "data": {
                                "transaction_id": "MPS25KLHLIKA",
                                "partner_transaction_id": "MPS25KLHLIKA",
                                "amount": "1000.00",
                                "expiration_datetime": "2026-05-06 14:32:00",
                                "status": "PENDING"
                                }
                            }

QR Code

POST /payments

Gera um QR Code dinâmico para pagamento com conta iMali. DYNAMIC_TERMINAL: valor variável, validade de 2 minutos (sem título/descrição). DYNAMIC_TICKET: valor fixo, expiração e título/descrição obrigatórios, sem refresh.

Parâmetros

ParâmetroTipoEstadoDescrição
store_account_numberstringobrigatórioNúmero da conta STORE iMali
amountdecimalobrigatórioValor a pagar
partner_transaction_idstringobrigatórioID único da transação. Exatamente 12 caracteres
payment_methodenum
imali
fixoFixo: "imali"
payment_typeenum
qrcode
fixoFixo: "qrcode"
qrcode_typeenum
DYNAMIC_TERMINAL | DYNAMIC_TICKET
obrigatórioDYNAMIC_TERMINAL: valor variável, 2 min. DYNAMIC_TICKET: valor fixo, requer expiração/título/descrição
transaction_typeenum
C2B
fixoFixo: "C2B"
titlestringopcionalTítulo (obrigatório para DYNAMIC_TICKET)
descriptionstringopcionalDescrição (obrigatório para DYNAMIC_TICKET)
expiration_datetimestringopcionalData/hora de expiração (obrigatório para DYNAMIC_TICKET)
curl -X POST 'https://paytek-africa.net:11901/api/partners/imaliway/v2/payments' \
                                -H 'Authorization: Bearer {privateKey}' \
                                -H 'X-Client-ID: {client_id}' \
                                -H 'Content-Type: application/json' \
                                -H 'Accept: application/json' \
                                --data '{"store_account_number":"290000001","amount":"400.00","partner_transaction_id":"FJNGMQWLXCP3","payment_method":"imali","payment_type":"qrcode","qrcode_type":"DYNAMIC_TERMINAL","transaction_type":"C2B"}'
Resposta (200 OK)
{
                                        "data": {
                                        "qrcode_id": "550e8400-e29b-41d4-a716-446655440000",
                                        "partner_transaction_id": "FJNGMQWLXCP3",
                                        "expiration_datetime": "2026-05-06 14:32:00",
                                        "amount": "400.00",
                                        "qrcode_type": "DYNAMIC_TERMINAL",
                                        "status": "PENDING"
                                        },
                                        "qrcode_token": "abc123:def456...789xyz",
                                        "qrcode_image": "data:image/png;base64,iVBORw0KGgo..."
                                    }

Verificar Estado

GET /payments/status

Verifica o estado de uma transação gerada via Push, Link ou QR Code. Para Push/Link usar partner_transaction_id. Para QR Code usar qrcode_token. Retorna PENDING, SUCCESS, FAILED ou EXPIRED.

Parâmetros

ParâmetroTipoEstadoDescrição
payment_typeenum
push | link | qrcode
obrigatórioTipo de pagamento
partner_transaction_idstringopcionalID da transação (para push e link)
qrcode_tokenstringopcionalToken do QR Code (apenas para qrcode)
curl -X GET 'https://paytek-africa.net:11901/api/partners/imaliway/v2/payments/status?partner_transaction_id=MPS25KLHLIKA&payment_type=push' \
                                    -H 'Authorization: Bearer {privateKey}' \
                                    -H 'X-Client-ID: {client_id}' \
                                    -H 'Accept: application/json'
Resposta (200 OK)
{
                                                "data": {
                                                "status": "PENDING",
                                                "left_time": "1:45"
                                                }
                                            }

Atualizar QR

POST /payments/qrcode/refresh

Atualiza a validade de um QR Code DYNAMIC_TERMINAL expirado. Estende a validade por mais 2 minutos e altera o status para PENDING. Não disponível para DYNAMIC_TICKET.

Parâmetros

ParâmetroTipoEstadoDescrição
qrcode_tokenstringobrigatórioToken do QR Code obtido na criação
curl -X POST 'https://paytek-africa.net:11901/api/partners/imaliway/v2/payments/qrcode/refresh' \
                                            -H 'Authorization: Bearer {privateKey}' \
                                            -H 'X-Client-ID: {client_id}' \
                                            -H 'Content-Type: application/json' \
                                            -H 'Accept: application/json' \
                                            --data '{"qrcode_token":"a7c6a:fcc8ee9ceb82cb28...a37d0c8f9dfbf495ce05ff"}'
Resposta (200 OK)
{
                                                    "data": {
                                                    "qrcode_id": "550e8400-e29b-41d4-a716-446655440000",
                                                    "partner_transaction_id": "FJNGMQWLXCP3",
                                                    "expiration_datetime": "2026-05-06 14:34:00",
                                                    "amount": "400.00",
                                                    "qrcode_type": "DYNAMIC_TERMINAL",
                                                    "status": "PENDING"
                                                    },
                                                    "qrcode_token": "new_token_abc123...",
                                                    "qrcode_image": "data:image/png;base64,iVBORw0KGgo..."
                                                }

Verificação B2C

POST /payments/check

Verifica as taxas que serão cobradas numa transferência B2C antes de a executar. Retorna fee, total e nome mascarado do destinatário. No ambiente Sandbox, masked_name retorna "Indisponível".

Parâmetros

ParâmetroTipoEstadoDescrição
client_account_numberstringobrigatórioNúmero de telefone ou conta iMali do destinatário
amountdecimalobrigatórioValor a transferir (decimal, ex: 100.00)
store_account_numberstringobrigatórioNúmero da conta BUSINESS (não Store) de onde sai o dinheiro
partner_transaction_idstringobrigatórioID único da transação. Exatamente 12 caracteres
payment_methodenum
mpesa | emola | mkesh | imali
obrigatórioMétodo de pagamento em minúsculas
transaction_typeenum
B2C
fixoFixo: "B2C"
curl -X POST 'https://paytek-africa.net:11901/api/partners/imaliway/v2/payments/check' \
                                                -H 'Authorization: Bearer {privateKey}' \
                                                -H 'X-Client-ID: {client_id}' \
                                                -H 'Content-Type: application/json' \
                                                -H 'Accept: application/json' \
                                                --data '{"client_account_number":"846002000","amount":"100.00","store_account_number":"290000002","partner_transaction_id":"B2C25CHECKID1","payment_method":"mpesa","transaction_type":"B2C"}'
Resposta (200 OK)
{
                                                        "data": {
                                                        "client_account_number": "846002000",
                                                        "amount": "100.00",
                                                        "total": 102.25,
                                                        "fee": "0.0225",
                                                        "masked_name": "Indisponível"
                                                        }
                                                    }

Transferência B2C

POST /payments

Executa uma transferência B2C (Business-to-Customer). Utiliza os mesmos parâmetros do método B2C Check. A conta store_account_number deve ser a conta BUSINESS (não Store).

Parâmetros

ParâmetroTipoEstadoDescrição
client_account_numberstringobrigatórioNúmero de telefone ou conta iMali do destinatário
amountdecimalobrigatórioValor a transferir (decimal, ex: 100.00)
store_account_numberstringobrigatórioNúmero da conta BUSINESS (não Store)
partner_transaction_idstringobrigatórioID único da transação. Exatamente 12 caracteres
payment_methodenum
mpesa | emola | mkesh | imali
obrigatórioMétodo de pagamento em minúsculas
transaction_typeenum
B2C
fixoFixo: "B2C"
curl -X POST 'https://paytek-africa.net:11901/api/partners/imaliway/v2/payments' \
                                                    -H 'Authorization: Bearer {privateKey}' \
                                                    -H 'X-Client-ID: {client_id}' \
                                                    -H 'Content-Type: application/json' \
                                                    -H 'Accept: application/json' \
                                                    --data '{"client_account_number":"846002000","amount":"100.00","store_account_number":"290000002","partner_transaction_id":"B2C25TRANS001","payment_method":"mpesa","transaction_type":"B2C"}'
Resposta (200 OK)
{
                                                            "code": "IMS002",
                                                            "success": "Created Successfully",
                                                            "type": "IMS",
                                                            "message": "Transferência feita com sucesso",
                                                            "messageLang": {
                                                            "pt": "Transferência feita com sucesso",
                                                            "en": "Success Transfer"
                                                            }
                                                        }

Webhooks — Visão Geral

Webhooks permitem que o sistema notifique automaticamente a sua aplicação sempre que ocorrer um evento importante, como a confirmação de um pagamento. Elimina a necessidade de polling constante.

A adesão ao webhook é feita automaticamente no acto da parceria. O parceiro deve fornecer uma callback_url e receberá uma webhook_secret para validação.

Eventos Disponíveis

PAYMENT.PENDINGPagamento criado, aguarda conclusão
PAYMENT.SUCCESSPagamento concluído com sucesso
PAYMENT.FAILEDPagamento falhou

Fluxo do Webhook

  1. Cliente inicia transação no sistema do parceiro
  2. iMali Gateway processa a transação e atualiza o estado
  3. Gateway envia requisição HTTP POST para a callback_url configurada
  4. Sistema do parceiro valida assinatura e processa a notificação

Estrutura do Payload

Headers

Content-Type: application/json
X-Webhook-Id: evt_123456
X-Webhook-Timestamp: 1712750000
X-Webhook-Signature: sha256=abc123...

Body

{
                                                        "id": "evt_123456",
                                                        "type": "payment.success",
                                                        "data": {
                                                        "payment_id": "pay_123",
                                                        "amount": 5000,
                                                        "status": "SUCCESS"
                                                        }
                                                    }
Retentativas: Se o endpoint não responder com HTTP 2xx, o webhook será reenviado automaticamente — até 10 tentativas em 72h com intervalo progressivo.

Segurança dos Webhooks

Valide cada webhook recebido usando a assinatura HMAC-SHA256 no cabeçalho X-Webhook-Signature para garantir autenticidade e proteção anti-replay.

Rejeite sempre webhooks com timestamp superior a 5 minutos para prevenir ataques de repetição.

Processo de Validação

1
Ler dados do header
Obter X-Webhook-Timestamp e X-Webhook-Signature do header.
2
Construir string assinada
Concatenar: timestamp + "." + payload_bruto
3
Gerar assinatura esperada
HMAC-SHA256(signed_string, webhook_secret)
4
Comparar e validar tempo
Usar hash_equals() para comparação. Validar que timestamp ≤ 5 minutos.