mar-pod-b2b / module-b2b-company-credit
Company credit accounts, ledger, reservations, and payment integration for Marpod B2B.
Package info
gitlab.com/mar-pod-b2b/module-b2b-company-credit
Type:magento2-module
pkg:composer/mar-pod-b2b/module-b2b-company-credit
Requires
- php: ^8.5
- magento/framework: ^103.0
- magento/module-graph-ql: ^100.4
- magento/module-payment: ^100.4
- magento/module-sales: ^103.0
- magento/module-store: ^101.1
- magento/module-webapi: ^100.4
- mar-pod-b2b/module-b2b-company: ^1.0
- mar-pod-b2b/module-b2b-core: ^1.0
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-08-24 16:10:52 UTC
README
Per-company trade credit: a limit, a reservation-then-settlement ledger, and a checkout payment method restricted to authorized companies.
Status
Full ledger engine, Admin UI (account list/edit + a manual-adjustment action), and a Magento payment method integration are all shipped. This is not an accounting system — it models a simple limit/reserve/settle credit line, not general ledger accounting; integrate with an ERP through the service contracts below if real accounting is required.
Implemented foundation
- declarative schema:
marpod_b2b_company_credit_account(one row per company: limit, currency),marpod_b2b_company_credit_entry(an immutable append-only journal — balance is never overwritten directly, only derived from summing entries),marpod_b2b_company_credit_reservation(one row per order, linking a reservation to the order that created it); CreditLedgerInterface::getAvailableBalance()— limit minus active reservations minus posted debits plus posted credits, computed live from the entry journal, not a cached/denormalized column;CreditLedgerInterface::reserveForOrder()— reserves credit at order placement time; the reservation is looked up and released or consumed later by order ID, so operations are naturally idempotent per order (marpod_b2b_company_credit_reservationlinks 1:1 to an order);releaseReservationForOrder()— called on cancellation, moves the reservation toreleased, freeing the credit back to available balance;postDebitForInvoice()/postCreditForRefund()— append immutable ledger entries (CreditEntryTypeInterface::DEBIT/CREDIT) rather than mutating any stored balance;CreditEntryTypeInterface(debit/credit) andCreditReservationStatusInterface(active/released/consumed) are the frozen vocabularies for the journal and reservations.
Admin UI
Marpod_B2bCompanyCredit::manage provides an account grid and edit screen
(marpod_b2b_company_credit/account/index / edit / new) to set a company's credit limit and
currency, plus a manual-adjustment action for out-of-band corrections that still go through the
same immutable-journal CreditLedgerInterface methods rather than a direct balance edit.
The edit screen follows Magento's native customer-edit pattern. General settings, manual adjustments, ledger history, and reservations are separate tabs. POST actions restore the relevant tab after redirect. Ledger and reservation grids include filters, record totals, page-size controls, and previous/next pagination.
REST and GraphQL
Administrative REST routes below /rest/V1/marpod-b2b/company-credit require the
Marpod_B2bCompanyCredit::manage ACL resource. They expose account lookup/list/save, ledger
entries, reservations, and manual adjustments.
Authenticated customers can query marpodB2bCompanyCredit(pageSize, currentPage) through GraphQL.
The company is resolved from the customer token and current website; callers cannot submit a
company ID. Ledger results are paginated, with a maximum page size of 100.
Run the Admin/API smoke test from the module's Test/Playwright directory with npm test.
Storefront
A "Company Credit" page under My Account (for customers whose account is assigned to a company) shows the account's credit standing — not shown to guests or customers with no company.
Checkout integration
A "Company Credit" payment method (Stores > Configuration > Sales > Payment Methods, disabled
by default) is available in checkout only to companies with an active credit account and enough
available balance — see Model/Payment/CompanyCredit. Enable it and set a title/default order
status before using it in a live checkout.
Requirements
- PHP 8.5
- Magento 2.4.9-compatible framework packages
mar-pod-b2b/module-b2b-core,mar-pod-b2b/module-b2b-company
Installation
Run from the Magento project root:
composer require mar-pod-b2b/module-b2b-company-credit:^1.1
bin/magento module:enable Marpod_B2bCompanyCredit
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean
Then enable the "Company Credit" payment method in
Stores > Configuration > Sales > Payment Methods before it appears at checkout.
Development
The planned scope, dependency rules, cache boundaries, security requirements, and test strategy
are documented in packages/B2B_LIGHT_PLAN.md in the development Magento project.
Unit tests:
vendor/bin/phpunit -c dev/tests/unit/phpunit.xml.dist packages/module-b2b-company-credit/Test/Unit
REST/GraphQL API tests (real HTTP against a running instance — routing, authentication, ACL
enforcement, and cross-company isolation; see mar-pod-b2b/module-b2b-core's README for the
shared Test/Api base classes these build on):
vendor/bin/phpunit -c dev/tests/api-functional/phpunit_rest.xml \
packages/module-b2b-company-credit/Test/Api/Rest/CreditAccountRestTest.php
vendor/bin/phpunit -c dev/tests/api-functional/phpunit_graphql.xml \
packages/module-b2b-company-credit/Test/Api/GraphQl/CompanyCreditGraphQlTest.php
Limitations
- not an accounting system — no multi-currency conversion, no tax handling beyond what the order itself already carries, no export to an external ledger;
- no automated dunning/collections workflow for overdue balances.
Uninstallation
Do not remove the package while another installed module requires it. The
marpod_b2b_company_credit_* tables contain business data (including the immutable journal) and
are retained when the module is disabled or its package is removed. Disable the payment method
in configuration first so no new orders are placed against a credit line about to be removed.