martinmogusu / django-daraja

A python django library for interacting with the MPESA Daraja API
MIT License
69 stars 77 forks source link

Invalid Access Token Error #11

Open Sajeyks opened 1 year ago

Sajeyks commented 1 year ago

I configured everything as guided and it worked. Then I come the next day and rerun the code without changing anything and I get the: { "requestId":"5115-78674050-1", "errorCode": "404.001.03", "errorMessage": "Invalid Access Token" }. So after waiting impatiently, it worked again. This keeps happening. Is there a possibility that it's lagging behind on updating the access token, coz you said that it does that automatically?

Sajeyks commented 1 year ago

I configured everything as guided and it worked. Then I come the next day and rerun the code without changing anything and I get the: { "requestId":"5115-78674050-1", "errorCode": "404.001.03", "errorMessage": "Invalid Access Token" }. So after waiting impatiently, it worked again. This keeps happening. Is there a possibility that it's lagging behind on updating the access token, coz you said that it does that automaticaly?

@martinmogusu

martinmogusu commented 1 year ago

Let me take a look...

martinmogusu commented 1 year ago

I tried to reproduce your scenario, I see that it might be related to a previous issue in version 1.2.0 on access token expiry time calculation. This issue has been addressed in the latest version of the package (1.3.0) Please run pip install django_daraja --upgrade to get the latest version. If your dependency version is in your requirements.txt file, you can specify the version there as well.

Please let me know if this works for you.

xavieromondi commented 1 year ago

hi i had the same problem gave me sleepless nights for days here is how i solved it : Use a middleware function to generate the token then call it just before the stkPush route e.g app.post("/stkpush",generateToken,(req,res){} and here is my source code const express = require("express"); const cors = require("cors"); const app = express(); const axios = require("axios"); const bodyParser = require("body-parser");

require("dotenv").config(); const PORT = process.env.PORT;

app.use(express.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cors());

const getAccessToken = async () => { const consumerKey = "wcMZ02TzOagGtiYg9oGRpfdR8BXYOFMN"; const consumerSecret = "Axvzm9tnBQxYcJ33";

try { const url = "https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials"; const encodedCredentials = Buffer.from( ${consumerKey}:${consumerSecret} ).toString("base64"); console.log(my credentials ${encodedCredentials}); const headers = { Authorization: Basic ${encodedCredentials}, };

const response = await axios.get(url, { headers });
return response.data.access_token;

} catch (error) { throw new Error("Failed to get access token."); } };

// Middleware function to generate access token const generateToken = async (req, res, next) => { try { const token = await getAccessToken(); req.token = token; next(); } catch (error) { console.error(error); res.status(400).json({ error: error.message }); } };

app.get("/stk", (req, res) => { res.send( `

  <input type="text" name="phone" />
  <label>Amount</label>
  <input type="text" name="amount" />
  <button type="submit">Pay</button>
</form>`

); });

app.post("/stk", generateToken, async (req, res) => { const phone = req.body.phone.substring(1); const amount = req.body.amount;

const date = new Date(); const timestamp = date.getFullYear() + ("0" + (date.getMonth() + 1)).slice(-2) + ("0" + date.getDate()).slice(-2) + ("0" + date.getHours()).slice(-2) + ("0" + date.getMinutes()).slice(-2) + ("0" + date.getSeconds()).slice(-2);

const shortCode = "174379"; // Sandbox: '174379' const passkey = "bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919";

const stk_password = Buffer.from(shortCode + passkey + timestamp).toString( "base64" );

// Choose one depending on your development environment const url = "https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest"; // Sandbox // const url = 'https://api.safaricom.co.ke/mpesa/stkpush/v1/processrequest'; // Live

try { const token = req.token; const headers = { Authorization: Bearer ${token}, "Content-Type": "application/json", };

const requestBody = {
  BusinessShortCode: shortCode,
  Password: stk_password,
  Timestamp: timestamp,
  TransactionType: "CustomerPayBillOnline",
  Amount: amount,
  PartyA: `254${phone}`,
  PartyB: shortCode,
  PhoneNumber: `254${phone}`,
  CallBackURL: "https://mydomain.com/path",
  AccountReference: "account",
  TransactionDesc: "test",
};

const response = await axios.post(url, requestBody, { headers });
console.log(response.data); // Log the response data
res.status(200).json(response.data);

} catch (error) { console.error(error); res.status(400).json({ error: error.message }); } });

app.listen(PORT, () => { console.log(Server is running on port ${PORT}); }); after making the changes you should get this log { MerchantRequestID: '5732-22683571-1', CheckoutRequestID: 'ws_CO_31052023093649166797211187', ResponseCode: '0', ResponseDescription: 'Success. Request accepted for processing', CustomerMessage: 'Success. Request accepted for processing' }

Sajeyks commented 1 year ago

@xavieromondi I also solved mine the same way... But I appreciate the help 👍