wikha-sdk
v1.1.11
Published
A JavaScript SDK for interacting with the Wikha payment gateway.
Readme
Usage
Initialization
Import the WikhaSDK class and initialize it with your API key, merchant ID, and public key:
import WikhaSDK from 'wikha-sdk';
const sdk = new WikhaSDK(
'YOUR_API_KEY',
'YOUR_MERCHANT_ID',
'YOUR_PUBLIC_KEY'
);
// You can also access static enums for convenience
console.log(WikhaSDK.PaymentType.payin);
console.log(WikhaSDK.Environment.sandbox);
# Processing a Payment
## Use the processPayment method to initiate a payment.
You'll need to provide a WikhaPayload object with the necessary payment details.
```TypeScript
import WikhaSDK from 'wikha-sdk';
const sdk = new WikhaSDK(
'YOUR_API_KEY',
'YOUR_MERCHANT_ID',
'YOUR_PUBLIC_KEY'
);
async function initiatePayment() {
const paymentData: WikhaSDK.WikhaPayload = {
provider: WikhaSDK.PaymentProviderType.mpesa,
payer_phone: '081XXXXXXX',
order_id: 'ORDER-12345',
amount: 100,
payer_name: 'John Tshisola',
operation: WikhaSDK.PaymentType.payin,
currency: 'CDF',
notify_url: '[https://your-callback-url.com/notify](https://www.google.com/search?q=https://your-callback-url.com/notify)',
return_url: '[https://your-website.com/success](https://www.google.com/search?q=https://your-website.com/success)',
};
try {
const response = await sdk.processPayment(paymentData);
console.log('Payment initiated successfully:', response);
// Handle the response, which might contain a payment URL or other instructions
} catch (error: any) {
console.error('Error initiating payment:', error.message);
// Handle the error
}
}
initiatePayment();Query transaction status
import WikhaSDK from 'wikha-sdk';
// Initialize your SDK instance (API Key, Merchant ID, Public Key are required)
const sdk = new WikhaSDK(
'YOUR_API_KEY',
'YOUR_MERCHANT_ID',
'YOUR_PUBLIC_KEY'
);
async function checkTransactionStatus(transactionId: string) {
try {
const transaction = await sdk.queryTransaction(transactionId);
console.log('Transaction details:', transaction);
if (transaction && transaction.status === WikhaSDK.PaymentStatus.accepted) {
console.log('Transaction was successful.');
} else if (transaction && transaction.status === WikhaSDK.PaymentStatus.rejected) {
console.log('Transaction was rejected.');
} else if (transaction && transaction.status === WikhaSDK.PaymentStatus.pending) {
console.log('Transaction is still pending.');
} else {
console.log('Transaction not found or status is unknown.');
}
} catch (error: any) {
console.error('Error querying transaction:', error.message);
// Handle the error
}
}
// Replace 'YOUR_TRANSACTION_ID' with the actual transaction ID you want to query
checkTransactionStatus('YOUR_TRANSACTION_ID');#Using Static Enums
import WikhaSDK from 'wikha-sdk';
function handlePaymentEvent(event: WikhaSDK.PaymentEventPayload) {
console.log('Payment Event Received:', event);
if (event.data?.type === WikhaSDK.PaymentType.payin && event.data?.status === WikhaSDK.PaymentStatus.accepted) {
console.log('A successful payin event occurred.');
}
}
// Example PaymentEventPayload (this would typically come from your backend or a webhook)
const samplePaymentEvent: WikhaSDK.PaymentEventPayload = {
id: 'evt_123',
eventType: 'payment.updated',
data: {
order_id: 'ORDER-12345',
type: WikhaSDK.PaymentType.payin,
status: WikhaSDK.PaymentStatus.accepted,
// ... other payment details
},
};
handlePaymentEvent(samplePaymentEvent);
console.log('Available Payment Providers:', Object.values(WikhaSDK.PaymentProviderType));
console.log('Sandbox Environment Value:', WikhaSDK.Environment.sandbox);#Client side usage
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WikhaSDK Payment</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.blue-indigo.min.css" />
<style>
body {
font-family: 'Roboto', sans-serif;
background-color: #f3f3f3;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.container {
background-color: #fff;
padding: 32px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
width: 90%;
max-width: 600px;
text-align: center;
}
h1 {
color: #3f51b5; /* Material Design Blue */
margin-bottom: 24px;
}
.mdl-textfield {
width: 100%;
margin-bottom: 16px;
display: block;
}
.mdl-button {
background-color: #3f51b5; /* Material Design Blue */
color: white;
margin-top: 24px;
}
#paymentResponse, #paymentError {
margin-top: 24px;
padding: 16px;
border-radius: 4px;
text-align: left;
}
#paymentResponse {
background-color: #e3f2fd; /* Light Blue */
border: 1px solid #bbdefb;
color: #1e88e5;
}
#paymentError {
background-color: #ffebee; /* Light Red */
border: 1px solid #ef9a9a;
color: #d32f2f;
}
#checkTransactionButton {
background-color: #3f51b5; /* Material Design Blue */
color: white;
margin-top: 16px;
}
</style>
</head>
<body>
<div class="container">
<h1>WikhaSDK Payment</h1>
<form id="paymentForm" class="mdl-grid">
<div class="mdl-cell mdl-cell--12-col">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<select class="mdl-textfield__input" id="provider">
<option value="mpesa">Mpesa</option>
<option value="orangemoney">Orange Money</option>
<option value="afrimoney">Afrimoney</option>
<option value="airtelmoney">Airtel Money</option>
</select>
<label class="mdl-textfield__label" for="provider">Payment Provider</label>
</div>
</div>
<div class="mdl-cell mdl-cell--12-col">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="tel" id="payer_phone" required>
<label class="mdl-textfield__label" for="payer_phone">Payer Phone</label>
<span class="mdl-textfield__error">Phone number required</span>
</div>
</div>
<div class="mdl-cell mdl-cell--12-col">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="order_id" required>
<label class="mdl-textfield__label" for="order_id">Order ID</label>
<span class="mdl-textfield__error">Order ID required</span>
</div>
</div>
<div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="number" id="amount" required>
<label class="mdl-textfield__label" for="amount">Amount</label>
<span class="mdl-textfield__error">Amount required</span>
</div>
</div>
<div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-tablet">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="payer_name" required>
<label class="mdl-textfield__label" for="payer_name">Payer Name</label>
<span class="mdl-textfield__error">Payer Name required</span>
</div>
</div>
<div class="mdl-cell mdl-cell--12-col">
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<select class="mdl-textfield__input" id="currency">
<option value="CDF">CDF</option>
<option value="USD">USD</option>
</select>
<label class="mdl-textfield__label" for="currency">Currency</label>
</div>
</div>
<div class="mdl-cell mdl-cell--12-col">
<button class="mdl-button mdl-js-button mdl-button--raised" type="button" onclick="initiatePayment()">
Initiate Payment
</button>
</div>
</form>
<div id="paymentResponse" style="display: none;"></div>
<div id="paymentError" style="display: none;"></div>
<button id="checkTransactionButton" class="mdl-button mdl-js-button mdl-button--raised" style="display: none;" onclick="checkTransactionStatus()">
Check Transaction Status
</button>
</div>
<script src="https://unpkg.com/wikha-sdk@latest/dist/wikha-sdk.umd.js"></script>
<script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<script>
let sdk;
let transactionId;
async function initiatePayment() {
const apiKey = ' API_KEY'; // Replace with your actual API key
const merchantId = 'MERCHANT_ID'; // Replace with your actual merchant ID
const publicKey = 'PUBLIC_KEY'; // Replace with your actual public key
const provider = document.getElementById('provider').value;
const payer_phone = document.getElementById('payer_phone').value;
const order_id = document.getElementById('order_id').value;
const amount = parseInt(document.getElementById('amount').value);
const payer_name = document.getElementById('payer_name').value;
const currency = document.getElementById('currency').value;
const paymentData = {
provider: provider,
payer_phone: payer_phone,
order_id: order_id,
amount: amount,
payer_name: payer_name,
operation: wikha.PaymentType.payin, // Assuming this is a payin
currency: currency,
// You can add optional fields like notify_url and return_url here
};
sdk = new wikha.WikhaSDK(apiKey, merchantId, publicKey);
const responseDiv = document.getElementById('paymentResponse');
const errorDiv = document.getElementById('paymentError');
const checkTransactionButton = document.getElementById('checkTransactionButton');
responseDiv.style.display = 'none';
errorDiv.style.display = 'none';
checkTransactionButton.style.display = 'none';
try {
const response = await sdk.processPayment(paymentData);
console.log('Payment Response:', response);
responseDiv.textContent = JSON.stringify(response, null, 2);
responseDiv.style.display = 'block';
// Assuming a successful response might contain a transaction ID
if (response?.paymentResult?.paymentId) {
transactionId = response.paymentResult.paymentId;
checkTransactionButton.style.display = 'block';
} else {
checkTransactionButton.style.display = 'none';
}
} catch (error) {
console.error('Payment Error:', error);
errorDiv.textContent = error.message;
errorDiv.style.display = 'block';
checkTransactionButton.style.display = 'none';
}
}
async function checkTransactionStatus() {
if (!sdk || !transactionId) {
alert('Payment must be initiated successfully first.');
return;
}
const responseDiv = document.getElementById('paymentResponse');
const errorDiv = document.getElementById('paymentError');
responseDiv.style.display = 'none';
errorDiv.style.display = 'none';
try {
const transaction = await sdk.queryTransaction(transactionId);
console.log('Transaction Status:', transaction);
responseDiv.textContent = 'Transaction Status: ' + JSON.stringify(transaction, null, 2);
responseDiv.style.display = 'block';
} catch (error) {
console.error('Error checking transaction status:', error);
errorDiv.textContent = 'Error checking transaction status: ' + error.message;
errorDiv.style.display = 'block';
}
}
</script>
</body>
</html># Error Handling
## The processPayment method returns a promise that resolves with the payment response or rejects with an error. Handle these cases accordingly.
# Node.js and Browser Compatibility
## This SDK is designed to work in both Node.js and browser environments.
# Dependencies
## node-fetch (for Node.js)
# Contributing
## Contributions are welcome! Please submit a pull request or open an issue on GitHub.
# # License
MIT
# Author
## Sylvain Kambiya, Wikha Hi-tech SARL