Git Product home page Git Product logo

noebs's Introduction

CI Keeping' it simple

noebs

Keepin' it simple

Open source payment gateway that implements all of EBS services.

About this project

noebs has grown from a small side-project to a production system that is used by more than 5 payment companies in Sudan.

This is an e-payment gateway system. It implements most of EBS's services with clear emphasis on scalabilty and a maintainable code. It is written in Go, a language for building high performant systems. It is also open source, the way any serious project should be. I wrote this software while I was learning Go, I tried to write an idiomatic Go as much as possible.

It is open source and it will remain open source. I will also maintain it and I welcome any contributors help me doing that as well. Our blog post covers some other aspects about this project.

Why this project

There are many reasons why I started this project. On one hand people can happily rely on EBS MCS webservices to run e.g., a POS. But this is not the goal of this project. I have a vision for the e-payment ecosystem in Sudan, way more beyond the 1SDG purchase fees.

  • a middleware for a many is major entry burden. Well, you have a free one now.
  • having a strong e-payment ecosystem will benefit all of us.

How to use noebs

You can contact us directly at [email protected] for more available hosting options.

There are different ways to use noebs:

Building with go get command [not recommended]

  • make sure you have Go installed (Consult go website to see various ways to install go)[https://golang.org]
  • Then
# this command may likely takes along time depending on your internet connections.
# also, make sure you are using a vpn since some of the libraries are hosted in GCE hosting which forbids Sudan
$ go get github.com/adonese/noebs
$ cd $GOPATH/github.com/adonese/noebs
$ go build .

You will have a binary that after running it will spawn a production ready server!

Building using Docker and docker-compose

We provide an easier way to build and run noebs using Docker.

  • Fork this repository (e.g., git clone https://github.com/adonese/noebs)
  • cd to noebs root directory (E.g., $HOME/src/noebs)
  • docker build -t noebs . # -t for giving it a name
  • docker run -v /home/adonese/src/noebs:/database -p 8080:8080 -it noebs:latest # This is recommended to mount the sqlite3 database
  • Open localhost:8000/test in your broswer to interact with noebs

Notes on installation

noebs needs to be connected with EBS merchant server in order to get useful responses. However, you can run our embedded server that mocks EBS responses in cases where you cannot reach EBS server. To do that, you need to enable the development mode using a special env var, EBS_LOCAL_DEV. You need to set EBS_LOCAL_DEV=1 in order to use the mocking functionality.

  • Using Docker
`docker run -it -p 8000:8000 -e EBS_LOCAL_DEV=1 noebs:latest`
  • Using go get method
$ export EBS_LOCAL_DEV=1 noebs

This project philosophy

noebs is not meant to be a full e-payment framework (e.g., unlike Morsal). It is meant as a generic e-payment gateway system. Currently, it implements EBS services, but we might add new gateway. Being such, adapts to Unix philosophy; doing one thing and do it good. Also, with our experience with embedded devices, working with authorizations and handling all of these headers and tokens (esp. JWT ones) has proven to be challenging as simply some of the older models cannot handle lengthy headers. You can however have this system architecture, suppose that you're building a mobile payment application system:

  • a mobile application app (with its backend system, obviously). This app will encapsulates the business logic and authenticate the incoming requests.
  • a chatting service. Like WeChat, where people can send their money to their friends and families, in a very friendly way.
  • ecommerce platform. The idea is not just to offer an epayment gateway, well, EBS offers that through their MCS web services.
  • and finally the payment gateway layer which handles the payment part.
  • there could be other services e.g., push notifications, SMS, 2FA and plenty of others.
  • logging and the reporting system.
  • rate limiting, geographical blocking and other API gateway protections. All of these will be implemented in a microservice archiectural design pattern, and it is your decision to choose what services you want. A mobile payment provider can use our payment service inside their application whenever their users are requesting any transactions. It is not our responsibility to authenticate your users. This way, we can use this application in virtually any place. Our client consumers are held responsible for providing any kind of authentication for their requests.

Services we offer

noebs implements ALL of EBS merchant services. We are working to extend our support into other EBS services, e.g., consumer services, TITP, etc. However, those other services are not stable and some of them (consumer) are deem to deprecation.

If YOU are interested in other services, please reach out and we will be more than happy to discuss them with you.

Consultancy

While everything you see here is very and open source; we don't hide any fees or charges, we expect that some might be interested in a commercial plans. We offer our consultancy services via Gndi. We have a team with variety of proficiency, from backend engineers, mobile developers to UX/UI and QA testing engineers. Some of our team members have worked at EBS, while most of the team have a huge experience in e-payment systems.

Contact us: +249 111493885 (Mohamed Yousif) | +249 9023 00672 (Mohamed Gafar) | [email protected] (Mohamed Yousif)

Our simulator and EBS services

Our team have developed an internal EBS QA test system that emulates EBS test environment. We offer our simulator as a paid service

  • very superior to that of EBS testing server. It runs on weekends. Well, 24/7, just like any server should work ¯\_(ツ)_/¯.
  • hate EBS's bureaucracy? We do too. No need for the EBS busy servers, you can test our server at any time.
  • we have two plans for the simulator:
    • you can use our EBS simulator on your own; we won't test your services.
    • we can use our EBS simulator while we do the plan for you, the exact way EBS does. Bear in mind that our testers are highly competitive and they're all ex-EBSers.

We plan on releasing our simulator very soon. Stay tuned.

Corporate sponsorship

We are extremely very gratitude to our sponsors:

  • ACTS
  • SolusPay
  • G&I Engineering

Companies that are using noebs

noebs powers and is used by these companies to process their payments:

  • ACTS
  • SolusPay
  • PACT
  • CAT
  • Sahil Ltd.
  • Tuti Tech Investment

Docs

More documentations can be found through Noebs Docs. Merchant documentations can be found here.

FAQ

  • Why is the name? For no reason really. It is just the first name that came into my mind.
  • Why open source? Open source is nice! Yeey! We love open source.
  • Why Go? I was trying to learn it for awhile and I never get to actually do something useful with it. I've started this project with Python, using a framework called Sanic (very fast, Flask compatible microframework). Then I stumbled on the request validations issue:
    • i either have to write my own validation schema
    • or, just adapt another technology. I opted to the second one. Go is cool!
  • Commitment to this project? I'm very committed to this project.

Sample for .secrets

{
    "jwt_secret": "my_top_secret",
    "db_path": "/database/test.db",
    "is_consumer_prod": false,
    "redis_port": "100.89.231.117:6379",
    "sms_gateway": "endpoint",
    "sms_key": "key==",
    "sms_sender": "tutipay",
    "sentry": "",
    "port": ":8080",
    "consumer_qa_id": "YourConsumerID",
    "merchant_qa_id": "YourConsumerID",
    "consumer_prod_id": "",
    "merchant_prod_id": "",
    "pan": "",
    "exp_date": "",
    "pin": "",
    "ipin": "",
    "cors": ["noebs.dev", "api.2t.sd", "staging.app.2t.sd", "beta.app.2t.sd"],
    "is_debug": false
}

noebs's People

Contributors

adonese avatar dependabot-preview[bot] avatar mseltahir avatar razanmedani avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

noebs's Issues

Allow for sending message on card transfer

it makes perfect sense to send a user's message on card transfer request. This should also not change the payment api itself--the payment api needs to be completely isolated from this logic.

APIs affected

This will affect consumer api only; nothing needs to be changed for the merchant.

Proposed solution

TODO

Document the APIs

This is a very must! I have to get my head into this and start seriously documenting the API.

Dependabot couldn't find a go.mod for this project

Dependabot couldn't find a go.mod for this project.

Dependabot requires a go.mod to evaluate your project's current Go dependencies. It had expected to find one at the path: /go.mod.

If this isn't a Go project, or if it is a library, you may wish to disable updates for it from within Dependabot.

You can mention @dependabot in the comments below to contact the Dependabot team.

build a new mobile number service provider guesser

We often need to figure out the mobile number service provider, we use heuristics such as the prefix to figure out what it is.

This service will be built on top of cashqbot mobile guesser, but we will need to add:

  • a service to check for relevant ebs response (wrong biller, wrong service provider, etc check ebs docs)
  • this service will first use the prefix (from cashqbot implementation), and given the response it will refine its results
  • this service could be done in our microservices code, not noebs

Dependabot can't resolve your Go dependency files

Dependabot can't resolve your Go dependency files.

As a result, Dependabot couldn't update your dependencies.

The error Dependabot encountered was:

github.com/ugorji/[email protected]: reading github.com/ugorji/go/go.mod at revision v1.1.5-pre: unknown revision v1.1.5-pre

If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.

View the update logs.

Dependabot couldn't find a go.mod for this project

Dependabot couldn't find a go.mod for this project.

Dependabot requires a go.mod to evaluate your project's current Go dependencies. It had expected to find one at the path: /go.mod.

If this isn't a Go project, or if it is a library, you may wish to disable updates for it from within Dependabot.

You can mention @dependabot in the comments below to contact the Dependabot team.

Dependabot couldn't find a go.mod for this project

Dependabot couldn't find a go.mod for this project.

Dependabot requires a go.mod to evaluate your project's current Go dependencies. It had expected to find one at the path: /go.mod.

If this isn't a Go project, or if it is a library, you may wish to disable updates for it from within Dependabot.

You can mention @dependabot in the comments below to contact the Dependabot team.

id is not a url, it should be used to inquire about payeers URL

ID is really just a unique id we assign to each transaction for each payeer. We need to inquire for the fully qualified UUID. Since each payeer will have different ids.

payee_id_key: set(ids)
payee = get_payee_key(id)
url = get_url_for_payee(payee)

And return it in the billerForm struct

Fix the response API, or unify it and make it sane

Currently the response messages are really messy and I highly rely on HTTP response codes to indicate to the clients what went wrong. I don't like it this way.
For error messages, I'm thinking about this: {"error_code": some_error_code, "error_message": "some_error_message}. Know that this have many variants. For validation errors, it will be a list of error_code, error_message.

Also, what is the kind of errors are we having. I'm thinking of validation errors and ebs errors.

Make support for browser cookies

currently our apigateway only supports jwt tokens, which while very well and served as pretty good on non browser clients, suck on the browser

Zain infrastructure is not stable

We better made an internal service that always checks EBS status and accordingly:

  • either change dns (api.noebs.dev, beta.noebs.dev)
  • or configure nginx to load balance betwee api.noebs.dev, beta.noebs.dev

Add OpenAPI adapter to our endpoint

This is important as it will help us in

  • documenting our APIs. The same OpenAPI schema can be used to document the endpoint.
  • it is really really nice though. Just do it.

Loosen coupling between Domain layer and external infrastructure

Low test coverage as a symptom of tight coupling

I noticed that the test coverage is quite low on this project, which may not be a massive problem early on - but can have a massive impact on how maintainable the project will be long term. Without tests it's very hard add new features/refactor with any degree of confidence that they will work/not break existing functionality.

I suspect that one of the reasons that there is currently low test coverage is that the project is currently difficult to test, such as below, where the redisClient is being pulled into the function:

https://github.com/adonese/noebs/blob/34343c571d8d473e26d0f358b426920b93076ddf/cards/cards.go#L180

A Suggestion

Decoupling your domain layer from external infrastructure makes it easier to test your application. Your core code shouldn't care if the data is being stored on Redis, Postgres, Cassandra, or even in memory on the same instance - it should be easy to swap in different storage drivers. This makes it easier to test with an in memory database, and gives you the flexibility to one day move away from Redis, if for example Redis can no longer support the volume of traffic your application handles.

Some great resources that helped me to understand this better:

Interfaces in Golang are very useful for accomplishing this looser coupling

A well designed, well tested application can also increase trust in a project, helping to drive adoption. I hope this is useful - and it goes without saying that time permitting I'm happy to help.

Decouple noebs from its implementation

In #26, the suggestion was to loosen the coupling between the system components, as that will help in testing.

One of the core issues related to #26 is that there is no clear distinction between noebs the library and the implementation. We must give our users interfaces for noebs functionalities.

  • move any of the functionalities that is used in our routers into exported functions (so that others, who don't want our implementation to use these helper functions)
  • slowly move ebs_service and the rest of main functions into a new package (preferably outside of noebs package)
  • noebs should be a package and all of its implicit toolings and magics be exposed to other uses

This decoupling will:

  • make testing noebs-the-library more easier
  • delegate testing the routes to the implementer
  • the only untestable part will be in EBSClient

Dependabot can't resolve your Go dependency files

Dependabot can't resolve your Go dependency files.

As a result, Dependabot couldn't update your dependencies.

The error Dependabot encountered was:

github.com/ugorji/go/[email protected]: reading github.com/ugorji/go/codec/codec/go.mod at revision codec/v1.1.5-pre: unknown revision codec/v1.1.5-pre

If you think the above is an error on Dependabot's side please don't hesitate to get in touch - we'll do whatever we can to fix it.

View the update logs.

Use a pointer in var res EBSSuccessfulResponse in handlers

To make the mocking server works, we need to modify the logic in our handlers in this way:

var res EBSResponse

=>

var res *EBSResponse

that way we will make sure to update the pointer not a new copy.
In EBSHTTPClient, we actually use a pointer receiver now.

missing Libraries or package

hello ,
i try test this system on my local machine
so i see this missing:
package noebs/dashboard
and noebs/validations
in .gitignore you put noebs file or package

I am not an expert in this language (gO lANG).

may can you writ some documentation :) 👍

Provide log.Logger in all services instance

services here mean all of our http.Handler endpoints. Currently, they include:

  • *redis.Client
  • *db.DB
  • log.Logger

The power of struct embedding is that we can keep on adding new fields without degrading the code quality, and keeping all layers easily separable.

add websockets for chat features

a very awaited feature is to add chat support for our cashq. it will help in many regards, but it is really just a nice feature to have a chat enabled in our platforms.

*redis.Client is thread safe

*redis.Client is thread safe and therefore can be used concurrently by multiple goroutines. We are currently using different clients and it seems to be not the right way of doing it. redis/go-redis#23

make the apis ebs compatible

The idea is that we want to encourage our clients to use our middleware! Even if they don't have access to the source code.

Required changes:

  • change the response to be EBS compatible
  • change the url to map into EBS service names as well

Proposed solution:

  • use http header X-Resource-Use-EBS to indicate that the client needs their urls EBS response.

Problems:

  • the problem with the proposed solution is that we must also change the endpoints names to map into EBS such that we achieve a 100% smooth transition.

Dependabot couldn't find a go.mod for this project

Dependabot couldn't find a go.mod for this project.

Dependabot requires a go.mod to evaluate your project's current Go dependencies. It had expected to find one at the path: /go.mod.

If this isn't a Go project, or if it is a library, you may wish to disable updates for it from within Dependabot.

You can mention @dependabot in the comments below to contact the Dependabot team.

Use json.Decode instead of injecting *gin.Context.Request.Body

Instead of Copying the incoming request stream into two different buffers, it is more efficient and just the correct way.
The request body will eventually transferred into many middlewares and different layers.
stream of request -> validator -> ebs_gateway -> response -> logger -> db? -> sms_gateway, and perhaps through different services.

Use Caddy as a proxy server

We need to use a proxy server. it will help us in:

  • handling SSL certificate
  • handling static files
  • proxying to different instances running as we want to add another EBS compatible layer

Separating the layers

We have different layers in noebs, and it is very wise that each one of them should be isolated from the others:

  • merchant apis
  • consumer apis
  • merchant dashboard
  • consumer user's services
    that will allow for smooth and safe deployment for these layers, as a change in consumer services, should not trigger a whole system build.

also, it is evident that the development on dashboard and consumer services will be more active than in the payment ones.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.