safaricom/LNMOnlineAndroidSample

Invalid Access Token

Closed this issue ยท 29 comments

I am getting below response:

{
"requestId":"10219-2484793-1",
"errorCode": "404.001.03",
"errorMessage": "Invalid Access Token"
}

Kindly assist.

I had not checked on Lipa na Mpesa Online on my App

The problem happens when the Lipa na Mpesa Online has yet not approved in your app that you created at .https://developer.safaricom.co.ke
Any one who has this problem always check your app if it has been approved. Other wise you will get the error.

To check whether app has been approved

Go to your apps:
Then select the app that you are working on:
You will see: Keys | Products| Details Analytics| Edit "yourAPP"| Delete "yourApp"

Select Products

You will find two products :

  1. API Product: MPesa Sandbox
  2. API Product: Lipa na Mpesa Online

You will see whether they have been approved or not depending on which product you are using.

Hallo there.

I am facing the same issue right now. I've checked products as explained above, mine is approved. But I still get the error.

{ "requestId":"11559-988723-1", "errorCode": "404.001.03", "errorMessage": "Invalid Access Token" }

I refresh the token on each request right now as I test. I've been at this all day. I wonder what I am doing wrong

The doc says:
request["authorization"] = 'Bearer <Access-Token>'

Is this the final syntax? with the < and > for example:

request["authorization"] = 'Bearer <AhxAEU1p0L4AgxVHwiZ87k9R4QOY>

Or should it be without? < > that is:

request["authorization"] = 'Bearer AhxAEU1p0L4AgxVHwiZ87k9R4QOY

Done that, Still same error. I'm writing this in ruby. Have a look at this

token  = get_token
uri = URI('https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest')
encode_ready_string = SHORTCODE + PASSKEY + TIMESTAMP
password =  Base64.encode64(encode_ready_string)


http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(uri)
request["accept"] = 'application/json'
request["content-type"] = 'application/json'
request["authorization"] = "Bearer #{token}"
request.body = "{\"BusinessShortCode\": \"80000\",
  \"Password\": \"#{password} \",
  \"Timestamp\": \"#{TIMESTAMP} \",
  \"TransactionType\": \"CustomerPayBillOnline\",
  \"Amount\": \"1\",
  \"PartyA\": \"#{PHONENUMBER}\",
  \"PartyB\": \"#{SHORTCODE}\",
  \"PhoneNumber\": \"#{PHONENUMBER} \",
  \"CallBackURL\": \"https://ip_address:port/callback\",
  \"AccountReference\": \"Discoucher mobile book purchase for #{PHONENUMBER} \",
  \"TransactionDesc\": \"Testing Transactions \"}"


  response = http.request(request)
  puts response.read_body

The get_token method works perfectly. While am here, I might ask what is the pass key ? couldn't find info in the doc.

Thank you for your help.

i want to same issue facing like and also mpesa api approved(http://prntscr.com/mjvzhm) :
{
"requestId":"23345-510564-1",
"errorCode": "404.001.03",
"errorMessage": "Invalid Access Token"
}

I had to go to 'Edit' in my App then made sure the following was enabled:

1.Lipa Na Mpesa Sandbox

2.MPesa Sandbox

And it worked!

I had to go to 'Edit' in my App then made sure the following was enabled:

1.Lipa Na Mpesa Sandbox

2.MPesa Sandbox

And it worked!

i still face the same error
{"requestId":"23345-510564-1",
"errorCode": "404.001.03",
"errorMessage": "Invalid Access Token"
}

im using php...and im require to $_GET[''token'] first...
here token refers to my prefered auth-password. how do you generate this password?

{ "requestId":"10018-959815-1", "errorCode": "401.003.01", "errorMessage": "Error Occurred - Invalid Access Token - Invalid access token" }

my app is already approved

jjoek commented

@joshua20
from the docs:
The password is generated by base64 encoding the passkey, shortcode and timestamp, the resultant string from this encoding is the password.

With php something like: base64_encode($shortcode . $passkey . $timestamp); should do

well for this issue as highlighted by @Nyundoogo
go
to
'Edit' in my App then made sure the following was enabled:

1.Lipa Na Mpesa Sandbox

2.MPesa Sandbox
but what the reason for the access token to valid for an hour my workaround for this will be shutting down my app every 50 minutes and generating the token but this will be cumbersome for what I was looking for

Had the same issue yet my lipa na mpesa app was approved on the portal.

My workaround was to use a separate url to fetch the access token , then used it (the access token) to auth my page.
So a simple access_token_request.php page that redirected to my other page with the token as a session var.

Reason: i suspect the url is used as a factor when handling tokens since this is a security feature. therefor my url might be what is causing the access token to be rejected. I bet am wrong tho given that if url is used to dispense and check everything, why would one access token be used for multiple pages?

All the best.

@Gravity1 sounds interesting

I facing this issue when simulating B2C payments

Ensure the word 'MPesa' is not on your url i.e https://example.org/mpesa/register.php it should instead be something else i.e.

  • **https://example.org/app/register.php**

image

It turn out that I was using C2B shortcode for B2C operations

I solved this by confirming am using the right URL
ie.
$url = '/c2b/v1/simulate';
$url = '/c2b/v2/simulate';

i still face the same error {"requestId":"23345-510564-1", "errorCode": "404.001.03", "errorMessage": "Invalid Access Token" }

1-if you are facing the same problem as I was change the curl variable to ch daraja 2.0 changed that variable us $ch instead of $curl.
2-change the call back to this url $CallBackURL = "https://mydomain.com/path";
3-Use this link https://developer.safaricom.co.ke/APIs/MpesaExpressSimulate to simulate the required credentials

if this helps add an emoji ๐Ÿ˜ƒ

I solved this by confirming am using the right URL ie. $url = '/c2b/v1/simulate'; $url = '/c2b/v2/simulate';

This works

Awesome

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(

Phone Number Amount Pay ); });

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'
}

I solved this by confirming am using the right URL ie. $url = '/c2b/v1/simulate'; $url = '/c2b/v2/simulate';

This works

Hi Eric,am having a problem generating b2c access token can you please help

I am getting below response:

{ "requestId":"10219-2484793-1", "errorCode": "404.001.03", "errorMessage": "Invalid Access Token" }

Kindly assist.

check the mpesa shortcode or the express code

Bonjour ! Aidez-moi a resoudre ce probleme

{
"requestId":"6e86-45dd-91ac-fd5d4178ab523792718",
"errorCode": "400.002.02",
"errorMessage": "Bad Request - Invalid PhoneNumber"
}
Je veux utiliser le numero M_pesa RDC