Initial commit
This commit is contained in:
397
app/Controllers/DisbursementController.php
Normal file
397
app/Controllers/DisbursementController.php
Normal file
@@ -0,0 +1,397 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Core\Controller;
|
||||
use App\Models\User;
|
||||
use App\Models\Disbursement;
|
||||
use App\Models\AirtelBroker;
|
||||
use App\Models\MpambaBroker;
|
||||
|
||||
use App\Core\Auth;
|
||||
use App\Core\Logger;
|
||||
|
||||
class DisbursementController extends Controller {
|
||||
|
||||
public function index() {
|
||||
#$users = User::all();
|
||||
$token = Auth::getBearerToken();
|
||||
|
||||
$user = User::getByToken($token);
|
||||
$logger = new Logger();
|
||||
if ($user == false) {
|
||||
// code...
|
||||
$logger->error("API Authentication failed token : " . $token);
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Unauthorised Access",
|
||||
]);
|
||||
}
|
||||
|
||||
$log_data = json_encode($user);
|
||||
$logger->info("User $log_data successfully authenticated from " . $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
$payload = json_decode(file_get_contents("php://input") , true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
// echo "JSON Error: " . json_last_error_msg();
|
||||
http_response_code(400);
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Bad Request. Invalid JSON Object",
|
||||
]);
|
||||
}
|
||||
$requested_keys = ['transaction_id', 'reference_id', 'mobile_number', 'amount'];
|
||||
foreach ($requested_keys as $key) {
|
||||
if (!isset($payload[$key]) || trim($payload[$key]) === '') {
|
||||
http_response_code(400);
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Validation Error: Missing or empty field : {$key}",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9]+$/', $payload['transaction_id'])) {
|
||||
http_response_code(400);
|
||||
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Validation Error: Malformed Transaction ID",
|
||||
]);
|
||||
}
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9]+$/', $payload['reference_id'])) {
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Validation Error: Malformed Reference ID",
|
||||
]);
|
||||
}
|
||||
|
||||
if (!preg_match('/^[0-9]{9,12}$/', $payload['mobile_number'])) {
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Validation Error: Invalid Mobile Number format",
|
||||
]);
|
||||
}
|
||||
|
||||
$amount = filter_var($payload['amount'], FILTER_VALIDATE_FLOAT);
|
||||
if ($amount === false || $amount <= 0) {
|
||||
return $this->json([
|
||||
"status" => "failed",
|
||||
"message" => "Validation Error: Amount must be a positive number",
|
||||
]);
|
||||
}
|
||||
$logger->info("Disbursement check request : " . json_encode($payload));
|
||||
$transaction_details = Disbursement::varifyTransaction($payload['transaction_id'], $payload['reference_id']);
|
||||
if ($transaction_details == false) {
|
||||
return $this->json([
|
||||
'status' => 'fail',
|
||||
'data' => 'Transaction not found',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$network = $this->getNetwork($payload['mobile_number']);
|
||||
//pull this away into the ENV file
|
||||
$pin = "IGbCqXwRoiqsHTIIjxfo6vWyzPMKg6iF3+pNQK6gTXbOyJgOd1bbPuIstTcMwSAiRXOgQrkRC0+sQU5wHF33aha+AL0TevBntLzVyGl8002ZXy6Ux4Pu+zymRdlw7J6H/PXRC2kXhbR2GIHLHlqHC49gu65OzpJ8fvpnscg1yjE=";
|
||||
|
||||
if ($network == 'airtel') {
|
||||
$broker_details = AirtelBroker::find($transaction_details[0]['wallet_id']);
|
||||
$authURL = $_ENV['AIRTEL_MONEY_AUTH_URL'];
|
||||
$auth_result = $this->authenticateAirtel($authURL, $broker_details['client_id'], $broker_details['client_secret']);
|
||||
if ($auth_result['success'] == false) {
|
||||
$logger->info("Airtel Money authentication failed " . json_encode($auth_result));
|
||||
return $this->json([
|
||||
'status' => 'fail',
|
||||
'data' => 'Your request could not be handled at this time. Try again',
|
||||
]);
|
||||
}
|
||||
$airtel_array = [
|
||||
"accessToken" => $auth_result['token'],
|
||||
"msisdn" => $transaction_details[0]['msisdn'],
|
||||
"amount" => $amount,
|
||||
"reference" => $transaction_details[0]['infotech_transaction_id'],
|
||||
"pin" => $pin,
|
||||
"transactionId" => $transaction_details[0]['transaction_id'],
|
||||
"country" => "MW",
|
||||
"currency" => "MWK"
|
||||
];
|
||||
|
||||
$retval = $this->airtelDisbursement($airtel_array);
|
||||
var_dump($retval);
|
||||
$disbursement_update_data = [
|
||||
'response_message' => $disbursement_retval['response'],
|
||||
'confirmed' => 1,
|
||||
'confirmed_at' => date('Y-m-d H:i:s'),
|
||||
'status' => 'successful'
|
||||
];
|
||||
$logger->info('Disbursement Update data : ' . json_encode($disbursement_update_data));
|
||||
$update_result = Disbursement::updateById($transaction_details[0]['id'], $disbursement_update_data);
|
||||
$logger->info('Airtel Disbursement Update Result : ' . $update_result);
|
||||
}
|
||||
elseif($network == 'tnm'){
|
||||
//code
|
||||
$broker_details = MpambaBroker::getBroker($transaction_details[0]['wallet_id']);
|
||||
$auth_result = $this->authenticateMpamba($transaction_details[0]['wallet_id'], $broker_details[0]['password']);
|
||||
$params = [
|
||||
"msisdn" => $transaction_details[0]['msisdn'],
|
||||
"amount" => $transaction_details[0]['amount'],
|
||||
"transaction_id" => $transaction_details[0]['transaction_id'],
|
||||
"narration" => "Testing", //$transaction_details[0]['description']
|
||||
"token" => $auth_result['token']
|
||||
];
|
||||
$disbursement_retval = $this->mpambaDisbursement($params);
|
||||
var_dump($disbursement_retval);
|
||||
$disbursement_update_data = [
|
||||
'response_message' => $disbursement_retval['raw'],
|
||||
'confirmed' => 1,
|
||||
'confirmed_at' => date('Y-m-d H:i:s'),
|
||||
'status' => 'successful'
|
||||
|
||||
];
|
||||
$logger->info('Disbursement Update data : ' . json_encode($disbursement_update_data));
|
||||
$update_result = Disbursement::updateById($transaction_details[0]['id'], $disbursement_update_data);
|
||||
$logger->info('Mpamba Disbursement Update Result : ' . $update_result);
|
||||
}
|
||||
else{
|
||||
return $this->json([
|
||||
'status' => 'fail',
|
||||
'data' => 'Invalid phone number',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function show($id) {
|
||||
$user = User::find($id);
|
||||
|
||||
if (!$user) {
|
||||
return $this->json(['message' => 'User not found'], 404);
|
||||
}
|
||||
|
||||
return $this->json($user);
|
||||
}
|
||||
public function testUpdate(){
|
||||
$disbursement_update_data = [
|
||||
'response_message' => 'in heere',
|
||||
'confirmed' => 1,
|
||||
'confirmed_at' => date('Y-m-d H:i:s'),
|
||||
'status' => 'successful'
|
||||
];
|
||||
$update_result = Disbursement::updateById('3', $disbursement_update_data);
|
||||
var_dump($update_result);
|
||||
}
|
||||
public function airtelDisbursement($params) {
|
||||
$timeout = 30;
|
||||
$logger = new Logger();
|
||||
$url = $_ENV['AIRTEL_MONEY_DISBURSEMENT_URL'];
|
||||
|
||||
$payload = [
|
||||
"payee" => [
|
||||
"msisdn" => $params['msisdn']
|
||||
],
|
||||
"reference" => $params['reference'],
|
||||
"pin" => $params['pin'],
|
||||
"transaction" => [
|
||||
"amount" => $params['amount'],
|
||||
"id" => $params['transactionId']
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
$log_data = json_encode($payload);
|
||||
$logger->info("Disbursement Requests to Airtel MW : " . $log_data );
|
||||
|
||||
$headers = [
|
||||
'Content-Type: application/json',
|
||||
'Accept: */*',
|
||||
'X-Country: ' . $params['country'],
|
||||
'X-Currency: ' . $params['currency'],
|
||||
'Authorization: Bearer ' . $params['accessToken']
|
||||
];
|
||||
|
||||
$ch = curl_init($url);
|
||||
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
CURLOPT_POSTFIELDS => json_encode($payload),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => $timeout,
|
||||
CURLOPT_SSL_VERIFYPEER => true
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$error = curl_error($ch);
|
||||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
if ($error) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'CURL_ERROR',
|
||||
'message' => $error
|
||||
];
|
||||
}
|
||||
$logger->info("Disbursement Response from Airtel MW : " . $response);
|
||||
return [
|
||||
'success' => ($code === 200),
|
||||
'http_code' => $code,
|
||||
'response' => json_decode($response, true),
|
||||
'raw' => $response
|
||||
];
|
||||
}
|
||||
public function authenticateAirtel($baseURL, $wallet, $password){
|
||||
// JSON payload
|
||||
$postData = json_encode([
|
||||
"client_id" => $wallet,
|
||||
"client_secret" => $password,
|
||||
"grant_type" => "client_credentials"
|
||||
]);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return [
|
||||
"status" => "failed",
|
||||
"message" => "Bad Request. Invalid JSON Object" . json_last_error_msg(),
|
||||
];
|
||||
}
|
||||
$ch = curl_init($baseURL);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($postData)
|
||||
]);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch)) {
|
||||
$curl_error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Curl error: ' . $curl_error
|
||||
];
|
||||
}
|
||||
|
||||
// Get HTTP status code
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
// Decode JSON response
|
||||
$result = json_decode($response, true);
|
||||
|
||||
// Check if token is present
|
||||
if ($httpCode === 200 && isset($result['access_token'])) {
|
||||
return [
|
||||
'success' => true,
|
||||
'token' => $result['access_token']
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $result['error_description'] ?? 'Unknown error',
|
||||
'details' => $result['error'] ?? []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
#Mpamba Scripts
|
||||
public function authenticateMpamba($wallet, $password){
|
||||
$logger = new Logger();
|
||||
$url = rtrim($_ENV['MPAMBA_BASE_URL'], '/') . '/authenticate';
|
||||
|
||||
// JSON payload
|
||||
$postData = json_encode([
|
||||
'wallet' => $wallet,
|
||||
'password' => $password
|
||||
]);
|
||||
$logger->info("Mpamba Authentication Requests : " . $postData );
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return the response
|
||||
curl_setopt($ch, CURLOPT_POST, true); // Use POST method
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);// Set the request body
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($postData)
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_errno($ch)) {
|
||||
$curl_error = curl_error($ch);
|
||||
$logger->info("Mpamba Authentication Error : " . $curl_error );
|
||||
curl_close($ch);
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Error: ' . $curl_error
|
||||
];
|
||||
}
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
// Decode JSON response
|
||||
$result = json_decode($response, true);
|
||||
|
||||
// Check if token is present
|
||||
$logger->info("Mpamba Authentication Response : " . json_encode($result));
|
||||
if ($httpCode === 200 && isset($result['data']['token'])) {
|
||||
return [
|
||||
'success' => true,
|
||||
'token' => $result['data']['token'],
|
||||
'expires_at' => $result['data']['expires_at']
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $result['message'] ?? 'Unknown error',
|
||||
'details' => $result['errors'] ?? []
|
||||
];
|
||||
}
|
||||
}
|
||||
public function mpambaDisbursement($params){
|
||||
$logger = new Logger();
|
||||
$url = $_ENV['MPAMBA_BASE_URL'] . "/payments";
|
||||
|
||||
$payload = array(
|
||||
"msisdn" => $params['msisdn'],
|
||||
"amount" => (int)$params['amount'],
|
||||
"transaction_id" => $params['transaction_id'],
|
||||
"narration" => $params['narration']
|
||||
);
|
||||
$logger->info("Mpamba Disbursement Requests : " . json_encode($payload));
|
||||
$ch = curl_init($url);
|
||||
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
||||
"Content-Type: application/json",
|
||||
"Authorization: Bearer " . $params['token']
|
||||
));
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if ($response === false) {
|
||||
$error = curl_error($ch);
|
||||
$logger->info("Mpamba Disbursement Response Error : " . $error);
|
||||
curl_close($ch);
|
||||
|
||||
return array(
|
||||
"status" => "ERROR",
|
||||
"message" => "Error: " . $error
|
||||
);
|
||||
}
|
||||
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
$logger->info("Mpamba Disbursement Response : " . $response);
|
||||
$responseData = json_decode($response, true);
|
||||
|
||||
return array(
|
||||
"http_code" => $httpCode,
|
||||
"response" => $responseData
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user