I am automating WiFi payments, so my code is able to ask for payments and a callback is sent. I get the information and save it, generate a user, send an sms to the client and create the generated user in mikrotik all at the same time. Below is my code:
'''
def confirmation(request):
print("Start Mpesa")
global profile
mpesa_body = request.body.decode('utf-8')
mpesa_body = json.loads(mpesa_body)
print(mpesa_body)
print("Mpesa Body")
merchant_requestID = mpesa_body["Body"]["stkCallback"]["MerchantRequestID"]
print('merchant_requestID: ', merchant_requestID)
checkout_requestID = mpesa_body["Body"]["stkCallback"]["CheckoutRequestID"]
print('checkout_requestID: ', checkout_requestID)
result_code = mpesa_body["Body"]["stkCallback"]["ResultCode"]
print('result_code: ', result_code)
result_desc = mpesa_body["Body"]["stkCallback"]["ResultDesc"]
print('result_desc: ', result_desc)
metadata = mpesa_body["Body"]["stkCallback"]["CallbackMetadata"]["Item"]
for item in metadata:
title = item["Name"]
if title == "Amount":
amount = item["Value"]
print('Amount: ', amount)
elif title == "MpesaReceiptNumber":
mpesa_receipt_number = item["Value"]
print('Mpesa Reference No: ', mpesa_receipt_number)
elif title == "TransactionDate":
transaction_date = item["Value"]
print('Transaction date: ', transaction_date)
elif title == "PhoneNumber":
phone_number = item["Value"]
print('Phone Number: ', phone_number)
str_transaction_date = str(transaction_date)
trans_datetime = datetime.strptime(str_transaction_date, "%Y%m%d%H%M%S")
tz_trans_datetime = pytz.utc.localize(trans_datetime)
payment = MpesaPayment.objects.create(
MerchantRequestID=merchant_requestID,
CheckoutRequestID=checkout_requestID,
ResultCode=result_code,
ResultDesc=result_desc,
Amount=amount,
MpesaReceiptNumber=mpesa_receipt_number,
TransactionDate=tz_trans_datetime,
PhoneNumber=phone_number,
)
if result_code == 0:
payment.save()
print("Successfully saved")
password_length = 5
password = secrets.token_urlsafe(password_length)
print(password)
headers = {
'Content-Type': 'application/json',
'h_api_key': os.getenv("SMS_Token"),
'Accept': 'application/json'
}
payload = {
"mobile": phone_number,
"response_type": "json",
"sender_name": "23107",
"service_id": 0,
"message": "Your WiFi Voucher is " + password + ".\nAirRumi."
}
response = requests.request("POST", 'https://api.mobitechtechnologies.com/sms/sendsms', headers=headers,
json=payload)
r = response.json()
print(r)
print("SMS Sent")
print(amount)
if amount == 1:
profile = 'one_hour'
elif amount == 50:
profile = 'one_day'
elif amount == 300:
profile = 'one_week'
elif amount == 1000:
profile = 'one_month'
else:
print('Incorrect Amount')
print(profile)
connection = routeros_api.RouterOsApiPool(
host=os.getenv("ip"),
username=os.getenv("usernamee"),
password=os.getenv("password"),
port=8728,
use_ssl=False,
ssl_verify=False,
ssl_verify_hostname=True,
ssl_context=None,
plaintext_login=True
)
api = connection.get_api()
user = api.get_resource('/ip/hotspot/user')
user.add(name=password, server="hotspot1", password='1234', profile=profile)
print("User " + password + " created.")
else:
print("Payment was not successful")
context = {
"resultcode": result_code,
"resultdesc": result_desc
}
if context['resultcode'] == 0:
return JsonResponse(dict(context))
'''
I keep getting this error:
2023-01-03T13:37:23.849348+00:00 app[web.1]: Internal Server Error: /confirm
2023-01-03T13:37:23.849349+00:00 app[web.1]: Traceback (most recent call last):
2023-01-03T13:37:23.849350+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
2023-01-03T13:37:23.849350+00:00 app[web.1]: response = get_response(request)
2023-01-03T13:37:23.849353+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
2023-01-03T13:37:23.849353+00:00 app[web.1]: response = wrapped_callback(request, *callback_args, **callback_kwargs)
2023-01-03T13:37:23.849354+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
2023-01-03T13:37:23.849354+00:00 app[web.1]: return view_func(*args, **kwargs)
2023-01-03T13:37:23.849354+00:00 app[web.1]: File "/app/Splash/views.py", line 184, in confirmation
2023-01-03T13:37:23.849355+00:00 app[web.1]: api = connection.get_api()
2023-01-03T13:37:23.849355+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/routeros_api/api.py", line 45, in get_api
2023-01-03T13:37:23.849355+00:00 app[web.1]: self.socket = api_socket.get_socket(self.host, self.port,
2023-01-03T13:37:23.849355+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.10/site-packages/routeros_api/api_socket.py", line 16, in get_socket
2023-01-03T13:37:23.849356+00:00 app[web.1]: api_socket.connect((hostname, port))
2023-01-03T13:37:23.849356+00:00 app[web.1]: TypeError: str, bytes or bytearray expected, not NoneType
2023-01-03T13:37:23.849807+00:00 app[web.1]: 10.1.14.110 - - [03/Jan/2023:13:37:23 +0000] "POST /confirm HTTP/1.1" 500 75776 "-" "Apache-HttpClient/4.5.5 (Java/1.8.0_251)"
2023-01-03T13:37:23.849768+00:00 heroku[router]: at=info method=POST path="/confirm" host=airrumi.herokuapp.com request_id=2cb1aad4-7a83-43ce-a942-005d2cf64be9 fwd="10.184.18.139,196.201.214.200" dyno=web.1 connect=0ms service=454ms status=500 bytes=76092 protocol=https
I have no idea where am messing up, because my test page is connecting perfectly and creating the user in mikrotik. Below is my test.py '''
# generate usernames
import secrets
import os
import routeros_api
from dotenv import load_dotenv
load_dotenv()
password_length = 5
password = secrets.token_urlsafe(password_length)
print(password)
amount = 1
if amount == 1:
profile = 'one_hour'
elif amount == 50:
profile = 'one_day'
elif amount == 300:
profile = 'one_week'
elif amount == 1000:
profile = 'one_month'
else:
print('Incorrect Amount')
print(profile)
connection = routeros_api.RouterOsApiPool(
host=os.getenv("ip"),
username=os.getenv("usernamee"),
password=os.getenv("password"),
port=8728,
use_ssl=False,
ssl_verify=False,
ssl_verify_hostname=True,
ssl_context=None,
plaintext_login=True
)
api = connection.get_api()
user = api.get_resource('/ip/hotspot/user')
user.add(name=password, server="hotspot1", password='1234', profile=profile)
print("User " + password + " Created.")
'''