# Third party trustee : PayPouz™ by CreditRama
## Description du projet
Ce projet consiste en la réalisation d'une plateforme permettant d'instaurer un tiers de confiance dans le cadre d'achats et/ou de ventes à distance.
Ce service ajoute un intermédiaire chargé de vérifier la validité des transactions ainsi que la bonne réception du colis par l'acheteur. Le vendeur reçoit son argent une fois le colis réceptionné par l'acheteur.
<center>
<img src="https://paypouz.com/assets/images/global-project.png">
</center>
## Conception
### 1 : User Case
#### Acteurs :
- CreditRama Banque
- PayPouz™ Service
- Transporteur
- Vendeur
- Acheteur
#### Cas d'utilisations :
- **1** Cas classique:
- Le vendeur peut créer une nouvelle transaction, PayPouz™ lui renvoie donc un identifiant de transaction unique PayPouzId
- Le vendeur transmet l'identifiant PaypouzId à l'acheteur qui pourra effectuer le paiement
- Le vendeur peut vérifier que l'acheteur à bien payé via l'identifiant PayPouzId
- Le vendeur doit spécifier un transporteur ainsi qu'un numéro de livraison à PayPouz™ une fois la transaction payée par l'acheteur
- PayPouz™ peut vérifier l'état de la livraison via le numéro de colis transmit par le vendeur
- PayPouz™ demande à CrediRama le transfert du paiement au vendeur une fois le colis livré
- Un acheteur ne communique jamais ses informations de paiement à un vendeur
- PayPouz™ possède un compte chez CrédiRama dans lequel il va stocker l'argent de l'acheteur le temps que la livraison soit effectuée. Une fois la livraison effectuée, Paypouz™ aura la possibilité de débiter son compte en faveur du vendeur ou de l'acheteur en cas de litige avéré.
- **2** Cas critique :
- PayPouz™ a la possiblité de renouveler une demande de transfert de paiement auprès de CrédiRama vers le vendeur
- L'acheteur a la possibilité de re-rentrer ses informations de paiement à postériori dans le cas où la connexion avec la banque serait perdu ou le paiement refusé.
- Dans le cas où le transporteur perd sa connexion avec les services de PayPouz™, le transporteur a la possibilité de stocker ses notifications en attente pour un renvoie ultérieur
- **3** Cas de litige : (Ouverture possible)
- L'acheteur a la possibilité de créer des litiges en cas de non/mauvaise reception du colis
- Le vendeur a la possibilité de créer des litiges en cas de mauvais paiement
- PayPouz™ a la possibilité de vérifier avec le livreur l'authenticité et l'état de la livraison actuelle ou antérieure
- Le livreur stock pour une durée indéterminé l'historique de ses livraisons
- PayPouz™ peut faire des vérifications auprès de la plateforme (article acheté, quantité, etc)
- PayPouz™ a la posssibilité de notifier les deux parties du litige
- PayPouz™ a possibilité de rembourser l'acheteur en cas de litige gagnant pour ce dernier
### 2 : Diagramme des composants
<center>
<img src="https://paypouz.com/assets/images/user-case.png">
</center>
### 3 : Diagramme des routes
<center>
<img src="https://paypouz.com/assets/images/routes2.svg">
</center>
### 4 : Diagramme interne
<center>
<img src="https://paypouz.com/assets/images/inside-paypouz-diagram.svg">
</center>
#### Les controlleurs
- Le Seller a accès à l'API **SellerAPI** pour la demande de génération de *PayPouzID*, la demande de l'état de sa transaction ainsi que le renseignement du *trackingID* une fois le colis envoyé
- Le buyer a accès à l'API **BuyerAPI** pour le paiement de transaction via son *PayPouzID*
- CréditRama a accès à une **interface de notifications** à PayPouz sur les états des transferts bancaires (interface pas encore définie, mail?, RSS?, autre ?)
- Le Transporteur a accès à une **interface de notifications** sur les changements de status pour des *trackingId*s définis au préalable (interface pas encore définie, mail?, RSS?, autre ?)
#### Les Services
- Le **PayPouz™ Transaction Service** est là pour la gestion de toutes les transactions liées à des *PayPouzID*
- Le **Bank Transfer Service** est là pour gérer et générer des transferts bancaires entre l'acheteur et CrédiRama ainsi qu'entre CrédiRama et PayPouz™
- Le **Tracking Service** est là pour la gestion de la livraison du colis, en cas de changement de statut de livraison il est chargé de le communiquer au *PP Transaction Service*.
## Roadmap & Plan
### Roadmap
- **Slice 1 :** Le vendeur peut demander la génération d'une transaction à PayPouz™. PayPouz™ lui transmet un PayPouzID. Le vendeur le transmet par la suite à l'acheteur qui peut renseigner/autoriser le paiement.
- **Slice 2 :** Mockage des différents acteurs externes (vendeur, acheteur, banque, transporteur)
- **Slice 3 :** Changement d'architecture, les acteurs externes ne sont plus simulés par un module externe mais directement dans les tests cucumber. Mise en place d'un scénario simple : un vendeur vend un article à un acheteur, crédirama effectue les mouvement de fonds, le transporteur notifie de la livraison. La transaction est instantanée et valide, il n'y aucun litige possible.
- **Slice 4 :** Gestion de certains cas de litiges :
- Le vendeur n'envoie jamais le colis.
- L'acheteur n'envoie jamais l'argent.
- L'acheteur n'a pas suffisament d'argent sur son compte.
### Plan
Nous prévoyons de dispatcher nos Slice en Sprints d'une durée d'une semaine.
## Implementation du POC
### 1 : Architecture
Le diagramme interne a été très peu modifié durant l'implementation. En effet, l'architecture est globalement la même à l'exception des répositories que nous avons regroupé en un seul avec une base de donnée extrêmement simple.
<center>
<img src="https://paypouz.com/assets/images/paypouz2.svg">
</center>
<p>
</p>
Nous avons décidé d'implémenter Paypouz sous la forme d'une application monolithique car cela:
<ul>
<li>simplifie le développement et permet d'être moins dépendant du réseau (important dans notre cas car on veut une application la plus robuste possible), en effet les différents services internes à notre application communiquent simplement par des appels de méthodes</li>
<li>simplifie le test, par exemple pour tester fonctionnellement notre API il suffit de la lancer et de tester ses points d'entrée, au lieu de lancer chaque service et tester chacun de leur points d'entrée dans le cas de microservices</li>
<li>simplifie la mise à l'échelle, il suffit de lancer plusieurs copies de l'application avec un load balancer</li>
<li>simplifie le déploiement</li>
</ul>
De plus nous ne pourrions pas tirer pleinement parti des avantages apportés par une architecture micro-service dans le cadre de notre application. En effet la complexité apportée par l'implémentation et la mise en place des piles technologiques requises pour les différents services serait trop importante par rapport aux bénéfices apportés. En effet la logique métier de notre application étant simple, l'implémenter en fragmentant l'application en micro-services qui seraient vraiment trop petits et simplistes pour justifier toute la mise en place que nécessite une architecture micro-service serait une erreur.
De plus ce type d'architecture apporterait de la complexité du point de vue de la sécurité et gestion de la cohérence des données entre les différents services, qui sont tous deux des points critiques car nous déployons notre application en tant que tier de confiance pour des transactions bancaires.
#### Utilisation de Java Spring
Nous avons utiliser Spring car nous connaissons le framework et qu'il nous a permit d'avancer très vite vers le poc désiré. En effet, dans notre équipe, nous avons tous fait au moins une fois du Spring et avons tous fait un projet plus ou moins complexe avec ce framework.
#### Utilisation du REST
Le choix du REST à l'in
### 2 : Base de donnée
#### Type de base de donnée
Nous avons choisi d'utiliser une base de donnée MySql. Nous avons choisi du sql et non du nosql par rapport au secteur dans laquel notre application va évoluer. En effet, l'environnement des transactions est un environnement très sensible dans lequel le moindre incident peut avoir des conséquences majeures. En effet, en temps que troisième partie de confiance, nous fonctionnons grâce à la confiance de nos utilisateurs. Le problème du nosql étant la possibilité d'avoir de la duplication de donnée, de la corruption ou encore une possibilité très minime, mais certes présente, d'avoir des résultats aléatoire.
#### Sauvegarde des données
Nous avons mis en place des sauvegardes de la base de données de façon automatique toujours dans l'objectif d'apporter un service fiable et de confiance à nos utilisateurs.
<center>
<img style="width:400px" src="https://i.imgur.com/brBTrcn.png">
</center><br>
Actuellement nous avons une sauvegarde à chaque changement d'état mais nous pouvons prévoir plus large avec une sauvegarde journalière par exemple.
#### Conception de base de donnée
##### Les champs
Nous avons choisi pour le moment une architecture de base de donnée simple pour notre première version du POC. Nous évitant de perdre trop de temps sur la conception de cette dernière. Cette version ne prend donc pas en considération les règles de normalisation de base de données (NF) mais pourra être modifiée dans le futur pour les prendre en compte.
<center>
<img style="width: 245px" src="https://paypouz.com/assets/images/datatable.png">
</center><br>
La base de donnée actuelle contient donc :
- **Un champ ID :** Sa valeur étant une clef unique composée d'entiers (Int 11). Dans notre architecture, ce champ représente notre PayPouzID
- **Un champ vendorIBAN :** Sa valeur étant textuelle (varchar 255) et pouvant être de valeur null. Dans notre architecture, ce champ représente l'iban du vendeur a créditer une fois une transaction complètement vérifiée par PayPouz.
- **Un champ buyerIBAN :** Sa valeur étant textuelle (varchar 255) et pouvant être de valeur null. Dans notre architecture, ce champ représente l'iban de l'acheteur qui est rentré par ce dernier lors de l'achat. Nous le gardons en cas de litige, nous permettant de rembourser l'acheteur.
- **Un champ amout :** Sa valeur étant composé d'un entier à virgule (double) permettant, dans notre architecture, de représenter le prix de la transaction.
- **Un champ state :** Sa valeur étant textuelle (varchar 255). Dans notre architecture, ce champ représente l'état courant d'une transaction, qui peuvent être :
- NEW : Toute nouvelle transaction
- PENDING_AUTHORIZE_PAYMENT : Toute transaction en attente de paiement de la part de l'acheteur
- PENDING_TRACKING_NOT_SET : Toute transaction en attente d'envoie de la part du vendeur (avec donc un trackingID)
- PENDING_IN_TRANSIT : Toute transaction en transit via le transporteur
- DELIVERED : Toute transaction étant livrée
- PENDING_BANK_TRANSFER : Toute transaction en attente d'un transfert banquaire. Notamment en attente de CrédiRama.
- PENDING_REFUND_TRANSFER : Toute transaction en de remboursement. Notamment lors d'ouverture de litige par l'acheteur par exemple.
- CLOSED : Toute transaction traitée et terminée.
- **Un champ tranckingID :** Sa valeur étant textuelle (varchar 255) et pouvant être de valeur null. Dans notre architecture, ce champ représente le numéro de suivi du transporteur pour le colis dont la transaction découle.
##### Le versionning
Pour la validité et la montée en version simplifiée de notre application, nous avons mis en place un système de versioning au niveau de notre base de donnée. Nous avons donc intégré **liquibase** qui est un outil open source pour la gestion des modifications et du déploiement de bases de données. Nous intégrons notamment un fichier au format XML dans nos ressources permettant à liquibase de vérifier la base de donnée et de la mettre à jour en cas de non cohérence des données.
#### Changement à prévoir
Dans le futur, nous pouvons envisager d'externalisé le champ state dans une autre table avec un lien par clef étrangère sur des state Ids pour une meilleur normalisation de la base de donnée. Nous pouvons aussi modifier le PayPouzId en varchar pour permettre la création de token unique beaucoup plus sécurisés que de simple id entiers.
### 3 : Test et Scenario
Nous avons mis en place la vérification des scénarios via nos tests, et notamment via nos tests **Cucumber**. Ceci nous permet de décrire nos scénario et de les faire dérouler en language naturelle avec de simple Given, When et Then.
Exemple avec notre premier scénario :
<center>
<img src="https://paypouz.com/assets/images/tests.png">
</center><br>
Nous voyons notamment chaque acteur avec le déroulement de notre scénario. Pour lancer les scénarios, nous avons mis à disposition un script sh dans la base du projet nommé run.sh
## Organisation du projet
### Intégration Continue
Nous avons mis en place un travis assez simple dans lequel nous exécutons les tests unitaires ainsi que les scénarios. Nous exécutons notamment notre travis pendant chaque nouvelle pull-request avant merge sur branche master pour garder la branche master la plus propre possible. En effet, ayant une branche par sprint, nous faisons un merge final sur la branche master à chaque fin de sprint via pull-request.
### Kanban et issue
Dans le cadre d'une meilleure communication dans l'équipe, nous avons mis en place une gestion via les issues. Nous avons 4 types d'issue :
<center>
<img src="https://paypouz.com/assets/images/issues.png">
</center><br>
- **Les bugs :** dans lequel nous faisons/traitons nos bug reports
- **Les Slice :** lié au sprint, étant le thème du sprint
- **Les task :** étant les taches à réalisés n'étant pas des features
- **Les Features :** étant un type de tache particulier dans lequel nous créons les nouvelles features
- **Les Sub-Task :** étant les sous-taches à réalisés dans le cadre d'une tache/feature
Chaque issue étant reliés à des kanban sous forme de projet avec :
<center>
<img src="https://paypouz.com/assets/images/kanban-project.png">
</center><br>
- Un projet général regroupant l'avancement du projet global
- Un projet relatif à l'avancement du sprint en cours
- Un projet permettant de trier les différents bugs en fonction de leur priorité.
## Ouverture
Dans le futur, nous pouvons déjà améliorer la base de donnée comme mentionner plus haut, nous avons aussi la possibilité d'implémenter une meilleur gestion des litiges avec notamment la possibilité de faire des réclamations voir même la possibilité de créer des comptes utilisateur arrivant à un service light de PayPal par exemple.
----
# Complexification du projet
Nos nouveaux objectifs seront:
- Donner la priorité à la sécurité pour que notre système soit plus robuste
- Gestion de la charge avec un load balancer
- Démonstration de l'efficacité de notre sécurité et de notre gestion de la charge
- Eventuellement une ré-architecture pour pouvoir avoir une meilleure gestion de la charge et une sécurité plus simple à gérer
## Plan
Nous prévoyons tout d'abord un léger changement pour la gestion du numéro de suivi, celui-ci sera maintenant récupéré par notre application Paypouz directement auprès du transporteur, et ensuite transmis à l'acheteur et au vendeur (par Paypouz).
Ensuite nous allons réfléchir à une nouvelle architecture pour pouvoir plus facilement gérer la sécurité et la montée en charge, nous prévoyons de faire du benchmark avec gatling pour déterminer si notre architecture actuelle est suffisamment robuste, ou s'il faudrait l'améliorer (éventuellement séparer 1 ou 2 services intégrés au monolithe et donc en faire des micro-services pour mieux gérer a charge).
En parallèle des changements architecturaux, nous prévoyons donc de démontrer pourquoi notre solution est bonne au niveau de la sécurité et de la gestion de la charge.
## Roadmap
Slice 1 : Ajout d'un service externe au monolithe permettant de mocker le transporteur.
Slice 2 : Mise en place de gatling afin de tester la monter en charge.
Slice 3 : Mise en place d'un load balancer et teste de la monter charge.
Slice 4 : Possible changement architecturaux en fonction des résultats des testes.
Slice 5 : Amélioration de la sécurité de l'application.