Sylius B2B : construire une plateforme e-commerce professionnelle
Le e-commerce B2B represente un marche colossal - bien plus important en volume que le B2C. Pourtant, la majorite des plateformes e-commerce sont pensees pour le grand public. Sylius, grace a son architecture flexible basee sur Symfony, se distingue comme une solution particulierement adaptee aux exigences du commerce inter-entreprises. Dans ce guide, je vous montre comment construire une plateforme B2B professionnelle avec Sylius.
Pourquoi le B2B necessite une approche differente
Si vous venez du monde B2C, le premier reflexe est de penser qu'un site B2B est simplement un site e-commerce classique avec des prix HT. La realite est bien plus complexe. Le parcours d'achat B2B implique des specificites fondamentales qui impactent chaque couche de votre application.
Les specificites cles du B2B
- Tarification personnalisee : chaque client ou groupe de clients peut avoir sa propre grille tarifaire, avec des remises par volume, des prix negocies et des conditions specifiques.
- Workflows d'approbation : un acheteur passe la commande, mais un responsable doit la valider avant qu'elle soit traitee. Parfois plusieurs niveaux de validation sont necessaires.
- Comptes entreprise multi-utilisateurs : une entreprise cliente a plusieurs collaborateurs qui passent des commandes, chacun avec des droits differents.
- Commandes en gros : les quantites minimales, les paliers de prix, les conditionnements par lot sont la norme.
- Facturation complexe : acomptes, paiement a 30/60/90 jours, avoir, factures pro forma, integration avec la comptabilite du client.
- Catalogue restreint : certains produits ne sont visibles que par certains clients ou groupes.
L'architecture Sylius pour le B2B
Sylius ne se presente pas comme une solution B2B cle en main, mais sa conception modulaire en fait un excellent socle. Voici comment exploiter ses composants natifs et les etendre pour le B2B.
Les Customer Groups pour la segmentation
Sylius dispose nativement d'un systeme de groupes clients (CustomerGroup). C'est la fondation de votre segmentation B2B. Chaque entreprise cliente est rattachee a un groupe qui determine ses conditions commerciales.
// src/Entity/Customer/CustomerGroup.php
namespace App\Entity\Customer;
use Sylius\Component\Customer\Model\CustomerGroup as BaseCustomerGroup;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'sylius_customer_group')]
class CustomerGroup extends BaseCustomerGroup
{
#[ORM\Column(type: 'integer', nullable: true)]
private ?int $paymentTermDays = null;
#[ORM\Column(type: 'decimal', precision: 5, scale: 2, nullable: true)]
private ?string $globalDiscount = null;
#[ORM\Column(type: 'boolean')]
private bool $requiresApproval = false;
// getters et setters...
}
Grilles tarifaires par groupe
Le systeme de pricing de Sylius repose sur des ChannelPricing. Pour le B2B, il faut l'etendre pour supporter des prix par groupe client. L'approche recommandee est de creer une entite CustomerGroupPricing qui lie un produit variant, un channel et un groupe client a un prix specifique.
// src/Entity/Pricing/CustomerGroupPricing.php
namespace App\Entity\Pricing;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'app_customer_group_pricing')]
#[ORM\UniqueConstraint(columns: ['variant_id', 'channel_id', 'customer_group_id'])]
class CustomerGroupPricing
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\ManyToOne(targetEntity: ProductVariant::class)]
private $variant;
#[ORM\ManyToOne(targetEntity: Channel::class)]
private $channel;
#[ORM\ManyToOne(targetEntity: CustomerGroup::class)]
private $customerGroup;
#[ORM\Column(type: 'integer')]
private int $price;
#[ORM\Column(type: 'json', nullable: true)]
private ?array $volumeTiers = null;
// Ex: [{"minQty": 10, "price": 900}, {"minQty": 50, "price": 800}]
}
Ensuite, un OrderProcessor personnalise applique le bon prix en fonction du groupe du client connecte :
// src/OrderProcessor/CustomerGroupPricingProcessor.php
namespace App\OrderProcessor;
use Sylius\Component\Order\Model\OrderInterface;
use Sylius\Component\Order\Processor\OrderProcessorInterface;
final class CustomerGroupPricingProcessor implements OrderProcessorInterface
{
public function process(OrderInterface $order): void
{
$customer = $order->getCustomer();
if (null === $customer || null === $customer->getGroup()) {
return;
}
foreach ($order->getItems() as $item) {
$groupPricing = $this->pricingRepository->findByVariantChannelAndGroup(
$item->getVariant(),
$order->getChannel(),
$customer->getGroup()
);
if (null !== $groupPricing) {
$price = $this->resolveVolumePrice($groupPricing, $item->getQuantity());
$item->setUnitPrice($price);
}
}
}
}
Workflow d'approbation des commandes
En B2B, une commande n'est pas forcement validee immediatement. Un acheteur passe la commande, puis un ou plusieurs responsables doivent l'approuver. Sylius 2.x utilise Symfony Workflow, ce qui rend l'implementation naturelle.
# config/packages/workflow.yaml
framework:
workflows:
b2b_order_approval:
type: state_machine
marking_store:
type: method
property: approvalState
supports:
- App\Entity\Order\Order
initial_marking: pending
places:
- pending
- approved
- rejected
transitions:
approve:
from: pending
to: approved
reject:
from: pending
to: rejected
Le workflow s'integre avec le systeme de notifications de Symfony pour envoyer un email au responsable des achats quand une commande est en attente d'approbation. Une fois approuvee, la commande reprend le flux standard de Sylius.
Comptes entreprise multi-utilisateurs
En B2B, un "client" n'est pas une personne mais une entreprise. Plusieurs collaborateurs doivent pouvoir passer des commandes sous le meme compte, avec des roles differents (acheteur, approbateur, administrateur). Sylius Plus propose cette fonctionnalite nativement. En version open source, il faut la developper :
- Creer une entite
Companyqui regroupe plusieursCustomer - Ajouter un systeme de roles au sein de l'entreprise (ROLE_BUYER, ROLE_APPROVER, ROLE_COMPANY_ADMIN)
- Partager le carnet d'adresses et l'historique de commandes au niveau de l'entreprise
- Implementer un portail d'administration pour le gestionnaire du compte entreprise
Gestion des commandes en gros
Les commandes B2B impliquent souvent des volumes importants. L'interface doit s'adapter :
- Import CSV/Excel : permettre aux clients d'importer une liste de references et quantites plutot que de naviguer dans le catalogue un produit a la fois
- Quick order : un formulaire simplifie ou le client saisit directement les codes produits et quantites
- Renouvellement de commande : possibilite de re-commander en un clic a partir d'une commande precedente
- Quantites minimales et multiples : forcer des quantites par lot (ex: par carton de 12)
// src/Validator/Constraints/MinimumQuantityValidator.php
namespace App\Validator\Constraints;
use Symfony\Component\Validator\ConstraintValidator;
class MinimumQuantityValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint): void
{
$variant = $value->getVariant();
$minQty = $variant->getMinimumOrderQuantity() ?? 1;
$stepQty = $variant->getQuantityStep() ?? 1;
if ($value->getQuantity() < $minQty) {
$this->context->buildViolation($constraint->minMessage)
->setParameter('{{ min }}', $minQty)
->addViolation();
}
if (($value->getQuantity() - $minQty) % $stepQty !== 0) {
$this->context->buildViolation($constraint->stepMessage)
->setParameter('{{ step }}', $stepQty)
->addViolation();
}
}
}
Facturation et conditions de paiement
La facturation B2B est un sujet majeur, d'autant plus avec la reforme de la facturation electronique en France. Les specificites a implementer :
- Paiement differe : 30, 60, 90 jours fin de mois. Chaque groupe client a ses conditions.
- Encours client : plafonner le montant total des commandes impayees par client.
- Factures pro forma : generer un devis formel avant la commande definitive.
- Avoir et retours : gerer les retours partiels avec generation automatique d'avoirs.
- Export comptable : integration avec Sage, Pennylane ou tout autre logiciel comptable via API.
Pour la methode de paiement "sur compte", creez un payment method personnalise qui valide la commande sans passerelle de paiement externe, en verifiant l'encours disponible du client.
Integration avec l'ecosysteme SI
Une plateforme B2B vit rarement en silo. L'integration avec l'ERP, le CRM et le PIM du client est souvent critique. Sylius, grace a Symfony Messenger, offre un pattern propre pour ces integrations asynchrones :
// src/MessageHandler/SyncOrderToErpHandler.php
namespace App\MessageHandler;
use App\Message\SyncOrderToErp;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
final class SyncOrderToErpHandler
{
public function __construct(
private readonly ErpClientInterface $erpClient,
private readonly LoggerInterface $logger,
) {}
public function __invoke(SyncOrderToErp $message): void
{
$order = $this->orderRepository->find($message->orderId);
try {
$this->erpClient->pushOrder($order);
$order->setErpSyncStatus('synced');
} catch (ErpException $e) {
$this->logger->error('ERP sync failed', [
'order' => $order->getNumber(),
'error' => $e->getMessage(),
]);
$order->setErpSyncStatus('failed');
throw $e; // Retry via Messenger
}
}
}
Performances et mise a l'echelle
Les catalogues B2B sont souvent volumineux (dizaines de milliers de references). Quelques bonnes pratiques pour garantir les performances :
- Utiliser Elasticsearch ou Meilisearch pour la recherche et le filtrage du catalogue
- Mettre en cache les grilles tarifaires avec Redis (invalidation par groupe client)
- Paginer les resultats avec des curseurs plutot que des offsets pour les gros catalogues
- Implementer un systeme de queue pour les imports/exports volumineux
Pour en savoir plus sur l'optimisation des performances, consultez notre article sur Sylius et Varnish.
Conclusion
Sylius offre un socle technique solide pour le B2B grace a Symfony. L'absence de fonctionnalites B2B natives peut sembler un frein, mais c'est en realite un avantage : vous construisez exactement ce dont votre metier a besoin, sans les compromis d'une solution generique. L'investissement initial est plus important, mais la plateforme resultante est parfaitement adaptee a vos processus.
Vous avez un projet B2B a concretiser ? Contactez-moi pour un audit de faisabilite et un chiffrage precis. Basee a Strasbourg et Metz, j'accompagne les entreprises du Grand-Est et de Belgique dans la construction de plateformes e-commerce sur mesure. Consultez egalement nos tarifs et nos services pour avoir une vision globale de notre accompagnement.
