refactored Mpamba Controller, added wallet tables
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class AirtelMoneyMalawiCallbacksController extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use App\Models;
|
||||
use App\Library\AirtelMoneyMw;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use Storage;
|
||||
|
||||
class AirtelMoneyMalawiController extends Controller
|
||||
{
|
||||
@@ -37,41 +38,38 @@ class AirtelMoneyMalawiController extends Controller
|
||||
"id" => $request->refID //time() . uniqid()
|
||||
]
|
||||
];
|
||||
//country, currency, msisdn,
|
||||
// $subscriber_country = $data['subscriber']['country'];
|
||||
// $subscriber_currency = $data['subscriber']['currency'];
|
||||
// $subscriber_msisdn = $data['subscriber']['msisdn'];
|
||||
$filename = "requests_" . date("Y-m-d") . ".txt";
|
||||
$logdata = date("Y-m-d H:i:s") . " - " . json_encode($request->all());
|
||||
Storage::disk('airtelmoney')->append($filename, $logdata);
|
||||
|
||||
// $transaction_amount = $data['transaction']['amount'];
|
||||
// $transaction_country = $data['transaction']['country'];
|
||||
// $transaction_currency = $data['transaction']['currency'];
|
||||
// $transaction_id = $data['transaction']['id'];
|
||||
$wallet = Models\AirtelMoneyWallet::where('name', $request->wallet_id)->first();
|
||||
if ($wallet == false) {
|
||||
// code...
|
||||
return response()->json(['code' => 3, 'msg' => 'Wallet Not found']);
|
||||
}
|
||||
#$authURL = "https://openapiuat.airtel.africa/auth/oauth2/token";
|
||||
$authURL = Config('airtelmoney.authURL');
|
||||
|
||||
$authURL = "https://openapiuat.airtel.africa/auth/oauth2/token";
|
||||
|
||||
//no comments
|
||||
//CONTINENTAL CAPITAL
|
||||
$clientID = "9ff18a6d-331e-4ec5-9ecc-4e512e13747c";
|
||||
$clientSecret = "40f44254-10e7-4eb8-b161-38125117f4ba";
|
||||
|
||||
|
||||
$result = $this->authenticate($authURL, $clientID, $clientSecret);
|
||||
$result = $this->authenticate($authURL, $wallet->clientID, $wallet->clientSecret);
|
||||
if($result['success']){
|
||||
|
||||
$bearerToken = $result['token'];
|
||||
|
||||
//send a ussd push
|
||||
$retval = $this->sendUSSDPush($bearerToken, $request_data);
|
||||
|
||||
$filename = "ussd_push_responses_" . date("Y-m-d") . ".txt";
|
||||
$logdata = date("Y-m-d H:i:s") . " - " . json_encode($retval);
|
||||
Storage::disk('airtelmoney')->append($filename, $logdata);
|
||||
|
||||
$result_data = json_decode($retval, true);
|
||||
// dump($result_data);
|
||||
// Check if the response has a status and success flag
|
||||
if (isset($result_data['status']['success']) && $result_data['status']['success'] === true) {
|
||||
// Success case
|
||||
$transactionId = $result_data['data']['transaction']['id'];
|
||||
$transactionStatus = $result_data['data']['transaction']['status'];
|
||||
$message = $result_data['status']['message'];
|
||||
|
||||
$msg = "✅ Transaction Successful!\n";
|
||||
$msg = "Transaction Successful!\n";
|
||||
$msg .= "Transaction ID: $transactionId\n";
|
||||
$msg .= "Status: $transactionStatus\n";
|
||||
$msg .= "Message: $message\n";
|
||||
@@ -81,7 +79,7 @@ class AirtelMoneyMalawiController extends Controller
|
||||
$errorCode = $result_data['status']['result_code'] ?? 'N/A';
|
||||
$errorMessage = $result_data['status']['message'] ?? 'Unknown error';
|
||||
|
||||
$msg = "❌ Transaction Failed!\n";
|
||||
$msg = "Transaction Failed!\n";
|
||||
$msg .= "Error Code: $errorCode\n";
|
||||
$msg .= "Message: $errorMessage\n";
|
||||
return response()->json(['code' => 3, 'msg' => $msg, 'responseRaw' => $result_data ]);
|
||||
@@ -271,25 +269,23 @@ class AirtelMoneyMalawiController extends Controller
|
||||
];
|
||||
}
|
||||
|
||||
// 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 {
|
||||
}
|
||||
else {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $result['error_description'] ?? 'Unknown error',
|
||||
'error' => $result, // $result['error_description'] ?? 'Unknown error',
|
||||
'details' => $result['error'] ?? []
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
// use App\Library\Kazang;
|
||||
use App\Library\AirtelMoneyMw;
|
||||
use App\Library\MpambaTnm;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
// Requests\CollectPaymentsRequest //
|
||||
|
||||
class MoneyCollectionController extends Controller
|
||||
{
|
||||
public function collectTest(Request $request){
|
||||
@@ -154,10 +154,9 @@ class MoneyCollectionController extends Controller
|
||||
//TODO : find a way to dynamically retrieve Product ID from the list
|
||||
#$product_list = $this->getProductIDs($request->product_name);
|
||||
|
||||
return response()->json(['code' => 1, 'data' => json_decode($product_list)]);
|
||||
return response()->json(['code' => 1, 'data' => $request->all()]);
|
||||
|
||||
return response()->json(['code' => 3, 'msg' => 'Your request could not handled at this time', 'endpoint' => $endpoint]);
|
||||
|
||||
}
|
||||
public function getSessionUuid($kazang){
|
||||
$kas_session = Models\KazangSession::find(1);
|
||||
|
||||
55
app/Http/Controllers/MpambaTnmCallbacksController.php
Normal file
55
app/Http/Controllers/MpambaTnmCallbacksController.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MpambaTnmCallbacksController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
/*
|
||||
Developer: David Kumwenda
|
||||
Contact: 0881161942 or 0996139030
|
||||
App: Mpamba 4 MSE
|
||||
Date: 30 August 2025
|
||||
Duration: 1 day dev work
|
||||
*/
|
||||
|
||||
|
||||
// Read raw POST data
|
||||
#$rawData = file_get_contents("php://input");
|
||||
|
||||
// Decode JSON
|
||||
#$data = json_decode($rawData, true);
|
||||
|
||||
// Basic logging (optional, useful for debugging)
|
||||
#file_put_contents("logs/callback_log_" . date('Ymd') . '.txt', date("Y-m-d H:i:s") . " - " . $rawData . PHP_EOL, FILE_APPEND);
|
||||
|
||||
$filename = "callback_log_" . date("Y-m-d") . ".txt";
|
||||
$logdata = date("Y-m-d H:i:s") . " - " . json_encode($request->all());
|
||||
Storage::disk('callbacks')->append($filename, $logdata);
|
||||
|
||||
|
||||
if (isset($request->receipt_number, $request->result_code, $request->transaction_id)) {
|
||||
|
||||
$receiptNumber = $request["receipt_number"];
|
||||
$resultCode = $request["result_code"];
|
||||
$resultDescription = $request->["result_description"] ?? "";
|
||||
$resultTime = $request->["result_time"] ?? date("Y-m-d H:i:s");
|
||||
$transactionId = $request->["transaction_id"];
|
||||
$success = $request->["success"] ?? false;
|
||||
|
||||
|
||||
// Respond with 200 OK to acknowledge receipt
|
||||
http_response_code(200);
|
||||
echo json_encode(["status" => "callback received"]);
|
||||
|
||||
}
|
||||
else {
|
||||
// Missing required fields
|
||||
http_response_code(400);
|
||||
echo json_encode(["error" => "Invalid callback payload"]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
253
app/Http/Controllers/MpambaTnmController.php
Normal file
253
app/Http/Controllers/MpambaTnmController.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
use App\Http\Requests;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models;
|
||||
use App\Library\MpambaTnm;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use Storage;
|
||||
|
||||
class MpambaTnmController extends Controller
|
||||
{
|
||||
//
|
||||
public function collect(Requests\MpambaTnmRequest $request){
|
||||
|
||||
/*
|
||||
//$incoming = file_get_contents("php://input");
|
||||
//$details = json_decode($incoming, true);
|
||||
$invoiceNumber = $details['invoiceNumber'];
|
||||
$amount = $details['amount'];
|
||||
$msisdn = $details['msisdn'];
|
||||
$description = $details['description'];
|
||||
{"message":"Request accepted and processing","errors":[],"trace":[],"data":[]}
|
||||
*/
|
||||
|
||||
|
||||
$filename = "requests_" . date("Y-m-d") . ".txt";
|
||||
$logdata = date("Y-m-d H:i:s") . " - " . json_encode($request->all());
|
||||
Storage::disk('mpambatnm')->append($filename, $logdata);
|
||||
|
||||
//todo
|
||||
// grab broker wallet detals
|
||||
$wallet = Models\MpambaTnmWallet::where('wallet_id', $request->wallet_id)->first();
|
||||
if ($wallet == false) {
|
||||
// code...
|
||||
return response()->json(['code' => 3, 'msg' => 'Wallet Not found']);
|
||||
}
|
||||
$invoiceNumber = . $wallet->id . "_" . time();
|
||||
$description = "Stock purchase Payment from " . $wallet->name;
|
||||
// generate invoiceNumber
|
||||
// return response()->json(['code' => 1, 'data' => $wallet]);
|
||||
$baseURL = Config('mpambatnm.base_url'); // "https://devpayouts.tnmmpamba.co.mw/api";
|
||||
|
||||
#$wallet = "505072";
|
||||
#$password = "N8O7L0vpl5mflfwHzf4DSle9bToV*";//CEDAR PASSWORD
|
||||
|
||||
//$res=authenticate($baseURL, $wallet, $password);
|
||||
#$bearerToken = "102164|newoEd6QOFaTptUiGAp232jULtUmgMtaX1x2CRww4Ka2270dc49";
|
||||
$token_arr = $this->authenticate($baseURL, $wallet->wallet_id, $wallet->password);
|
||||
if ($token_arr['success'] == true) {
|
||||
$result = $this->sendUSSDPush($baseURL, $token_arr['token'], $invoiceNumber, $request->amount, $request->msisdn, $description);
|
||||
//create transaction here
|
||||
$filename = "ussd_push_responses_" . date("Y-m-d") . ".txt";
|
||||
$logdata = date("Y-m-d H:i:s") . " - " . json_encode($result);
|
||||
Storage::disk('mpambatnm')->append($filename, $logdata);
|
||||
$transaction_params = [
|
||||
'msisdn' => $request->msisdn,
|
||||
'amount' => $request->amount,
|
||||
'invoice_number' => $invoiceNumber,
|
||||
'wallet_id' => $wallet->wallet_id,
|
||||
'reference_id' => $request->refID,
|
||||
];
|
||||
$transaction = Models\TnmTransaction::create($transaction_params);
|
||||
return response()->json(['code' => 1, 'data' => $result]);
|
||||
}
|
||||
}
|
||||
|
||||
public function sendUSSDPush($baseURL, $token, $invoiceNumber, $amount, $msisdn, $description) {
|
||||
// Endpoint
|
||||
$url = rtrim($baseURL, "/") . "/invoices";
|
||||
|
||||
// Prepare payload
|
||||
$data = [
|
||||
"invoice_number" => $invoiceNumber,
|
||||
"amount" => (int)$amount,
|
||||
"msisdn" => $msisdn,
|
||||
"description" => $description
|
||||
];
|
||||
|
||||
// Initialize cURL
|
||||
$ch = curl_init($url);
|
||||
|
||||
// Set cURL options
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer " . $token,
|
||||
"Content-Type: application/json"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
|
||||
// Execute request
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Check for cURL errors
|
||||
if (curl_errno($ch)) {
|
||||
echo "cURL Error: " . curl_error($ch);
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close connection
|
||||
curl_close($ch);
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
public function changePassword($baseURL, $token,$newPassword, $newPasswordConfirmation) {
|
||||
// Endpoint URL
|
||||
$url = rtrim($baseURL, "/") . "/password";
|
||||
|
||||
// Prepare data
|
||||
$data = [
|
||||
"new_password" => $newPassword,
|
||||
"new_password_confirmation" => $newPasswordConfirmation
|
||||
];
|
||||
|
||||
// Initialize cURL
|
||||
$ch = curl_init($url);
|
||||
|
||||
// Set cURL options
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH"); // PATCH request
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
"Authorization: Bearer " . $token,
|
||||
"Content-Type: application/json"
|
||||
]);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
||||
|
||||
// Execute and capture response
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Check for errors
|
||||
if (curl_errno($ch)) {
|
||||
echo "cURL Error: " . curl_error($ch);
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close connection
|
||||
curl_close($ch);
|
||||
|
||||
// Decode JSON response
|
||||
return json_decode($response, true);
|
||||
}
|
||||
|
||||
public function validate_msisdn($baseURL, $msisdn, $bearerToken){
|
||||
// Ensure proper endpoint format
|
||||
$url = rtrim($baseURL, '/') . '/payments/validate/' . urlencode($msisdn);
|
||||
|
||||
// Initialize cURL
|
||||
$ch = curl_init($url);
|
||||
|
||||
// Set cURL options
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPGET, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
||||
'Authorization: Bearer ' . $bearerToken,
|
||||
'Accept: application/json'
|
||||
]);
|
||||
|
||||
// Execute the request
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Handle cURL error
|
||||
if (curl_errno($ch)) {
|
||||
curl_close($ch);
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Curl error: ' . curl_error($ch)
|
||||
];
|
||||
}
|
||||
|
||||
// Get HTTP status code
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
|
||||
// Decode JSON response
|
||||
$result = json_decode($response, true);
|
||||
|
||||
if ($httpCode === 200 && isset($result['data']['full_name'])) {
|
||||
return [
|
||||
'success' => true,
|
||||
'full_name' => $result['data']['full_name']
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => $result['message'] ?? 'Unknown error',
|
||||
'details' => $result['errors'] ?? []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function authenticate($baseURL, $wallet, $password){
|
||||
// Endpoint URL
|
||||
$url = rtrim($baseURL, '/') . '/authenticate';
|
||||
|
||||
// JSON payload
|
||||
$postData = json_encode([
|
||||
'wallet' => $wallet,
|
||||
'password' => $password
|
||||
]);
|
||||
|
||||
// Initialize cURL
|
||||
$ch = curl_init($url);
|
||||
|
||||
// Set cURL options
|
||||
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)
|
||||
]);
|
||||
|
||||
// Execute the request
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Check for cURL errors
|
||||
if (curl_errno($ch)) {
|
||||
curl_close($ch);
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Curl error: ' . curl_error($ch)
|
||||
];
|
||||
}
|
||||
|
||||
// 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['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'] ?? []
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,8 @@ class CollectPaymentsRequest extends FormRequest
|
||||
public function messages(){
|
||||
return array(
|
||||
'channel.required' => 'You need to specify the channel',
|
||||
'payment_mode.required' => 'You need to specify the payment mode',
|
||||
'broker_id.required' => 'You need to specify the borker',
|
||||
'wallet_id.required' => 'You need to specify the borker',
|
||||
'refID.required' => 'No reference ID found',
|
||||
// 'refID.unique' => 'Duplicate refID, check and try again'
|
||||
);
|
||||
}
|
||||
public function responsenn(array $errors){
|
||||
@@ -40,12 +38,9 @@ class CollectPaymentsRequest extends FormRequest
|
||||
return [
|
||||
'msisdn' => 'required|regex:/\d{10}$/',
|
||||
'amount' => 'required',
|
||||
'country' => 'required',
|
||||
'currency' => 'required',
|
||||
'channel' => 'required', //web, ussd, mobile app
|
||||
'refID' => 'required',
|
||||
'payment_mode' => 'required',
|
||||
'broker_id' => 'required',
|
||||
'wallet_id' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
43
app/Http/Requests/MpambaTnmRequest.php
Normal file
43
app/Http/Requests/MpambaTnmRequest.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class MpambaTnmRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function messages(){
|
||||
return array(
|
||||
'channel.required' => 'You need to specify the channel',
|
||||
'wallet_id.required' => 'You need to specify the borker',
|
||||
'refID.required' => 'No reference ID found',
|
||||
// 'refID.unique' => 'Duplicate refID, check and try again'
|
||||
);
|
||||
}
|
||||
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'msisdn' => 'required|regex:/\d{10}$/',
|
||||
'amount' => 'required',
|
||||
'channel' => 'required', //web, ussd, mobile app
|
||||
'refID' => 'required',
|
||||
'wallet_id' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
||||
13
app/Models/AirtelMoneyWallet.php
Normal file
13
app/Models/AirtelMoneyWallet.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AirtelMoneyWallet extends Model
|
||||
{
|
||||
protected $guarded = [
|
||||
'id'
|
||||
];
|
||||
public $table = 'airtel_money_wallets';
|
||||
}
|
||||
13
app/Models/MpambaTnmWallet.php
Normal file
13
app/Models/MpambaTnmWallet.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MpambaTnmWallet extends Model
|
||||
{
|
||||
protected $guarded = [
|
||||
'id'
|
||||
];
|
||||
public $table = 'mmpamba_tnm_wallets';
|
||||
}
|
||||
Reference in New Issue
Block a user