Authentication
All /v1/* payment endpoints require GATEWAY digest auth.
Header format
Authorization: GATEWAY <base64>
Decode the base64 token to apiKey:hexDigest. The digest must match:
hexDigest = sha256(apiSecret + requestPath + rawRequestBody)
Signing rules
requestPathis the path on the API host, e.g./v1/walletcashin/process(no host, no query string unless your client sends one).rawRequestBodyis the exact UTF-8 JSON string in the POST body. Re-serializing JSON with different key order or spacing will break the signature.- Use an empty string for the body when there is no payload (not typical for Lipachap payment calls).
Key modes and hosts
| Host | Key mode |
|---|---|
sandbox.api.lipachap.com | TEST only |
api.lipachap.com | LIVE only |
Using a TEST key on the live host (or vice versa) returns 401 Unauthorized.
Error responses
{
"resultcode": "401",
"resultdesc": "Unauthorized - Invalid digest",
"status": "FAILED"
}
Implementation samples
const crypto = require('crypto');
function lipachapAuthHeader(apiKey, apiSecret, requestPath, rawBody = '') {
const digest = crypto
.createHash('sha256')
.update(apiSecret + requestPath + rawBody)
.digest('hex');
const token = Buffer.from(`${apiKey}:${digest}`).toString('base64');
return `GATEWAY ${token}`;
}
// Example
const path = '/v1/walletcashin/process';
const body = JSON.stringify({
transid: 'TXN-001',
amount: 5000,
msisdn: '255712345678',
utilityref: 'ORDER-123',
utilitycode: 'VMCASHIN',
vendor: 'YOUR_VENDOR',
pin: '0000',
});
const authorization = lipachapAuthHeader(process.env.LIPACHAP_API_KEY, process.env.LIPACHAP_API_SECRET, path, body);import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import org.apache.commons.codec.digest.DigestUtils;
public final class LipachapAuth {
public static String authorizationHeader(String apiKey, String apiSecret, String path, String rawBody) {
String signed = apiSecret + path + (rawBody == null ? "" : rawBody);
String digest = DigestUtils.sha256Hex(signed);
String credentials = apiKey + ":" + digest;
return "GATEWAY " + Base64.getEncoder().encodeToString(credentials.getBytes(StandardCharsets.UTF_8));
}
}
// Usage
String path = "/v1/walletcashin/process";
String body = "{\"transid\":\"TXN-001\",\"amount\":5000,\"msisdn\":\"255712345678\"}";
String auth = LipachapAuth.authorizationHeader(apiKey, apiSecret, path, body);<?php
function lipachap_auth_header(string $apiKey, string $apiSecret, string $path, string $rawBody = ''): string {
$digest = hash('sha256', $apiSecret . $path . $rawBody);
$token = base64_encode($apiKey . ':' . $digest);
return 'GATEWAY ' . $token;
}
$path = '/v1/walletcashin/process';
$body = json_encode([
'transid' => 'TXN-001',
'amount' => 5000,
'msisdn' => '255712345678',
'utilityref' => 'ORDER-123',
], JSON_UNESCAPED_SLASHES);
$authorization = lipachap_auth_header(getenv('LIPACHAP_API_KEY'), getenv('LIPACHAP_API_SECRET'), $path, $body);import base64
import hashlib
import json
import os
def lipachap_auth_header(api_key: str, api_secret: str, path: str, raw_body: str = "") -> str:
digest = hashlib.sha256((api_secret + path + raw_body).encode("utf-8")).hexdigest()
token = base64.b64encode(f"{api_key}:{digest}".encode("utf-8")).decode("ascii")
return f"GATEWAY {token}"
path = "/v1/walletcashin/process"
body = json.dumps({
"transid": "TXN-001",
"amount": 5000,
"msisdn": "255712345678",
"utilityref": "ORDER-123",
"utilitycode": "VMCASHIN",
"vendor": "YOUR_VENDOR",
"pin": "0000",
}, separators=(",", ":"))
authorization = lipachap_auth_header(
os.environ["LIPACHAP_API_KEY"],
os.environ["LIPACHAP_API_SECRET"],
path,
body,
)package lipachap
import (
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"fmt"
)
func AuthHeader(apiKey, apiSecret, path, rawBody string) string {
sum := sha256.Sum256([]byte(apiSecret + path + rawBody))
digest := hex.EncodeToString(sum[:])
token := base64.StdEncoding.EncodeToString([]byte(apiKey + ":" + digest))
return "GATEWAY " + token
}
// Usage in a handler:
// path := "/v1/walletcashin/process"
// body := `{"transid":"TXN-001","amount":5000,"msisdn":"255712345678"}`
// req.Header.Set("Authorization", AuthHeader(apiKey, apiSecret, path, body))