Aller au contenu

Referral For Primary Purchase

Contrôleur HTTP des récompenses de parrainage liées aux achats primaires : statut de payout par property (lecture seule, Retool) et gestion des récompenses bloquées par seuil annuel (déblocage par upload de facture). Le payout lui-même est automatisé par le cron Graphile referral-primary-purchase-auto-payout ; il n'y a plus de route admin pour le déclencher manuellement. Source : referral-for-primary-purchase.controller.ts.

Tous les endpoints requièrent une session admin BetterAuth valide (AdminAuthGuard).

Préfixe de routes : /administration/referral-for-primary-purchase.

GET /:propertyId/payout-status

Retourne le statut de payout des parrainages pour une property et le montant total à verser.

Path param

  • propertyId — UUIDv4

Response

{
  "payoutStatus": {
    "financialStatus": "...",
    "referralPayoutStatus": "payout-not-allowed | payout-to-be-done | payout-done"
  },
  "amount": "1 234,56 €"
}

amount est la somme des récompenses en attente, formatée en chaîne (via prettyNumberWithCurrency).

referralPayoutStatus (source) :

  • payout-done : property.referralPaidAt est renseigné (la property a déjà été traitée par le cron de payout)
  • payout-to-be-done : financialStatus autorise le déboursement (∈ disbursementAllowedStatuses)
  • payout-not-allowed : sinon

Erreurs

Code Statut Cause
property.not-found 404 Property introuvable

GET /waiting-for-invoice

Liste les investisseurs ayant atteint le plafond annuel de récompenses parrainage et dont les rewards bloquées attendent une facture justificative.

Response

{
  "reachedLimitRewards": {
    "<email>": {
      "<year>": {
        "waiting-for-invoice": 5000,
        "invoice-received": 0
      }
    }
  },
  "maxRewardPerYearInCents": 50000
}

Type : ReferralsWaitingForInvoiceResponse.

POST /invoice-received

Upload d'une facture pour débloquer des récompenses parrainage en waiting-for-invoice. multipart/form-data avec champ file + body. Trace une REFERRAL_UPLOAD_INVOICE_TO_UNBLOCK.

Request body (multipart)

  • file — fichier de facture (validé via multerFileOptions())
  • Champs body validés via invoiceReceivedPayload (source) :
{
  "investorEmail": "investor@example.com",
  "invoiceAmountInCents": "5000",
  "year": "2026"
}

invoiceAmountInCents et year sont reçus en chaîne et coerce-és (numberFromString).

Effet

Algorithme getRewardsToUnblock (source) :

  • Itère sur les rewards bloquées par ordre chronologique
  • Si blockedAmount > invoiceRemainingAmount → erreur invoice-amount-too-low
  • Si la somme atteint exactement invoiceAmount → débloque les rewards visitées
  • Sinon (somme totale < invoiceAmount) → erreur invoice-amount-too-high

Erreurs

Code Statut Cause
invoice-amount-too-low 400 Le montant de la facture ne couvre pas exactement un sous-ensemble cohérent de rewards
invoice-amount-too-high 400 Le montant excède la somme totale des rewards bloquées

Liens