This project is aimed at creating the Back-End of a Bakery Marketplace that connects establishments to people crazy about breads and sweets!
We already:
- Created the endpoint of listing and creating bakeries.
- Created the endpoint of listing and creating products.
- Created the endpoint of listing and creating customers.
- Created an endpoint that creates a recipient and bank account for a bakery.
- Create an endpoint that creates a sale for the bakery.
- Integrate with the Pagarme payments API.
- Added split rule.
- Added integration tests to the current codebase.
- Document in Swagger.
Below is what was used to create this project:
- [Python] - The chosen language was Python;
- [Django] - For a clean and fast api development;
- [Django Rest Framework] - Apis development kit that implements Django and makes our implementation even more elegant;
- [Pagarme] - Payment intermediary that facilitates transactions carried out;
- [Swagger] - API documentation tool
- Get Python
- register with paying for a test account at this link -> https://dashboard.pagar.me/#/login
- update your .env with its 'PAGARME_CHAVE_API' and 'PAGARME_RECIPIENT_ID' values
- go to the source 'cd .\briochefood\src'
- run 'pip install -r requirements.txt'
- run 'python manage.py migrate'
- run 'python manage.py runserver'
- Enjoy!
The flow to be followed is as follows
- create customer
- create bakerie
- create product
- create recipient and bank account
- create sale
We have the following routes below, but you can also check them on Swagger at this link 'https://app.swaggerhub.com/apis/Dianna-coder/BriocheFood/1.0.0'
We expect the input to be a json like this
{
"name": "Pirate Customer 2",
"email": "pirate@customer.com",
"cpf": "44699109888",
"phone_number": "11938485966",
"birthday": "2001-02-02",
"country": "BR",
"state": "SP",
"city": "Taboao da Serra",
"neighborhood": "Av aaa",
"street": "Av aaaa",
"street_number": "10000",
"zipcode": 6787360
}
Our successful creation output will be (201)
[
{
"id": "2fefb2bf-7182-4346-b49c-7de349cbd9c6",
"name": "Pirate Customer 2",
"email": "pirate@customer.com",
"cpf": "44699109888",
"phone_number": "11938485966",
"birthday": "2001-02-02",
"country": "BR",
"state": "SP",
"city": "Taboao da Serra",
"neighborhood": "Av aaa",
"street": "Av aaaa",
"street_number": "10000",
"zipcode": 6787360
}
]
We expect the input to be a json like this
{
"cnpj": "33095101000142",
"name": "Bread Bakery",
"address": "Av bakery"
}
Our successful creation output will be (201)
{
"id": "9575e89d-cb36-4da3-add5-613074795778",
"cnpj": "33095101000142",
"name": "Bread Bakery",
"address": "Av bakery",
"recipient": null
}
We expect the input to be a json like this
{
"title": "Bread",
"unit_price": "10000",
"quantity": 1000,
"bakery": "9575e89d-cb36-4da3-add5-613074795778"
}
Our successful creation output will be (201)
{
"id": "ffd32a1b-e784-4166-bb0f-5613c55d91c4",
"title": "Bread",
"unit_price": "10000",
"quantity": 1000,
"bakery": "9575e89d-cb36-4da3-add5-613074795778"
}
We expect the input to be a json like this
{
"transfer_day": "5",
"transfer_interval": "weekly",
"bank_account": {
"agencia": "0932",
"agencia_dv": "5",
"bank_code": "341",
"conta": "58054",
"conta_dv": "1",
"document_number": "26268738888",
"legal_name": "HOUSE TARGARYEN"
}
}
Our successful status output will be (200)
Recebedor e conta bancária criados!
We expect the input to be a json like this
{
"amount": "10000",
"payment_method": "credit_card",
"card_number": "4111111111111111",
"card_cvv": "123",
"card_expiration_date": "0922",
"card_holder_name": "Morpheus Fishburne",
"customer": {
"external_id": "2fefb2bf-7182-4346-b49c-7de349cbd9c6",
"name": "Arroz de teste",
"type": "individual",
"country": "br",
"email": "mopheus@nabucodonozor.com",
"documents": [
{
"type": "cpf",
"number": "30621143049"
}
],
"phone_numbers": ["+5511999998888", "+5511888889999"],
"birthday": "1965-01-01"
},
"billing": {
"name": "Trinity Moss",
"address": {
"country": "br",
"state": "sp",
"city": "Cotia",
"neighborhood": "Rio Cotia",
"street": "Rua Matrix",
"street_number": "9999",
"zipcode": "06714360"
}
},
"shipping": {
"name": "Arroz de teste",
"fee": "1000",
"delivery_date": "2000-12-21",
"expedited": true,
"address": {
"country": "br",
"state": "sp",
"city": "Cotia",
"neighborhood": "Rio Cotia",
"street": "Rua Matrix",
"street_number": "9999",
"zipcode": "06714360"
}
},
"items": [
{
"id": "9dd2b3cf-9e1b-4927-9cd7-24aa85a61a83",
"title": "Red pill",
"unit_price": "10000",
"quantity": "1",
"tangible": true
},
{
"id": "1b989eb3-4ca1-4c9d-97e5-38058984679d",
"quantity": "1",
"title": "Blue pill",
"unit_price": "10000",
"tangible": true
}
]
}
Our successful status output will be (200)
Compra realizada!
Our validation error output (400)
{
"name": [
"This field is required."
]
}
Output on server error (500):
HTTP 500 INTERNAL SERVER ERROR
- run
python manage.py test
The architecture follows the MVT standard proposed by Django Rest Framework, in addition I separated the project into modules
- On the first level we concentrated the project on the src and I shared two major responsibilities which are "bakeries" and "customers".
- We have a global folder of utils where I can put providers or other utilities.
- We have examples of json to make requests.
- And the rest of the level concerns the project's settings and database.
briochefood
├── src/
│ ├── bakeries/
│ ├── customers/
│ ├── requests_examples/
│ ├── utils/
│ ├── manage.py
│ ├── requirements.txt
│ ├── urls.py
│ └── wsgi.py
└── db.sqlite3
- In each module we have the migrations and models to create the SQL tables, we have their tests, serializers, routes and views with the implementation of the endpoints.
- In utilities I have the methods and rules related to Pagarme's api.
- I added use cases to separate part of the View logic and to help with tests that make external calls.
briochefood
├── src/
│ ├── bakeries/
│ │ ├── migrations/
│ │ ├── tests/
│ │ ├── use_cases/
│ │ ├── validators/
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── serializer.py
│ │ ├── urls.py
│ │ └── view.py
│ ├── customers/
│ │ ├── migrations/
│ │ ├── tests/
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── serializer.py
│ │ ├── urls.py
│ │ └── view.py
│ ├── requests_examples/
│ │ ├── bakery_create.json
│ │ ├── customer_create.json
│ │ ├── product_create.json
│ │ ├── recipient_and_bank_create.json
│ │ └── sale_create.json
│ ├── utils/
│ │ └── pagarme/
│ ├── manage.py
│ ├── requirements.txt
│ ├── urls.py
│ └── wsgi.py
└── db.sqlite3