enlever le curseur apres irumva puis je veux que les deux boutons experience et
touch in sois au milieux dans un telephone et aussi designer les text de about Me,
je les veux sexy et aussi desiner bien le footer en ajoutans aussi mon numero
telephone +25767833026(c'est whatsapp)
Bonjour,
Merci pour votre retour et l’opportunité d’évaluation.
Voici mes réponses :
1. Intégration d’une API de paiement telle que Visa Direct :
- Création d’un compte sur Visa Developer et configuration du projet (API,
certificats, identifiants).
- Mise en place d’un environnement sécurisé avec certificats SSL/TLS ([Link],
[Link], CA).
- Développement d’un module backend (ex: Django/Flask en Python) pour encapsuler
les appels API (push funds, pull funds, multipush, queryapi, ...).
- Vérification des données côté serveur (montants, numéros de cartes) avant
envoi vers l’API.
- Gestion des réponses Visa (succès, erreurs) et journalisation dans une base de
données pour suivi des transactions.
- Tests sur Sandbox avant toute mise en production.
2. Mécanismes de sécurité :
- Utilisation systématique du protocole HTTPS avec certificats validés.
- Chiffrement des données sensibles (numéros de cartes) avec AES-256 et gestion
sécurisée des clés (Vault).
- Stockage minimal des données sensibles, en respectant le principe du PCI DSS
(ne pas stocker les PAN complets).
- Mise en place de tokens JWT pour authentifier les utilisateurs et limiter
l’accès aux APIs internes.
- Détection et prévention des fraudes via des règles (ex : montants maximums,
pays interdits).
- Journalisation sécurisée et monitoring en temps réel.
3. Expérience sur les architectures scalables :
- Oui, j'ai déjà travaillé sur des microservices avec Docker et Kubernetes.
- Pour Paylink, je mettrais en place :
* Une architecture microservices (authentification, paiements, reporting
séparés).
* Mise en cache des données fréquemment utilisées avec Redis pour réduire la
charge.
4. Démonstration technique :
- Une intégration test Visa Direct (sandbox) a été réalisée en Python.
- Le code source + guide simple de démo sont disponibles sur GitHub :
[Link]
5. Rémunération souhaitée :
- Entre 1 500 000 Fbu et 2 000 000 Fbu par mois.
Je reste disponible pour toute clarification ou démonstration en direct.
Cordialement,
Irumva Arsène
03/09/2025from .dependencies import *
def calculer_amortissement_degressif(credit: Credit, created_by: User):
amortissements = []
montant_initial = [Link]
echeances = [Link]
interet_total = [Link]
interet_mensuel = interet_total / echeances
capital_mensuel = montant_initial / echeances
mensualite = capital_mensuel + interet_mensuel
personnel = [Link](user=created_by)
microfinance = [Link]()
restant_du = montant_initial
for i in range(1, echeances + 1):
principal = round(capital_mensuel)
interet = round(interet_mensuel)
mensualite_arr = round(mensualite)
nouveau_restant_du = round(restant_du - capital_mensuel)
date_fin = ([Link]() + timedelta(minutes=i * 2))
amortissement = AmortissementDegressive(
capital=principal,
mensualite=mensualite_arr,
interet=interet,
restant_du=nouveau_restant_du if i < echeances else 0,
created_at=[Link](),
date_fin=date_fin,
credit=credit,
echeance=i,
done=False,
microfinance=microfinance
)
[Link](amortissement)
restant_du -= capital_mensuel
return amortissements
def sauvegarder_amortissements_degressifs(credit, created_by):
amortissements = calculer_amortissement_degressif(credit, created_by)
for amortissement in amortissements:
[Link]()
"""@action(
methods=["POST"],
detail=True,
url_name="differer",
url_path="differer",
serializer_class=DiffererCreditSerializer,
permission_classes=[[Link],IsPersonnel]
)
def differer(self, request, pk=None):
credit = self.get_object()
serializer = DiffererCreditSerializer(data=[Link])
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
if credit.done_at is not None:
return Response({"status": "Ce credit est déjà terminé"}, 400)
try:
periode = [Link]('periode', 0)
amortissements_non_payes =
[Link](credit=credit,
done=False).order_by('created_at')
for amortissement in amortissements_non_payes:
amortissement.date_fin = models.F('date_fin') +
timedelta(days=periode)
[Link]()
amortissement.refresh_from_db()
credit.payment_date = models.F('payment_date') +
timedelta(days=periode)
[Link]()
credit.refresh_from_db()
[Link](
compte=[Link],
action=[Link],
details=f"Reechelonnement du crédit {[Link]} de {periode}
jours",
montant=0,
balance=[Link],
created_by=[Link],
created_at=[Link]()
)
return Response([Link], status=status.HTTP_200_OK)
except Exception as e:
return Response({
"error": str(e)
}, status=status.HTTP_400_BAD_REQUEST)"""
"""@action(
detail=True,
methods=['get'],
url_path='reechelonner_impaye',
permission_classes=[[Link], IsPersonnel]
)
@[Link]
def reechelonner_impaye(self, request, pk=None):
credit = self.get_object()
if not credit.is_active or credit.done_at is not None:
return Response({"status": "Le crédit est terminé ou inactif."}, 400)
amortissements_impayes = [Link](credit=credit,
done=False).order_by('created_at')
nombre_mois_restants = amortissements_impayes.count()
if nombre_mois_restants == 0:
return Response({"status": "Aucun impayé trouvé."}, 400)
penalites_total = 0
montant_total_restant = 0
for amortissement in amortissements_impayes:
penalite = [Link]
penalites_total += penalite
montant_restant = amortissement.capital_a_payer +
amortissement.interet_a_payer
montant_total_restant += montant_restant
montant_total = montant_total_restant + penalites_total
nouvelle_mensualite = montant_total / nombre_mois_restants
amortissements_impayes.delete()
for i in range(nombre_mois_restants):
date_amortissement = [Link]().date() +
[Link](minutes=2 * i)
interet_de_retard = [Link] / [Link]
[Link](
credit=credit,
reste=nouvelle_mensualite,
interet=interet_de_retard,
capital=nouvelle_mensualite - interet_de_retard,
mensualite=nouvelle_mensualite,
date=date_amortissement,
date_fin=date_amortissement + [Link](minutes=2),
echeance=[Link] + i,
credit_restant_du=montant_total_restant - (nouvelle_mensualite * (i
+ 1)),
interet_restant=interet_de_retard,
mensualite_restante=nouvelle_mensualite
)
[Link]()
serializer = self.get_serializer(credit)
return Response([Link], 201)"""
"""@action(
detail=True,
methods=['post'],
url_path='reechelonner_capacite_reduite',
serializer_class=ReechelonnerCapaciteSerializer,
permission_classes=[[Link], IsPersonnel]
)
@[Link]
def reechelonner_capacite_reduite(self, request, pk=None):
credit = self.get_object()
if not credit.is_active or credit.done_at is not None:
return Response({"status": "Le crédit est terminé ou inactif."},
status=status.HTTP_400_BAD_REQUEST)
try:
nouvelle_mensualite = float([Link]('nouvelle_mensualite', 0))
if nouvelle_mensualite <= 0:
return Response({"status": "Un montant mensuel valide est
requis."}, status=status.HTTP_400_BAD_REQUEST)
except (TypeError, ValueError):
return Response({"status": "Montant invalide."},
status=status.HTTP_400_BAD_REQUEST)
amortissements_restants = [Link](credit=credit,
done=False)
reste_a_payer = amortissements_restants.aggregate(
total=Sum('mensualite')
)['total'] or 0
if reste_a_payer <= 0:
return Response({"status": "Aucun montant restant à payer."},
status=status.HTTP_400_BAD_REQUEST)
nouveau_nombre_mois = [Link](reste_a_payer / nouvelle_mensualite)
amortissements_restants.delete()
penalites_total = sum([Link] for amortissement in
amortissements_restants)
for i in range(nouveau_nombre_mois):
date_amortissement = [Link]().date() + timedelta(days=30 * (i +
1))
interet_mensuel = [Link] / [Link]
capital_mensuel = min(nouvelle_mensualite - interet_mensuel,
reste_a_payer - interet_mensuel)
[Link](
credit=credit,
interet=interet_mensuel,
capital=capital_mensuel,
mensualite=nouvelle_mensualite,
date_fin=date_amortissement,
echeance=i + 1,
capital_a_payer=capital_mensuel,
interet_a_payer=interet_mensuel,
mensualite_a_payer=nouvelle_mensualite,
penalite=penalites_total / nouveau_nombre_mois if i == 0 else 0 #
Applique toute la pénalité sur le premier mois
)
reste_a_payer -= nouvelle_mensualite
if reste_a_payer <= 0:
break
[Link] = nouveau_nombre_mois
[Link]()
serializer = self.get_serializer(credit)
return Response([Link], status=status.HTTP_201_CREATED)"""