Professional B2B System for Magento 2 Open Source

Kowal B2B Suite is a Magento 2 module package designed for companies that want to run B2B sales on Magento Open Source without giving up the platform native catalog, cart, checkout, MSI, store view, website scope, and integration mechanisms.
SKU
M2-B2B
€922.50
Email to a Friend

Enquire about this product

Description / Professional B2B System for Magento 2 Open Source

MAGENTO 2 · MAGENTO OPEN SOURCE · COMPANIES · B2B COMMERCE

Combine B2B and B2C sales in one Magento installation.

Kowal B2B Suite

Build a contractor portal with companies, roles, pricing, catalogs, RFQ, limits, documents, and integrations. Activate B2B logic for selected websites and adapt the process to your commercial rules.

16 modules and a theme · Website scope · REST and GraphQL

HOW IT WORKS IN PRACTICE

01 · Define your sales model
You define companies, channels, prices, and data sources.

02 · Configure the B2B process
You assign roles, catalog, terms, and approvals.

03 · Connect systems and deploy
You select adapters and verify complete scenarios.

What does your store gain?

Explore the module features, use cases, and settings.

Explore the module

KOWAL B2B SUITE · MAGENTO 2 OPEN SOURCE

A professional B2B system without moving to Adobe Commerce

Kowal B2B Suite extends Magento 2 Open Source with the features needed for wholesale and contract sales.

Manage companies, users, custom pricing, quick orders, trade credit limits, approvals, quotes, documents, and integrations — all in one Magento environment.

Companies and roles · Prices and catalogs · RFQ · Trade credit · Documents · Integrations

B2B sales tailored to your commercial rules

Each contractor can receive its own prices, catalog, payment terms, limits, and users with different permissions.

The system supports both a simple wholesale model and advanced purchasing processes with multi-step approval and integration with ERP, PIM, WMS, or CRM.

Key areas of the B2B platform

Move daily contractor service from emails, spreadsheets, and manual arrangements directly into Magento.

Companies, users, and purchasing roles

One company can have multiple users, addresses, and people responsible for purchasing. Roles define who can place orders, approve them, or view data.

Custom pricing and catalogs

Each contractor can receive its own catalog, contract prices, quantity tiers, and purchasing rules. The customer sees the offer intended for their company.

Quick orders and shopping lists

Customers can efficiently place large orders by SKU, use shopping lists, and import items instead of searching for each product separately.

RFQ, quotes, and approvals

The quoting process can include negotiated prices, an expiration date, and individual terms. Orders can go through approval based on value or user role.

Financial control without spreadsheet work

Trade credit limits, credit utilization, and payment terms help control sales with deferred payment.

The customer has access to documents, while the team sees commercial terms and process status in one place.

Documents in the customer portal

  • invoices and credit memos,
  • delivery documents and confirmations,
  • PDF quotes,
  • documents from Magento or the ERP system.

What does implementation look like?

The platform can be implemented in stages. First, we organize commercial rules, then map them in Magento and integrate them with company systems.

1. Sales model

We define customers, channels, price lists, payments, restrictions, and data sources.

2. Company rules

We configure users, prices, catalog, addresses, limits, and purchasing roles.

3. Purchasing process

We implement quick orders, quotes, approvals, documents, and checkout rules.

4. Integrations and testing

We connect ERP, PIM, WMS, or CRM, test scenarios, and prepare the team for daily work.

Integrations with company systems

Data about customers, prices, products, orders, and documents can be exchanged with ERP, PIM, WMS, CRM, EDI, and contractor purchasing systems.

Synchronization can include trade credit limits, payment terms, order statuses, and documents. Task and error history makes it easier to control the process.

B2B that grows with your business

Kowal B2B Suite is a solution for wholesalers, distributors, manufacturers, and companies running contract sales.

You can start with companies, pricing, and catalog, then extend the platform with quick orders, RFQ, limits, approvals, documents, and integrations.

One Magento. One catalog. One B2C and B2B sales process.

One package, modular architecture

kowal/metapackage-b2b-suite provides the files for 16 B2B modules and the frontend/Kowal/b2b theme. The main package registers them in autoload and replaces subpackage names, so installing the suite does not require a separate repository for each module.

The implementation is designed for Magento Open Source 2.4.9 and PHP 8.3. The scope of activated modules, theme compatibility, and process scenarios must be verified in the target installation.

Website and company access model

B2B features operate in the context of the selected website_id. A company must have an active relationship with that channel, and roles define access to purchasing, users, quotes, and documents.

The first company model assumes one assigned website. B2C sales can use the same installation, but B2B activation and access to companies remain separated by channel configuration.

Quick Order, approvals, and staged implementation

Quick order checks SKU, quantity, website assignment, company visibility, and B2B price. Shopping lists and import logs help handle repeat orders.

Approval rules take company, website, currency, and threshold into account. The current pending request is closed with an approve, reject, or cancel decision. A multi-step workflow must be agreed and verified as a specific implementation scope.

Documents and secure access

Documents are assigned to a company and website. PDF files are stored in var/kowal_b2b_documents and downloaded through a controller that verifies access.

The source can be Magento Sales or a hybrid Magento + API mode. The package includes order, invoice, shipment, and credit memo documents, as well as a shared PDF renderer; synchronizing documents from an external system requires the appropriate adapter.

Integrations require adapters and data sources

The Integration layer provides profiles, identifier mapping, jobs, retry, logs, and a dead letter queue. A specific ERP, PIM, WMS, or CRM is connected with an adapter implementing SyncAdapterInterface.

Before launch, define the source of truth for companies, prices, inventory, orders, and documents. REST and GraphQL are integration points; installing the package does not automatically connect all company systems.

Installation via Composer

Package kowal/metapackage-b2b-suite, module Kowal_B2BBase. After configuring access to the Kowal repository, install the package, enable the module, update Magento, and clear cache. In production, include compilation and static content deployment according to the store process.

From configuration to results

1. Define your sales model
You define companies, channels, prices, and data sources.

2. Configure the B2B process
You assign roles, catalog, terms, and approvals.

3. Connect systems and deploy
You select adapters and verify complete scenarios.

Order portal for contractors

The company is assigned to an active B2B website. Its user works with the catalog and price defined by the agreed terms, adds items by SKU, and places the order.

Depending on configuration, the process includes a limit and approval. Documents and integrations remain linked to the company and the correct sales channel.

Plan a B2B implementation tailored to your company

Want to adapt the module to your store? Ask about implementing Kowal B2B Suite and discuss the configuration or required extensions.

More Information

Theme compatibility Luma / Blank, KOWAL

Integration Configuration

Kowal B2B API — Complete REST Documentation

Contract version: V1 · Source of truth: Kowal_B2BApi/etc/webapi.xml · Audience: store administrators, implementation partners, and teams integrating ERP, PIM, WMS, or purchasing systems.

1. API purpose and boundaries

Kowal B2B API exposes B2B data and processes operating in Magento 2: companies, catalog and individual prices, quick purchasing, documents, trade credit limit, approvals, RFQ, and integration queues. It is a REST API for system integrations; it does not replace standard Magento endpoints for catalog, cart, checkout, and customer account.

The document describes only the endpoints currently exposed by the module. It does not promise operations not made available by the V1 contract, such as order creation via REST, price list CRUD, or website configuration editing.

2. Obtaining access and collaboration rules

2.1. Integration launch process

  1. The integrator provides the store administrator with the integration goal, environment (test/production), source system, data scope, and list of required API areas.
  2. The administrator creates or configures the Magento integration, assigns minimal ACL permissions, and securely provides: baseUrl, token, websiteId, companyId when applicable, currency, and test data.
  3. The integrator runs the GET /V1/kowal-b2b/websites/:websiteId/config test, followed by functional tests in the test environment.
  4. Before production, both parties agree on the synchronization schedule, maximum data size, retry, data owner, and error reporting method.
  5. Tokens are stored only in a secrets vault; the administrator rotates or revokes them when the vendor, user, or integration scope changes.

2.2. Responsibilities

PartyResponsibility
Store administratorConfiguration of B2B website, company and company relationship with website, token, and ACL; provision of test data; decision on data access.
IntegratorSecure token storage, correct use of websiteId/companyId context, data validation, error and retry handling, and not disclosing data of other companies.
Business process ownerAgreement on the source of truth for prices, documents, RFQ, limits, and synchronization statuses.

Do not use an administrator token in a client application or share one token across independent systems. Each integration should have its own token and only the required ACL.

2.3. Permissions

Magento verifies the Bearer token and ACL assigned to the administrative user or integration. B2B endpoints require one of the following permission groups:

ACLScope
configWebsites and feature flags
companies, company_save, company_users, batchCompanies, their users, and batch company import
products, prices, catalog_permissionsCatalog, availability, prices, and visibility
import_export, quick_order, documentsImport/export profiles, shopping lists, and documents
credit_limits, approvals, orders, quotesLimit, approval workflow, order context, and RFQ
system_integrationsProfiles, mappings, and integration jobs

The scope should result from the purpose of the integration. Example: a purchasing system usually needs products, prices, catalog_permissions, quick_order, and quotes; an ERP handling documents — documents and, if it owns synchronization, system_integrations.

3. Technical conventions

Address, headers, and parameters

The base address has the form https://b2b.example.com/rest/V1. All paths later in this document are provided from /V1; the full endpoint address is BASE_URL + path.

Authorization: Bearer Accept: application/jsonContent-Type: application/json

The API uses JSON. Names in URLs are camelCase (websiteId, companyId), and JSON fields correspond to Magento contract parameter names. :companyId, :quoteId, :sku, etc. are path parameters. In examples, ? indicates an optional parameter.

websiteId is required for sales channel-dependent operations. It must point to an existing website with B2B enabled. companyId points to a company that must have an active relationship with this website when the operation runs in its context. The API does not select a default website or company.

Request body and idempotency

Magento serializes the DTO object under the method parameter name: most write operations accept {'request': {...}}; company creation uses {'company': {...}}; company batch — {'companies': [...]}. Endpoints with simple arguments accept fields without a wrapper, e.g. {'websiteId': 1, 'currency': 'PLN', 'items': [...]}.

The Idempotency-Key header, max. 128 characters, is currently supported by POST /companies: retrying with the same key will return the previously created company. For an integration job, use the request.idempotencyKey field. Do not assume automatic idempotency of other write endpoints; retry them only after determining the operation status.

Responses and errors

Successful responses are Magento contract objects or arrays. Fields returned by objects may be extended in a compatible way; the integration should ignore unknown fields. A business error may contain:

{ 'code': 'b2b.company.not_assigned_to_website', 'message': 'B2B company is not assigned to website.', 'website_id': 1, 'trace_id': 'request-correlation-id', 'details': {'company_id': 10}, 'field_errors': []}
HTTPMeaningIntegrator response
400 / 422Invalid data or domain validationCorrect the data; do not retry without changing the payload.
401 / 403Missing or insufficient token/ACLDo not retry; report the token scope to the administrator.
404The resource or relationship does not exist in the given contextVerify identifiers and website context.
409Status conflict or duplicateRead the current state before deciding to retry.
5xx / timeoutTechnical errorUse limited retry with backoff and keep the trace_id.

Do not log tokens, full personal data, or configuration secrets. A report to the store team should include time, method, path without secrets, HTTP status, trace_id, and anonymized payload.

4. Input data schemas

The schemas below are common to the reference endpoints. A field without ? is required by the contract; ? means an optional value. The metadata, config, configuration, and payload fields are JSON objects.

DTO / wrapperFields
companywebsiteId, name, taxId, externalId?, status?, salesRepresentativeId?, customerGroupId?, websiteActive?
companyUserwebsiteId, roleId, active
request — RFQwebsiteId, companyId, customerId?, externalId?, title, currency, validUntil?, customerNote?, salesNote?, metadata?
request — RFQ itemquoteId, sku, productId?, name?, qty, requestedPrice?, offeredPrice?, comment?, metadata?
request — RFQ decisioncustomerId?, adminUserId?, message?
request — RFQ commentquoteId, customerId?, adminUserId?, authorType, message, visibleForCustomer
request — documentwebsiteId, companyId, orderId?, orderIncrementId?, invoiceId?, invoiceIncrementId?, creditmemoId?, creditmemoIncrementId?, externalId?, documentNumber, documentType, status, issueDate?, dueDate?, grandTotal?, currency?, metadata?
request — document filedocumentId, fileName, filePath, mimeType, fileSize, checksum?, primary
request — limitwebsiteId, companyId, termsId?, creditLimit, currency, active, status, metadata?
request — limit exposurewebsiteId, companyId, sourceType, sourceId, sourceIncrementId?, amount, currency, dueDate?, metadata?
request — payment termswebsiteId, code, name, daysDue, active, description?
request — approval rulewebsiteId, companyId, name, thresholdAmount, currency?, priority, active, metadata?
request — approverruleId, customerId, sortOrder, active
request — approval decisionapproverCustomerId?, comment?
request — approval requestwebsiteId, companyId, orderId?, orderIncrementId?, requesterCustomerId?, grandTotal, currency, comment?, metadata?
request — import/export profilewebsiteId, code, name, direction, entityType, format, behavior, active, configuration?
request — integration profilewebsiteId, code, name, systemType, adapterCode, direction, active, maxAttempts, config?
request — mappingwebsiteId, systemType, entityType, localId, externalId, metadata?
request — integration jobprofileId, direction?, entityType, operation, idempotencyKey?, maxAttempts?, payload?, scheduledAt?

5. Endpoint reference

In the tables, ACL means the minimum Magento permission resource. Result defines the successful response type.

5.1. Websites and configuration

Method and endpointACLInputResult and use
GET /V1/kowal-b2b/websitesconfig—Array of websites (websiteId, code, name, B2B flag). Retrieve before integration configuration.
GET /V1/kowal-b2b/websites/:websiteId/configconfigpath: websiteIdB2B website configuration, including enabled/debug/log retention. Run as an access test.
GET /V1/kowal-b2b/websites/:websiteId/featuresconfigpath: websiteIdFeature flags active for the website; use for conditional client feature enabling.

5.2. Companies and company users

Method and endpointACLInputResult and use
GET /companies?websiteId=companiesquery: websiteIdArray of companies assigned to the website.
POST /companiescompany_savebody: companyCreates a company and relationship with the website; use Idempotency-Key on retries. Returns the company.
POST /companies/batchbatchbody: companies — array of companyCreates multiple companies and returns a result per item, including errors.
GET /companies/:companyId?websiteId=companiespath: companyId; query: websiteIdCompany verified in website context.
PUT /companies/:companyIdcompany_savepath: companyId; body: companyUpdates company data and relationship for company.websiteId.
POST /companies/:companyId/activate?websiteId=company_savepath: companyId; query: websiteIdActivates the company in the indicated website and returns it.
POST /companies/:companyId/block?websiteId=company_savepath: companyId; query: websiteIdBlocks the company in the indicated website and returns it.
GET /companies/:companyId/users?websiteId=company_userspath: companyId; query: websiteIdArray of customer assignments to the company.
PUT /companies/:companyId/users/:customerIdcompany_userspath: companyId, customerId; body: companyUserGrants/updates the customer role and activity in the company; returns the assignment.

5.3. Products, price, and catalog visibility

Method and endpointACLInputResult and use
GET /products?websiteId=productsquery: websiteIdArray of basic Magento products for the website.
GET /products/:sku?websiteId=productspath: encoded sku; query: websiteIdProduct (id, sku, name, type, status, websites).
GET /products/:sku/availability?websiteId=productspath: sku; query: websiteIdMSI availability and salable quantity for SKU.
GET /products/:sku/b2b-status?websiteId=productspath: sku; query: websiteIdB2B status: website assignment, translations, and stock data.
GET /reports/products/missing-translations?websiteId=productsquery: websiteIdReport of SKUs without required translations, with reason/details.
GET /reports/products/missing-stock?websiteId=productsquery: websiteIdReport of SKUs without required stock data.
GET /companies/:companyId/products/:sku/price?websiteId=&currency=&qty=pricespath: companyId, sku; query: websiteId, currency, optional qty (default 1)Explanation of the price applicable to the company, currency, and quantity; read before purchase.
GET /companies/:companyId/products/:sku/visibility?websiteId=catalog_permissionspath: companyId, sku; query: websiteIdSKU visibility/purchase result for the company.
GET /companies/:companyId/catalog-visibility?websiteId=catalog_permissionspath: companyId; query: websiteIdArray of company visible catalog index items.
POST /companies/:companyId/catalog-visibility/reindex?websiteId=catalog_permissionspath: companyId; query: websiteIdRebuilds the index and returns the number of indexed items. Administrative operation.

5.4. File import and export

Method and endpointACLInputResult and use
GET /import-export/profiles?websiteId=import_exportquery: websiteIdArray of website import/export profiles.
POST /import-export/profilesimport_exportbody: request — import/export profileSaves the profile and returns its data.
POST /import-export/import/:profileId?sourceFile=&dryRun=import_exportpath: profileId; query: sourceFile, optional dryRun=falseStarts import of a file indicated on the Magento environment side; returns a job. Does not send multipart.
POST /import-export/export/:profileId?resultFile=import_exportpath: profileId; optional query: resultFileCreates an export job, optionally with a target file path.
GET /import-export/jobs?websiteId=import_exportquery: websiteIdArray of import/export jobs for the website.
GET /import-export/jobs/:jobIdimport_exportpath: jobIdStatus, result, and data of a single job.
GET /import-export/jobs/:jobId/logsimport_exportpath: jobIdDiagnostic logs of the job.

5.5. Quick order and shopping lists

Method and endpointACLInputResult and use
POST /companies/:companyId/quick-order/validatequick_orderpath: companyId; body: websiteId, currency, items (sku, qty)Validates multiple SKUs in company context: availability, visibility, and price; returns a summary result.
GET /companies/:companyId/shopping-lists?websiteId=quick_orderpath: companyId; query: websiteIdArray of company shopping lists.
POST /companies/:companyId/shopping-listsquick_orderpath: companyId; body: websiteId, name, optional customerId, isDefault=falseCreates and returns a shopping list.
GET /shopping-lists/:listId/itemsquick_orderpath: listIdArray of items on the indicated list.
POST /shopping-lists/:listId/itemsquick_orderpath: listId; body: currency, items (sku, qty)Adds items to the list and returns the saved items.

5.6. Documents and files

Method and endpointACLInputResult and use
GET /companies/:companyId/documents?websiteId=&documentType=documentspath: companyId; query: websiteId, optional documentTypeCompany documents, optionally filtered by type.
GET /documents/:documentId?companyId=&websiteId=documentspath: documentId; query: companyId, websiteIdDocument details after company ownership verification.
POST /documentsdocumentsbody: request — documentCreates or saves document metadata and returns the document.
POST /documents/filesdocumentsbody: request — document fileRegisters an existing file in Magento storage (name, path, MIME, size); does not upload binaries.
GET /documents/:documentId/files?companyId=&websiteId=documentspath: documentId; query: companyId, websiteIdArray of document file metadata.
GET /documents/:documentId/sync-logsdocumentspath: documentIdDocument synchronization logs; intended for administrative integration.

5.7. Trade credit limit and payment terms

Method and endpointACLInputResult and use
GET /companies/:companyId/credit/status?websiteId=&currency=credit_limitspath: companyId; query: websiteId, currencyLimit status, utilization, and available company amount.
POST /credit-limitscredit_limitsbody: request — limitCreates/updates the company limit and returns the limit.
POST /credit/exposurescredit_limitsbody: request — exposureReserves limit exposure for a source, such as an order, and returns it.
POST /credit/exposures/:exposureId/releasecredit_limitspath: exposureId; optional body: messageReleases exposure; returns its state.
GET /payment-terms?websiteId=credit_limitsquery: websiteIdArray of active/known website payment terms.
POST /payment-termscredit_limitsbody: request — payment termsSaves payment terms and returns them.

5.8. Approval workflow

Method and endpointACLInputResult and use
GET /companies/:companyId/approval/rules?websiteId=&currency=approvalspath: companyId; query: websiteId, optional currencyCompany approval rules for the channel/currency.
POST /approval/rulesapprovalsbody: request — ruleCreates/updates a threshold rule and returns it.
GET /approval/rules/:ruleId/approversapprovalspath: ruleIdArray of assigned approvers, in sortOrder.
POST /approval/approversapprovalsbody: request — approverSaves the customer assignment as an approver.
GET /companies/:companyId/approval/required?websiteId=&grandTotal=&currency=approvalspath: companyId; query: websiteId, grandTotal, currencyBoolean: whether the amount requires approval.
POST /approval/requestsapprovalsbody: request — approval requestCreates a request for the order and returns it.
GET /companies/:companyId/approval/requests?websiteId=&status=approvalspath: companyId; query: websiteId, optional statusArray of company approval requests.
POST /approval/requests/:requestId/approveapprovalspath: requestId; body: request — decisionApproves the request; returns its current state.
POST /approval/requests/:requestId/rejectapprovalspath: requestId; body: request — decisionRejects the request; returns its current state.
POST /approval/requests/:requestId/cancelapprovalspath: requestId; body: request — decisionCancels the request; returns its current state.
GET /approval/requests/:requestId/decisionsapprovalspath: requestIdDecision history for the request.

5.9. B2B order context

Method and endpointACLInputResult and use
GET /orders/:orderId/b2b-contextorderspath: orderIdB2B context of a single native Magento order, e.g. company, approval status, limit, export.
GET /companies/:companyId/orders/b2b-context?websiteId=&approvalStatus=orderspath: companyId; query: websiteId, optional approvalStatusArray of company order contexts, optionally filtered by approval status.

5.10. RFQ and commercial offers

Method and endpointACLInputResult and use
GET /companies/:companyId/quotes?websiteId=&status=quotespath: companyId; query: websiteId, optional statusCompany RFQs and quotes, optionally by status.
POST /quotesquotesbody: request — RFQCreates a draft RFQ and returns it. Add items with a separate endpoint.
GET /quotes/:quoteIdquotespath: quoteIdRFQ/quote details.
GET /quotes/:quoteId/itemsquotespath: quoteIdArray of RFQ items.
POST /quotes/itemsquotesbody: request — RFQ itemAdds SKU and quantity, optional requested/offered price, and comment.
GET /quotes/:quoteId/commentsquotespath: quoteIdRFQ comments. The customer sees only comments marked as visible.
POST /quotes/commentsquotesbody: request — RFQ commentAdds a message; authorType and visibleForCustomer define the author and visibility.
GET /quotes/:quoteId/historyquotespath: quoteIdRFQ status change and event history.
POST /quotes/:quoteId/submitquotespath: quoteId; body: request — RFQ decisionSubmits the draft RFQ for pricing.
POST /quotes/:quoteId/make-offerquotespath: quoteId; body: request — RFQ decisionThe salesperson creates/submits an offer; define item prices before calling.
POST /quotes/:quoteId/acceptquotespath: quoteId; body: request — RFQ decisionAccepts the current offer. This contract does not create a REST order.
POST /quotes/:quoteId/rejectquotespath: quoteId; body: request — RFQ decisionRejects the offer/RFQ.
POST /quotes/:quoteId/cancelquotespath: quoteId; body: request — RFQ decisionCancels the RFQ if the current status allows it.

5.11. Integration profiles and jobs

Method and endpointACLInputResult and use
GET /integrations/profiles?websiteId=&systemType=system_integrationsquery: websiteId, optional systemTypeIntegration profiles for the website.
POST /integrations/profilessystem_integrationsbody: request — integration profileSaves an ERP/PIM/WMS, etc. profile and returns it.
POST /integrations/mappingssystem_integrationsbody: request — mappingSaves a local ID ↔ external ID pair.
GET /integrations/mappings/local?websiteId=&systemType=&entityType=&localId=system_integrationsquery: all parameters requiredFinds a mapping by Magento identifier.
GET /integrations/mappings/external?websiteId=&systemType=&entityType=&externalId=system_integrationsquery: all parameters requiredFinds a mapping by external system identifier.
POST /integrations/jobssystem_integrationsbody: request — jobPublishes a job for execution; idempotencyKey identifies the business operation.
GET /integrations/jobs?websiteId=&status=system_integrationsquery: websiteId, optional statusArray of integration jobs.
GET /integrations/jobs/:jobIdsystem_integrationspath: jobIdStatus and details of a single job.
POST /integrations/jobs/:jobId/processsystem_integrationspath: jobIdProcesses the job and returns its current state.
POST /integrations/jobs/:jobId/retrysystem_integrationspath: jobIdRetries the job after an error, according to its attempt limit.
GET /integrations/jobs/:jobId/logssystem_integrationspath: jobIdJob execution logs.
GET /integrations/jobs/:jobId/errorssystem_integrationspath: jobIdDomain/technical job errors.

6. Example calls

export BASE_URL='https://b2b.example.com/rest/V1'export TOKEN='token-przekazany-przez-administratora'export WEBSITE_ID=1 COMPANY_ID=10 SKU='B2B-SKU-001' CURRENCY='PLN'# Test dostępu i konfiguracji kanałucurl -sS '$BASE_URL/kowal-b2b/websites/$WEBSITE_ID/config' \ -H 'Authorization: Bearer $TOKEN' -H 'Accept: application/json'# Cena kontraktowa firmy dla konkretnej ilościcurl -sS '$BASE_URL/kowal-b2b/companies/$COMPANY_ID/products/$SKU/price?websiteId=$WEBSITE_ID&currency=$CURRENCY&qty=5' \ -H 'Authorization: Bearer $TOKEN' -H 'Accept: application/json'# Walidacja koszyka po SKUcurl -sS -X POST '$BASE_URL/kowal-b2b/companies/$COMPANY_ID/quick-order/validate' \ -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' \ --data '{'websiteId':1,'currency':'PLN','items':[{'sku':'B2B-SKU-001','qty':5}]}'# Utworzenie RFQcurl -sS -X POST '$BASE_URL/kowal-b2b/quotes' \ -H 'Authorization: Bearer $TOKEN' -H 'Content-Type: application/json' \ --data '{'request':{'websiteId':1,'companyId':10,'customerId':25,'title':'Dostawa kwartalna','currency':'PLN','externalId':'ERP-RFQ-2026-001'}}'

7. Recommended integration scenarios

Purchase by SKU

  1. Read the website configuration and save the provided websiteId, companyId, and currency.
  2. Use quick order for batch validation of SKU, quantity, visibility, and availability.
  3. For accepted items, retrieve the price from price with the correct qty.
  4. Create an RFQ, add items, and send them via submit if the purchase requires a quote.
  5. Track RFQ status and history; after acceptance, follow the agreed Magento order process because V1 does not expose an order creation endpoint.

Documents and billing

  1. Retrieve the company document list, optionally filtering by documentType.
  2. For the selected document, retrieve metadata and the file list; the file path is not automatically a public URL — agree on the binary download method with the store administrator.
  3. Read the limit status before the purchasing process; only an integration with credit_limits ACL can manage it.

Asynchronous operations

  1. Save the integration profile and identifier mappings.
  2. Publish a job with a business idempotencyKey and keep the jobId.
  3. Read the job and logs/errors; call retry only after analyzing the error and removing its cause.

8. Pre-production acceptance list

  • The token has only the required ACL and is not an administrator token used by the UI.
  • The integrator correctly handles 401, 403, 404, 422 validation, 409 conflict, and timeouts.
  • Each request in the B2B context provides the correct websiteId, and company data uses the correct companyId.
  • Prices, visibility, and availability are checked before creating the purchasing process.
  • Company creation uses Idempotency-Key; integration jobs have a stable idempotencyKey in the body.
  • Logs do not contain tokens or sensitive data, and the support procedure provides trace_id.
  • Tests were performed in a test environment on a company that has an active relationship with the B2B website.

9. Compatibility

The contract is versioned by /V1. Extending responses with new fields is compatible; the integrator should tolerate unknown fields. A change that removes a field, field meaning, or endpoint requires a new API version. If there is a discrepancy between the document and the running installation, the active webapi.xml contract of the given module version is binding.

Module Installation Instructions

Kowal B2B Suite Installation and Configuration

This manual is intended for the person who purchased Kowal B2B Suite and needs to launch it in an existing Magento Open Source installation. It guides you through two stages:

  1. technical installation — performed by a developer or server administrator;
  2. business configuration — performed in the Magento panel by the store administrator.

Before you begin, create a backup of the Magento database and files. We recommend performing the first launch in a test environment and only then deploying to production.

1. What you receive and what you need

Kowal B2B Suite is delivered as the Composer package kowal/metapackage-b2b-suite. It includes B2B modules and the frontend/Kowal/b2b theme.

Requirements

ElementRequirement
MagentoMagento Open Source 2.4.9
PHP8.3
ComposerComposer 2
Server accessSSH and the ability to run bin/magento
Magentoworking catalog, customers, checkout, Sales, MSI, and cron
PDFwrite access to var/ for the PHP process

From Kowal, you will receive:

  • private Composer repository address — referred to below as REPOSITORY_URL;
  • user name or access identifier — USERNAME;
  • access token — ACCESS_TOKEN;
  • allowed package version range.

Do not store the token in the Git repository, tickets, or shell history shared with other people.

2. Technical installation

Run all commands in the root directory of the existing Magento installation, as a user with access to the files and to the bin/magento command.

2.1. Preparation

  1. Make sure Magento works correctly before the change.
  2. Save the deployment state and back up the database and the app/etc, pub/media, and var directories.
  3. In production, enable maintenance mode for the update:
bin/magento maintenance:enable

2.2. Adding the private repository

Add the Kowal Composer repository and configure the access credentials you received.

You will receive Composer repository access credentials, the customer email address and license token, by email after purchase. They are also available in the customer panel after logging in at kowal.store. Replace TWOJ_EMAIL_KLIENTA with your account email address and TWOJ_TOKEN with the token you received. Run the commands in the Magento root directory.

composer config repositories.kowal composer https://repo.kowal.store
composer config http-basic.repo.kowal.store 'TWOJ_EMAIL_KLIENTA' 'TWOJ_TOKEN'

Composer usually stores credentials in the local auth.json; do not add this file to Git.

2.3. Package installation

Install the version provided with the license. For the current package line, an example command is:

composer require kowal/metapackage-b2b-suite:^0.2 --with-all-dependencies

After downloading dependencies, update the Magento schema and configuration:

bin/magento setup:upgrade
bin/magento cache:clean

In production mode, also run:

bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f pl_PL en_US
bin/magento cache:flush

Use only the locales that are active in the store. If the installation uses a different deployment process, add the above commands to its standard procedure.

2.4. Installation verification

bin/magento module:status | grep Kowal
bin/magento indexer:status

The admin panel should show the B2B menu and the Stores > Configuration > Kowal > B2B tab. If they are missing, check the setup:upgrade result, cache, and the ACL roles of the administrator user.

2.5. PDF file permissions

PDFs generated by B2B use mPDF and directories under var/, including var/tmp/kowal_b2b_mpdf and var/kowal_b2b_documents. The PHP process must be able to create and write to them. Missing permissions result in document or PDF generation errors.

After completing the production deployment, disable maintenance mode:

bin/magento maintenance:disable

3. Configuring the B2B store structure

3.1. Website and store view

The suite operates at the website scope, not globally. You can run B2C and B2B in the same Magento installation, but B2B should operate on a separate website or on a deliberately selected business sales website.

  1. In Stores > Settings > All Stores, create or select the B2B website, its store, and store view.
  2. Note the website_id — it is used by companies, prices, documents, API, and integrations.
  3. In Content > Design > Configuration, assign the frontend/Kowal/b2b theme only to the B2B store view.
  4. Verify that active currencies, taxes, shipping methods, and payment methods are configured for the same scope.

Do not assign the B2B theme to a B2C store view if you do not want to change its presentation layer. Installing the modules alone does not enable B2B logic for all websites.

3.2. Activating B2B

  1. Open Stores > Configuration > Kowal > B2B.
  2. In the scope switcher, select the correct Website.
  3. In the General section, set Enable B2B to Yes.
  4. During implementation, you can enable Debug Mode; disable it after testing.
  5. In the Default Config scope, set the log retention period.
  6. Save the configuration and clear cache.

After activation, all store views belonging to this website are treated as B2B. A company without an active relationship with this website will not gain access to it.

3.3. Seller data

Complete the selling company data in Stores > Configuration > General > Store Information: name, address, phone, and tax ID. They are used in documents and RFQ PDFs. Also complete the general sender email address in Sales Emails configuration and the email logo if it should appear in PDFs.

4. Configuring the first B2B customer

Use the following order for each company. It helps avoid a situation where the customer has an account but cannot see the offer or proceed through checkout.

4.1. Company, people, and addresses

  1. Open B2B > Companies and create a company.
  2. Enter the name, tax ID, external identifier if the company is synchronized with ERP, Active status, and assignment to the B2B website.
  3. Add a company user or assign an existing Magento customer. Assign the correct role and activate the assignment.
  4. In B2B > Company Addresses, add company addresses; mark the default billing and shipping address for the B2B website.
  5. In B2B > Company Contacts, add an active primary contact with email and phone.

The billing address and primary contact are also used in RFQ PDFs. Missing data does not block the PDF, but the document will be less complete.

4.2. Company roles

Grant users only the permissions they need. A typical division is:

RoleExample tasks
Company administratorusers, roles, addresses, documents, and company history
Buyercatalog, quick order, cart, RFQ, and orders
Approverdecisions in the approval workflow
Accountingdocuments and billing information

Test an account of each type, especially permission to place orders and approve them. Do not use one shared account for the entire company.

5. Offer, pricing, and checkout

5.1. Catalog and prices

  1. Make sure Magento products are assigned to the B2B website, active, and have correct MSI data.
  2. Configure price lists or contract prices for the company in B2B > Pricing (Price Lists, Price List Assignments, or Contract Prices).
  3. Configure catalog visibility rules for the company according to the implemented permission model, then verify visibility on the customer account.
  4. Test on the company account: SKU search, product visibility, and price for quantity 1 and for the quantity tier.

The B2B price depends on company, website, currency, and quantity. A product visible in B2C does not have to be available to a B2B customer.

5.2. Shipping and payment

  1. Enable the required shipping and payment methods in the standard Magento configuration for the B2B store view.
  2. In B2B > Checkout, add rules for available methods for the company/website if you want to restrict selection.
  3. Run a cart test using the company default addresses.

If order creation from RFQ is expected to work automatically on the administrator side, the company must have unambiguous default addresses and active payment and shipping methods. Otherwise, the Suite will load the data into native Backend Order Create, where the administrator completes missing elements.

5.3. Limits and approvals

These features are optional, but they should be configured before enabling them for customers.

  1. In B2B > Credit > Payment Terms, add payment terms.
  2. In B2B > Credit > Credit Limits, assign a limit, currency, status, and payment term to the company.
  3. In B2B > Approvals > Rules, create an amount threshold rule for the company and website.
  4. In B2B > Approvals > Approvers, assign approvers.
  5. Test the cart below and above the threshold and verify whether the approver decision changes the next step of the process.

6. Documents, PDF, and RFQ

6.1. Magento documents

In Stores > Configuration > Kowal > B2B > Documents, select the document source and decide which documents should be generated automatically: order confirmations, invoices, delivery documents, and credit memos. Also set the target document status.

In B2B > Documents > PDF Templates:

  1. check the active template for each type and website;
  2. preview it;
  3. adjust HTML/CSS only if you have someone familiar with Magento templates and mPDF CSS;
  4. generate a test invoice or confirmation and verify download from the company account.

6.2. RFQ and quote PDF

  1. In B2B > Quotes > RFQ, create a test RFQ for an active company and user.
  2. Add SKUs visible to the company, quantity, and quoted price.
  3. Set the expiration date, send the quote to the customer, and generate the PDF.
  4. Check the customer variant: seller/buyer data, items, price, total, and expiration date.
  5. Check the administrator variant: additionally sales notes, comments, history, and internal item information.

The customer PDF must not contain salesperson notes or internal status history.

7. Quick orders, imports, and integrations

Quick orders

In B2B > Quick Order > Debug SKU, check the SKU,qty list for the company, website, and currency. Then create a shopping list and test its use by the customer on the storefront.

Import and export

In B2B > Import/Export, define a profile only after establishing the data source. Profile configuration is a JSON object and must contain file paths available on the Magento server. First run the import in test mode and analyze the job and logs.

API integrations

Before creating an integration token, define the data scope and synchronization owner. Use a separate Magento integration for each ERP, PIM, WMS, or middleware and grant only the required B2B ACL. The full list of endpoints, tokens, and security rules is available in the API documentation for integrators (request the current integration documentation from Kowal).

8. Acceptance checklist

Before production launch, confirm:

  • ☐Kowal modules are active, cron works, and cache and indexes are correct.
  • ☐B2B is enabled only for the correct website.
  • ☐The B2B theme is assigned only to the B2B store view.
  • ☐The test company has Active status, a user, role, contact, and default addresses.
  • ☐The test product is active, assigned to the website, visible to the company, and has the correct B2B price.
  • ☐The customer can log in, search for SKU, use quick order, and add a product to the cart.
  • ☐Checkout shows only permitted shipping and payment methods.
  • ☐The limit and approval rule work according to company policy if these features are used.
  • ☐The document and RFQ PDF generate and are available only to the correct company.
  • ☐RFQ can be sent, accepted, and passed to the order creation process.
  • ☐Integrations have separate tokens and restricted ACL if they are used.

9. Most common issues

SymptomWhat to check
No B2B menusetup:upgrade, module status, cache, and administrator ACL.
Company or customer does not see B2BWhether B2B is active for the correct website and whether the company has an active relationship with that website.
Product is not visible or has no priceProduct assignment to website, SKU activity, MSI data, catalog rules, company price, currency, and quantity.
No shipping or payment methodStandard Magento configuration, B2B store view scope, and B2B Checkout rules.
PDF is not createdActive PDF template, mPDF package, permissions for var/, seller data, and Magento logs.
RFQ does not create an order automaticallyDefault company addresses, unambiguous payment and shipping; in other cases, use Backend Order Create.
API returns 403The integration token does not have the required ACL; do not use an administrator token in an external application.

When contacting support, provide the Magento version, package version, reproduction steps, event time, safely anonymized logs, and any trace_id. Do not send tokens or passwords.

10. Package update

  1. Review the release information provided by Kowal.
  2. Perform the update first in a test environment.
  3. Create a backup, run composer update kowal/metapackage-b2b-suite --with-all-dependencies, bin/magento setup:upgrade, and in production also DI compilation and static asset deployment.
  4. Repeat the acceptance checklist, with special attention to prices, checkout, documents, and integrations.

Do not update the package by manually copying files to app/code; this causes Composer issues and makes future support more difficult.

Press to skip carousel

We found other products you might like!

Write Your Own Review
You're reviewing: Professional B2B System for Magento 2 Open Source
Your Rating:
Price
Quality
Support
loader
Loading...

You submitted your review for moderation.

Questions and Answers

Question
Does Kowal B2B Suite work with Magento 2 Open Source?
Answer
Yes. Kowal B2B Suite extends Magento 2 Open Source with B2B sales features, allowing many wholesale and contract sales processes without moving to Adobe Commerce.
Question
Can each B2B customer have individual prices and product catalogs?
Answer
Yes. The system can represent individual trading terms, including prices, catalogs, quantity thresholds and purchasing rules. The configuration scope is adapted to the company's sales model.
Question
Can one company have multiple users with different permissions?
Answer
Yes. A single business account can have multiple users and purchasing roles. This allows separation of ordering, approval and access to data and documents.
Question
Can the B2B system integrate with ERP, PIM, WMS or CRM?
Answer
Yes. Kowal B2B Suite can exchange data with external systems, including ERP, PIM, WMS and CRM. Integration can cover products, prices, customers, orders, documents, statuses and other data required by the specific business process.
Question
Can a B2B platform be deployed in stages?
Answer
Yes. Deployment can start with basic features such as companies, users, prices and catalogs, then expand to quick orders, RFQ, credit limits, approvals, documents and integrations.
Update cookie preferences