Creating a Mock USSD Service Using Python

Creating a Mock USSD Service Using Python

ECX 30 Days of Code and Design

Day 10

USSD Bank Service

Task

Create a mock USSD service that takes users' input and provides appropriate responses.

  • Users provide a USSD code as input
  • Users can then choose among a list of options (with numbers), whether to check their balance, send money, purchase airtime, etc.
  • To check their balance, users are prompted to provide their password (hard-coded by you). If correct, they are shown the balance—also hard-coded.
  • For sending money, users are prompted to choose from a selection of banks, after which they are to provide an account number, and then an amount to send. And then a password, which if correct, would send the required amount and deduct it from their account balance.
  • Follow a similar scheme as sending money, for purchasing airtime—except that in this case, users are prompted for a phone number instead.

My Approach

This is the full code. I would explain it in bits throughout this article.

import time                         # To create a time counter to mimic transaction loading

# Customer registered details
saved_password = 1234
saved_balance = 9081726354
customer_phone = '08091234567'

# Global variables
list_of_banks = ['Gtbank', 'UBA', 'First Bank', 'Wema Bank', 'Heritage', 'Ecobank', 'Zenith Bank']
ussd_service = False
ussd = ''
bar = 5            # Number of times customer is allowed to type a wrong password

print(' Favour Bank '.center(30, '*'))

# Check for wrong USSD code and ValueError
try:
    ussd = int(input('Enter 101 to access Favour Bank USSD Service: '))
    if ussd == 101:
        ussd_service = True
    else:
        print('Invalid Request')

except ValueError:
    print('Invalid Request')

# Main Program Loop
while ussd_service is True:
    try:
        print('Choose a transaction\n'
              '1. Check Balance\n'
              '2. Send Money\n'
              '3. Purchase airtime\n'
              '4. Cancel')

        customer_choice = int(input('Enter: '))

        # CHECK BALANCE
        if customer_choice == 1:

            customer_password = int(input('Enter password: '))

            # Check for correct password
            if customer_password == saved_password:
                print('Balance:', saved_balance)

            else:
                bar = bar - 1
                print('Wrong paasword!\nYou would be barred after ' + str(bar) + ' wrong tries\n')

                if bar > 0:
                    continue
                else:
                    print('You have been barred. Visit our nearest branch to unblock your account.')
                    break

        # MONEY TRANSFER
        elif customer_choice == 2:
            bank_choice = int(input('1. Favour Bank\n'
                                    '2. Other Banks\n'
                                    'Enter: '))

            if bank_choice == 1:
                print('Favour Bank')

            if bank_choice == 2:
                print('Select bank')

                # List out all other banks from bank list
                count = 1
                for bank in list_of_banks:
                    print(str(count) + '. ' + bank)
                    count = count + 1

                bank_name = int(input('Enter: '))

                print(list_of_banks[bank_name - 1])

            print('Balance:', saved_balance)

            # Input amount to send and details of recipient
            amount_to_transfer = int(input('Enter amount: '))
            account_number = int(input('Enter account number: '))

            password_check = int(input('Enter your password: '))

            # Password check
            if password_check == saved_password:

                # Loading timer
                for i in range(5):
                    print('.', end='')
                    time.sleep(0.25)

                saved_balance = saved_balance - amount_to_transfer
                print('\n' + str(amount_to_transfer) + ' sent to ' + str(account_number))
                print('Balance:', saved_balance)

            else:
                bar = bar - 1
                print('Wrong password!\nYou would be barred after ' + str(bar) + ' wrong tries\n')

                if bar > 0:
                    continue

                else:
                    print('You have been barred. Visit the nearest branch to unblock your account.')
                    break

        # BUY AIRTIME
        elif customer_choice == 3:
            card_purchase = int(input('1. Buy card for yourself\n'
                                      '2. Buy for others\n'
                                      'Enter: '))

            phone_number = ''

            if card_purchase == 1:
                phone_number = customer_phone

            elif card_purchase == 2:
                phone_number = input('Enter phone number: ')

            else:
                print('Invalid entry!')
                continue

            card_amount = int(input('Enter amount: '))

            password_check = int(input('Enter your password: '))

            if password_check == saved_password:

                # Loading timer
                for i in range(5):
                    print('.', end='')
                    time.sleep(0.25)

                saved_balance = saved_balance - card_amount
                print('\n' + phone_number + ' has been credited with ' + str(card_amount))
                print('Balance:', saved_balance)

            else:
                bar = bar - 1
                print('Wrong password!\nYou would be barred after ' + str(bar) + ' wrong tries\n')

                if bar > 0:
                    continue

                else:
                    print('You have been barred. Visit the nearest branch to unblock your account.')
                    break

        # CANCEL USSD SERVICE
        elif customer_choice == 4:
            break

        # WRONG CHOICE INPUT
        else:
            print('Wrong input!\n')
            continue

        # PERFORM ANOTHER TRANSACTION
        # Ask if another transaction is to be carried out
        print('\nDo you want to carry out another transaction?\n'
              '1. Yes\n'
              '2. No')

        another_transaction = int(input('Enter: '))

        if another_transaction == 1:
            ussd_service = True
        else:
            print('Goodbye')
            ussd_service = False

    except ValueError:
        print('Invalid entry\n')

# TODO: Possible additions: a dictionary for each bank containing dummy account details can be created.
# When the customer types the account detail, the name on the account gets displayed.

Customer Details

First, we import the time module, which we would use to create a mock loading time for transactions. Next, we assume the customer data is already saved, thus we create variables (for the customer’s password, balance, and phone number) and assign values to them. We then create a list of banks which would pop up when the customer hopes to make a bank transfer to a beneficiary having a bank account in a bank other than Favour Bank. We create a variable, ussd_service, and assign it the Boolean value of False. It remains false until the customer types in the correct USSD numbers, which in this code is 101. We also create a variable, ussd, which would hold the USSD the customer inputs. We create a variable, bar, which determines the number of times a customer can input the wrong password. We assign it the value of 5, and it decreases each time the customer enters the wrong password.

import time        

saved_password = 1234
saved_balance = 9081726354
customer_phone = '08091234567'

list_of_banks = ['Gtbank', 'UBA', 'First Bank', 'Wema Bank', 'Heritage', 'Ecobank', 'Zenith Bank']
ussd_service = False
ussd = ''
bar = 5 

print(' Favour Bank '.center(30, '*'))

Inputting of USSD Number

Next, we check the USSD number the customer enters; if it is correct, we make ussd_service True, else we notify the customer that the number inputted is wrong. We also check for value error (i.e., the case where he inputs characters other than numbers).

try:
    ussd = int(input('Enter 101 to access Favour Bank USSD Service: '))
    if ussd == 101:
        ussd_service = True
    else:
        print('Invalid Request')

except ValueError:
    print('Invalid Request')

Available USSD Services

When the USSD number inputted by the customer is found to be true, we display the choice of transactions he can make. We make use of use of the try except block to handle value error that occurs when the customer inputs a character other than a number. We also make provision to ensure that if the user chooses a digit not among the choices provided (1 – 4), he is prompted of his wrong choice.

while ussd_service is True:
    try:
        print('Choose a transaction\n'
              '1. Check Balance\n'
              '2. Send Money\n'
              '3. Purchase airtime\n'
              '4. Cancel')

        customer_choice = int(input('Enter: '))
--snip--
        # WRONG CHOICE INPUT
        else:
            print('Wrong input!\n')
            continue
--snip--
    except ValueError:
        print('Invalid entry\n')

Checking Balance

If the customer chooses to check his balance, we ask him to input his password, which we would validate against the one already saved. If the password inputted is correct, we display his balance, else we would warn him of the incorrect password and the number of times he has to enter the right password before his account is blocked (a security measure against theft) before he is taken back to the start where the options for choice of transactions is displayed.

        # CHECK BALANCE
        if customer_choice == 1:

            customer_password = int(input('Enter password: '))

            # Check for correct password
            if customer_password == saved_password:
                print('Balance:', saved_balance)

            else:
                bar = bar - 1
                print('Wrong paasword!\nYou would be barred after ' + str(bar) + ' wrong tries\n')

                if bar > 0:
                    continue
                else:
                    print('You have been barred. Visit our nearest branch to unblock your account.')
                    break

Bank Transfer

If the customer chooses to make a bank transfer, we ask him if he wants to send money to a beneficiary within the same bank or another bank. If he chooses another bank, all banks in list_of_banks list are printed out, and he is prompted to choose the bank his beneficiary is using. The name of the bank of the beneficiary and the customer’s current balance are printed out. We then ask the customer the amount he hopes to send and the account number of the beneficiary. He is then asked for his password. If his password is correct, we create a mock loading timer to assume the transaction is ongoing, then the transaction detail is printed out and his remaining balance is displayed.

        # MONEY TRANSFER
        elif customer_choice == 2:
            bank_choice = int(input('1. Favour Bank\n'
                                    '2. Other Banks\n'
                                    'Enter: '))

            if bank_choice == 1:
                print('Favour Bank')

            if bank_choice == 2:
                print('Select bank')

                # List out all other banks from bank list
                count = 1
                for bank in list_of_banks:
                    print(str(count) + '. ' + bank)
                    count = count + 1

                bank_name = int(input('Enter: '))

                print(list_of_banks[bank_name - 1])

            print('Balance:', saved_balance)

            # Input amount to send and details of recipient
            amount_to_transfer = int(input('Enter amount: '))
            account_number = int(input('Enter account number: '))

            password_check = int(input('Enter your password: '))

            # Password check
            if password_check == saved_password:

                # Loading timer
                for i in range(5):
                    print('.', end='')
                    time.sleep(0.25)

                saved_balance = saved_balance - amount_to_transfer
                print('\n' + str(amount_to_transfer) + ' sent to ' + str(account_number))
                print('Balance:', saved_balance)

            else:
                bar = bar - 1
                print('Wrong password!\nYou would be barred after ' + str(bar) + ' wrong tries\n')

                if bar > 0:
                    continue

                else:
                    print('You have been barred. Visit the nearest branch to unblock your account.')
                    break

Airtime Purchase

If the customer chooses to buy airtime, we ask him if he wants to buy for himself (the number registered with the bank account) or for another phone number. If he chooses another, he is prompted to type the number. He is then prompted to enter the amount he wants to send and to enter his password to validate the transaction. If he enters the right password, the transaction detail and his remaining balance are displayed on the screen.

        # BUY AIRTIME
        elif customer_choice == 3:
            card_purchase = int(input('1. Buy card for yourself\n'
                                      '2. Buy for others\n'
                                      'Enter: '))

            phone_number = ''

            if card_purchase == 1:
                phone_number = customer_phone

            elif card_purchase == 2:
                phone_number = input('Enter phone number: ')

            else:
                print('Invalid entry!')
                continue

            card_amount = int(input('Enter amount: '))

            password_check = int(input('Enter your password: '))

            if password_check == saved_password:

                # Loading timer
                for i in range(5):
                    print('.', end='')
                    time.sleep(0.25)

                saved_balance = saved_balance - card_amount
                print('\n' + phone_number + ' has been credited with ' + str(card_amount))
                print('Balance:', saved_balance)

            else:
                bar = bar - 1
                print('Wrong password!\nYou would be barred after ' + str(bar) + ' wrong tries\n')

                if bar > 0:
                    continue

                else:
                    print('You have been barred. Visit the nearest branch to unblock your account.')
                    break

Cancel USSD Service

If the customer chooses to not make use of the USSD service, an option is provided to opt-out.

        # CANCEL USSD SERVICE
        elif customer_choice == 4:
            break

Perform Another Transaction

When the user is done with a transaction, we ask him if he wants to carry another transaction; if he chooses yes, ussd_service remains true and he is taken back to the start of the loop, else (if he chooses no), the loop breaks.

        # PERFORM ANOTHER TRANSACTION
        # Ask if another transaction is to be carried out
        print('\nDo you want to carry out another transaction?\n'
              '1. Yes\n'
              '2. No')

        another_transaction = int(input('Enter: '))

        if another_transaction == 1:
            ussd_service = True
        else:
            print('Goodbye')
            ussd_service = False

You would notice I placed a TODO at the end of the code. You can expand the code by creating dictionaries for the various banks and creating mock account numbers and names, so that when the user inputs the bank of the beneficiary and the account number, the name assigned to the account gets displayed.

# TODO: Possible additions: a dictionary for each bank containing dummy account details can be created.
#  When the customer types the account detail, the name on the account gets displayed.

Output

Let us check the balance of the customer.

******** Favour Bank *********
Enter 101 to access Favour Bank USSD Service: 101
Choose a transaction
1. Check Balance
2. Send Money
3. Purchase airtime
4. Cancel
Enter: 1
Enter password: 1234
Balance: 9081726354

Do you want to carry out another transaction?
1. Yes
2. No
Enter: 2
Goodbye

There you have it. I enjoyed every bit of this particular project.
Run the code on Replit
Recall: The USSD code is 101 and the password is 1234.