This is a clone of Fawry, an e-payments and digital finance solution in Egypt.
There are two types of users who can use this system:
- Normal user
- Admin
This user can pay for the services provided by the different service providers in the system. They have a wallet which they can use in payment, and they can issue refund requests for the payment transactions they make.
This user can respond to refund requests made by normal users, they can add discounts to the available services, and see all recorded transactions.
- Users and admins can sign up using an email, a username and a password.
- Users can search for service providers.
- Users can pay for services.
- Users can make refund requests.
- Users can add funds to their wallet.
- Admins can add discounts to services.
- Admins can see all transactions made by normal users.
- Admins can respond to refund requests made by normal users.
The whole system is divided into 7 main subsystems:
- The authentication subsystem
- The payment subsystem
- The service providers subsystem
- The refunds subsystem
- The wallet subsystem
- The discounts subsystem
- The transactions subsystem
Each subsystem has one minimal and clear goal that it achieves by exposing its functionality through a bunch of REST endpoints.
Each subsystem is contained in a package designed in the following manner:
classDiagram
class Controller {
-repository: Repository
+endpoint()
}
class Repository {
<<interface>>
+create()
+read()
+update()
+delete()
}
Controller o--> Repository
class InMemoryRepository {
-data: List
+create()
+read()
+update()
+delete()
}
Repository <|.. InMemoryRepository
class Model {
-field: Object
}
InMemoryRepository *-- Model
The package common
as its name suggests contains
all classes used by multiple controllers, such as exception
and exception handling classes,
and the input validation class Validator
.
Initially, there are 3 service providers:
- WE
- Vodafone
- Etisalat
For every service, no matter it's type (e.g. donation, landline, etc.)
there will be a concrete
class that extends the ServiceProvider
abstract class
and declares all the inputs it needs to provide its services.
A developer can easily add a new service provider by following the simple steps below:
- Go to the package
eg.edu.cu.fcai.swe.fawry.provider.providers
. - Create a new class for the new provider to be added.
- Make the provider class extend the
ServiceProvider
class. - Create a constructor that takes the following parameters:
String id
String name
and pass them to the super(String id, String name)
constructor call.
The id
should be unique across all service providers.
The name
is the service name that end users will see when
they are searching for service providers.
- Implement the
boolean handle(Map<String, Object> paymentForm)
method.
Put all checks on the required form fields
(found in paymentForm
) here, and of course,
the calls to the service provider's API.
This system implements an actual authentication system, so when you create a user account or an admin account you will get a token in return (in the response body) that you will have to put in the Authorization header of requests to protected endpoints.
The value of the Authorization header should follow this format:
Bearer <TOKEN>
where <TOKEN>
is the actual token string returned from the sign-up/in endpoint.
If you want to bypass token validation, there is a dummy user account and a dummy admin account created initially that you can use by turning on debug mode.
To turn on debug mode, follow these simple steps:
-
Go to the class
eg.edu.cu.fcai.swe.fawry.common.Validator
-
Find this line:
private static final boolean DEBUG_MODE = false;
- Change the value of
DEBUG_MODE
totrue
.
Now, you should be able to access all endpoints without the need to create user or admin accounts.
The following endpoints are protected, which means you need to be an authenticated user or admin to access them.
If the
previously mentioned
DEBUG_MODE
is set to false
, you will
need to be an authenticated admin to access the following
endpoints:
POST /discount/{{providerId}}
POST /discount
GET /refund/all
POST /refund/response
GET /transaction/all
and an authenticated user to access the following endpoints:
POST /pay/{{providerId}}
GET /wallet
POST /wallet
GET /refund/request
POST /refund/request
GET /transaction