Skip to content

Vendre à un client existant

La documentation suivante décrit la mise en place, via API, d'une vente à un client existant uniquement. La vente à des personnes inconnues du club, par exemple sur un portail non connecté, suit un process spécifique.

INFO

Retrouvez ce scenario dans les collections Bruno disponibles ici : Vendre à un client existant

CAUTION

Il est primmordial de vous être familiarisé avec les termes définis dans le glossaire avant de lire cette documentation.

WARNING

Dans le cas d’une intégration avec un prestataire de paiement, il est important d’effectuer cette action uniquement lorsque celui-ci a validé le paiement (et non ajouter des intentions de paiement).

Macro process de vente

Le processus de vente à un contact existant s'articule comme suit :

  1. Connaître le contact
  2. Récupérer le catalogue correspondant au contact
  3. Vendre un ou plusieurs produits au contact
  4. Vérifier la validité de la vente
  5. Valider la vente et enregistrer le paiement

Connaître le contact

Plusieurs informations relatives au contact ciblé par la vente sont à récolter en amont de celle-ci. Ces informations serviront ensuite lors de la récupération du catalogue.

Récupérer les mots clés du contact

Les tags sont listés sous forme de tableau dans la description d'un objet contact, dans la propriété tags.

bash
GET `/{clientToken}/contacts/{contactId}`
bash
GET `/demoapi/contacts/1234`
json
{  
   "@context":"/clienttoken/contexts/Contact",
   "@id":"/clienttoken/contacts/1234",
   "@type":"http://schema.org/Person",
   "number":"4110012692",
// ...
   "tags":[                          // <-- liste des mots clés de l'utilisateur
      {  
         "@id":"/clienttoken/contact_tags/416202",
         "@type":"ContactTag",
         "name":"abonnement",        // <-- mot clé #1
         "validFrom":"2019-05-07",
         "validThrough":"2019-06-07"
      },
      {  
         "@id":"/clienttoken/contact_tags/416245",
         "@type":"ContactTag",
         "name":"vip",               // <-- mot clé #2
         "validFrom":"2019-05-07",
         "validThrough":"2019-06-07"
      }
   ],
// ...
}

Récupérer le montant de dette du client

WARNING

Si un client est en dette, il est fort probable que la vente d'un produit lui soit refusée, surtout s'il s'agît d'un produit d'abonnement

Il est donc impératif que vous vous assuriez avant toute chose que le contact ne soit pas endetté.

Et s'il l'est, de l'inviter à clôturer sa dette avant de pouvoir aller plus loin (cf. documentation dédiée)

bash
GET `/{clientToken}/stats/accounts/contacts/:contactId`
bash
GET `/demoapi/stats/accounts/contacts/1234`
json5
{
  // ...
  "totalRealDebt": 10000, // <-- la valeur de la dette actuelle du contact
  // ...
}

Récupérer le catalogue du contact

Avant de commencer une vente il est nécessaire de lister les produits que le contact va pouvoir acheter. Pour cela, on va interroger l’api en lui fournissant le contexte de la vente.

GET /{clientToken}/products

paramètredescriptionexemple
context[channel]Canal de vente, valeurs autorisées club, web, terminal. Le catalogue peut varier selon le canal de vente.web
context[club]Club lieu de la vente. Le catalogue peut varier selon le club de vente./clientToken/clubs/123
context[contactTag]Les mots clés du contact. Le catalogue peut varier selon les mots clés (exemple : 'VIP' ou 'étudiants').nomdutag
context[debt]Il s'agit de la dette du client (en centimes), certains clubs restreignent les offres pour les clients ayant une dette trop élevée.600
context[date]Date souhaitée de l'achat. Certains produits ne sont pas disponibles tout au long de l'année (les promotions de la rentrée par exemple).2019-04-15
typeLa catégorie du produit. Il est possible de filtrer par catégorie. Valeurs autorisées subscription , subscription_option, badge, counter, package, countermark,test_session, regularsubscription voir les correspondances de catégories ci après
pageNuméro de page. La réponse comportant 30 résultats, celle ci peut être paginée.1
bash
GET /{clientToken}/products?context[channel]=club&context[club]=/{clientToken}/clubs/123&context[contactTag][]=tag-1&context[contactTag][]=tag-2&context[contactId]=/{clientToken}/contacts/123&context[debt]=0&context[date]=2019-04-02&type=badge&page=1

Catégories de produits

Voici les catégories existantes :

  • subscription : les produits "abonnements"
  • subscription_option : les produits "options d'abonnement"
  • badge : les produits "badges"
  • counter : les produits "carnets de séances"
  • package : les produits de formules packagées
  • countermark : les produits "contremarque"
  • test_session : les produits "séance d'essai"
  • regular : les produits "boutique"

Vendre un ou plusieurs produits au contact

Pour commencer une vente il faut d'abord créer le panier qui accueillera les articles que l'on souhaite vendre. Lors de cette création seules quelques infos sommaires sont nécessaires :

  • Le contact à qui la vente est faite (contactId)
  • Le club dans lequel la vente est faite (clubId, clubCode)

A cela s'ajouteront des informations non obligatoires à la création, mais que vous devrez renseigner avant la validation finale. Ces informations serviront à la facturation :

  • Les informations supplémentaires du contact (contactFamilyName, contactGivenName, contactNumber)
  • Son adresse (address)

Création de la vente

Les informations requises dans la requête :

paramètredescriptionexemple
contactIdIdentifiant du contact ciblé par la vente. Il s'agit d'une IRI et non d'un simple identifiant numérique/{clientToken}/contacts/12345
contactFamilyNameNom de famille du contact.Doe
contactGivenNamePrénom du contact.John
contactNumberNuméro du contact.423456
clubIdIdentifiant du club sous forme d'IRI/{clientToken}/clubs/1
clubCodeCode du clubABCDE
address[addressCountry]PaysFrance
address[addressLocality]VilleLa Madeleine
address[postalCode]Code postal59110
address[streetAddress]Adresse41 rue du Général de Gaulle
bash
POST `/{clientToken}/sales`
bash
curl --location --globoff '/demoapi/sales' \
--data '{
    "contactId": "/demoapi/contacts/1",
    "contactFamilyName": "Doe", 
    "contactGivenName": "John", 
    "contactNumber": "1", 
    "clubId": "/demoapi/clubs/1",
    "clubCode": "ABCDE", 
    "address": { 
        "addressCountry": "France",
        "addressLocality": "La Madeleine",
        "postalCode": "59110",
        "streetAddress": "41 Rue du Général de Gaulle"
    }
}'
json
{  
   "@context":"/clientToken/contexts/Sale",
   "@id":"/clientToken/sales/373969",  // <-- identifiant du panier
   "@type":"Sale",
  // ...
}

Ajouter un article au panier

Quelques précisions d'importance avant d'ajouter un article au panier.

Les comportements

Comme toute API de vente, nous avons donc un catalogue composé de produits et un panier composé d'articles. Par dessus ces notions classiques se trouvent les comportements (behaviors). Ce sont eux qui sont responsables du métier du fitness et des incidences liées aux achats des divers produits (ajouter un abonnement, créditer des séances ...).

Parmi ces comportements, certains impliquent des précisions de la part de l'acheteur (par exemple, acheter un abonnement nécessite une date de début) et d'autres ne nécessitent aucune précision (par exemple, acheter une gourde ou une serviette ne souffre d'aucune interrogation).

Référrez vous à la documentation dédiée aux comportements de produit.

Vendre un produit

Pour vendre un produit, il faut donc ajouter celui-ci au panier. Vous aurez donc besoin de l'identifiant du panier précédemment créé. Se reporter à la création du panier.

D'autre part, selon les comportements associés au produit vous devrez fournir les précisions attendues. Ajouter un article au panier passe donc toujours par le même point d'API, seuls les paramètres varient en fonction des comportements.

POST /{clientToken}/sales/{saleId}/articles

paramètredescriptionexemple
offerIdIdentifiant de l'offre du produit que l'on souhaite vendre. Il s'agit d'une IRI et non d'un simple identifiant numérique/{clientToken}/offers/4321
implementation(optionnel) précisions liées au comportement du produit ajouté. Voir ci après pour les différents formats attendus
implementations(optionnel) précisions liées aux multiples comportements du produit dans le cas de packages. Voir ci après pour les différents formats attendus

Vérifiez la validité de la vente

Il se peut que certains produits de la vente ne soient pas compatibles avec le contact. Par exemple une offre avec une restriction d'âge contredite par la date de naissance. L'ajout sur la vente n'est pas empêché, puisque vous pourriez vouloir modifier le contact en aval. Néanmoins si vous ne vérifiez pas l'intégrité de la vente avant de la soumettre vous risquez des erreurs.

WARNING: Attention : Régler (via un paiement) une vente incompatible, va encaisser l'argent sur le compte du client - la vente ne sera pas réglée (ventilée) : Ce sera au club de venir refaire la vente et d'y ventiler le paiement.

GET /{client_token}/sales/{id}/check

Cet endpoint renvoie

204

La vente est valide

400

La vente contient des erreurs

404

Identifiant de la vente incorrect / vente introuvable

Valider la vente et enregistrer le paiement

Afin de valider une vente vous pouvez, au choix :

  • Ajouter le paiement
  • Différer le paiement de la vente

Connaître la caisse et le montant à encaisser

Avant d'enregistrer un paiement, quelques informations à récolter :

  • montant à encaisser
  • caisse sur laquelle enregistrer le paiement

Pour cela il suffit d'interroger notre panier.

GET /{clientToken}/sales/{saleId}

paramètredescriptionexemple
saleIdIdentifiant du panier456

Exemple de requête

GET /{clientToken}/sales/1

json5
{
  // ...
  "checkoutId": "/clientToken/checkouts/1234", // <-- identifiant de la caisse
  "totalTI": 1100,                              // <-- montant à encaisser en centimes
  // ...
}

Valider la vente en lui ajoutant un paiement

WARNING

Attention, ces appels permettent de créer des paiments dans l'application, il est donc important de comprendre qu'à chaque appel, un paiment est créé, avec les liaisons comptables derrière.

Pour une vente de 50€, si 2 appels à l'API "ajout d'un paiement" de 50€ sont faits, le client aura un trop perçu de 50€ qui pourra servir à régler d'autres achats, même si le client n'a pas réellement payé 100€. Il est important de bien sécuriser ces appels.

Lors de l'ajout d'un paiement, plusieurs informations sont nécessaires :

  • Le contact à l'origine du paiement (contactId, contactFamilyName, contactGivenName, contactNumber)
  • Le club dans lequel le paiement est fait (clubId, clubCode, checkout)
  • Le montant du paiement (amount)
  • Le moyen de paiement, parmi :
    • CBWeb, pour un paiement CB en ligne
    • cash, pour un paiement en liquide
    • cheque, pour un paiement en chèque
    • card, pour un paiement en CB sur place

POST /{clientToken}/sales/{saleId}/payments

paramètredescriptionexemple
contactIdIdentifiant du contact effectuant le paiement/{clientToken}/contacts/456
contactFamilyNameNom de famille du contact effectuant le paiementDoe
contactGivenNamePrénom du contact effectuant le paiementJohn
contactNumberNuméro du contact effectuant le paiement98765
amountMontant du paiement en centimes4995
meanMoyen de paiementCBWeb
clubIdIdentifiant du club sous forme d'IRI/{clientToken}/clubs/1
clubCodeCode du clubABCDE
checkoutIdentifiant de caisse du club sous forme d'IRI/{clientToken}/checkouts/2
paymentCardsDétail des paiements par carte uniquement dans le cas d'un mean=card
paymentCards[][amount]Montant du paiement par carte en centimes (uniquement smean=card)4995
paymentCards[][network]Réseau bancaire parmi CBGroup, AmEx, Payline et `External(uniquement simean=card)
chequesDétail des paiements par chèques uniquement dans le cas d'un mean=cheque
cheques[][amount]Montant du chèque en centimes (uniquement si mean=cheque)4995
cheques[][bank]Nom de la banque (uniquement si mean=cheque)Banque populaire
cheques[][code]Numéro du chèque (uniquement si mean=cheque)1234567890
cheques[][depositDesiredDate]Date de dépôt souhaitée (uniquement si mean=cheque) 2019-01-31
cheques[][owner]Nom du titulaire du chèque (uniquement si mean=cheque)John Doe

Exemple d'un paiement Web

bash
curl '/{clientToken}/sales/1/payments'
json5
{
    "contactId": "/{clientToken}/contacts/1",
    "contactFamilyName": "Doe",
    "contactGivenName": "John",
    "contactNumber": "1",
    "amount": 5000,
    "mean": "CBWeb",
    "clubId": "/{clientToken}/clubs/1",
    "clubCode": "AA1",
    "checkout": "/{clientToken}/checkouts/1"
}
json5
{
    "contactId": "/{clientToken}/contacts/1",
    "contactFamilyName": "Doe",
    "contactGivenName": "John",
    "contactNumber": "1",
    "amount": 5000,
    "mean": "card",
    "clubId": "/{clientToken}/clubs/1",
    "clubCode": "AA1",
    "checkout": "/{clientToken}/checkouts/1",
    "paymentCards": [
        {
            "amount": 5000,
            "network": "CBGroup",
        }
    ]
}
json5
{
    "contactId": "/{clientToken}/contacts/1",
    "contactFamilyName": "Doe",
    "contactGivenName": "John",
    "contactNumber": "1",
    "amount": 5000,
    "mean": "cheque",
    "clubId": "/{clientToken}/clubs/1",
    "clubCode": "AA1",
    "checkout": "/{clientToken}/checkouts/1",
    "cheques": [ // A remplir uniquement pour les paiements en chèques
        {
            "amount": 5000,
            "bank": "Crédit du nord",
            "code": "1234567890",
            "depositDesiredDate": "2019-04-15", 
            "owner": "John Doe" 
        }
    ]
}

Valider la vente en différant le paiement

Il est permis de valider une vente en différant le paiement. Le contact sera redevable des montants de la vente avant la date indiquée.

paramètredescriptionexemple
dateDate à compter de laquelle le paiement sera considéré "en retard"2019-02-28
bash
POST `/{clientToken}/sales/{saleId}/postpone_due`
json
{
    "date": "2019-02-28"
}

Valider la vente sans paiement / Produits offerts

Si - et seulement si - vous veniez à créer une vente d'un montant nul (0€, produit gratuit)

Vous pouvez alors terminer la vente en lui appliquant une transition de validation

bash
`POST /{client_token}/sales/{id}/transitions`
json
{
    "transition": "validate"
}

La vente se retrouvera alors enregistrée, et les (potentiels) comportements de produits joués.