Hello. I’m imamu, a Backend Engineer on Merpay’s Payment & Customer Platform (PCP) team. This article is Day 6 of Merpay & Mercoin Tech Openness Month 2026.
Introduction
"Partner invoicing" is a deferred payment method for partners (such as merchants and business partners). At the time of each transaction, the platform handles the payment on the partner’s behalf, then later invoices and collects the amount in a consolidated manner. For partners, this eliminates the need to pay per transaction and allows them to use the service without worrying about cash flow each time.
Because the platform pays in advance and collects later, it takes on a critical responsibility: safely managing each partner’s credit limit. If this breaks down, uncollectible receivables can accumulate and become a major business risk.
In this post, I’ll introduce four key design points we considered when we extracted the credit-related features into a dedicated Credit Service to enable partner invoicing. We focused on (1) ownership/boundaries, (2) decoupling credit vs invoicing, (3) multi credit lines, (4) lifecycle-aware transactions.
Background: How partner invoicing worked previously
With partner invoicing, the platform advances payment at the time of transactions and later invoices and collects the total. Conceptually, the lifecycle looks like this:

Traditionally, there were three main ways to implement this:
- Using an external post-payment service: some products relied on a third-party post-payment provider for both credit management and billing, but it was difficult to adapt risk controls and billing operations to our product-specific requirements, and manual processes were often unavoidable.
- Using an external billing agency: outsource billing operations such as invoice issuance and delivery. However, transactions could still be accepted even when they exceed the intended limit because the credit limit is not managed in our own systems.
- Corporate card payment and billing: operate with per-partner card spending limits. In this model, failures could surface only later in the payment pipeline (e.g., at the capture/settlement stage because we would not be able to track “how much is available right now” in our own systems). In practice, this meant that transactions could fail after the user had already completed the purchase flow, forcing cancellations and hurting end customers’ experience—and increasing operational burden for partners.
All three approaches enabled partner invoicing, but none provided a mechanism to centrally manage partner credit within our own platform.
Problem: Why credit management became necessary
The approaches above all made partner invoicing possible, but when products have different operational patterns and requirements, a shared problem remained: we could not centrally manage credit and receivables per partner across products. However, because this deferred payment model is expected to be used by multiple products, the platform is required to satisfy the following simple invariant:
Total receivables held across all products < the partner’s credit limit
For example, if a partner’s credit limit is 100, we must not allow a situation where Product A uses 60 and Product B uses 60 concurrently and the total becomes 120. With credit decisions split across products and/or external services, it is easy for this invariant to be broken.
Therefore, our goal was to provide credit management as a platform capability that satisfied all of the following:
- Centralized credit and receivables management across products
- Always enforce the invariant above.
- Safely accept transactions before execution
- Decide “how much can be used now”, and reserve credit, if needed, before starting a transaction.
- Seamlessly connect to billing, repayment, and settlement
- Follow transaction state changes and naturally connect to downstream billing and collection flows.
To achieve this, we designed credit management as an independent microservice.
Design: Four key design points
We designed the system based on the following service-integration use case:

First, the Payment Service receives payment requests from each product—because its responsibility is to provide payment methods and manage the state of payment resources. The Payment Service then asks the Credit Service to use (and if needed reserve) credit, and the Credit Service registers the resulting receivable in the Debt Service, which owns receivables management. The Invoice Service aggregates those receivables and issues invoices. We designed this collaboration from the following four perspectives.
In this article, we use receivables to refer to outstanding amounts owed to the platform. These receivables are managed by the Debt Service.
1. Consolidating credit-management responsibilities into one service
The first decision was: “Which service should own the credit domain knowledge?”
If we brought credit-domain knowledge—such as credit line management and available amount calculation—into Payment Service, it would expand beyond its intended scope. Instead, we consolidated the following responsibilities into Credit Service:
- Determining the overall credit limit (fixing the limit as the result of partner screening)
- Creating/updating credit lines (managing configurable lines per product)
- Calculating available amounts (computing how much can be used now)
- Consuming credit (reserving/using credit and requesting receivable registration)
We intentionally did not separate “screening” (setting limits) from “usage” (spending limits). This allows Payment Service to call a single operation—“use credit”—while the sequence of checks, consumption, and receivable registration stays encapsulated within Credit Service.
Also, to enforce the cross-product invariant atomically, we needed a single place that owns credit usage. Consolidating responsibilities was therefore a design decision derived from clear domain boundaries and invariants.

2. Decoupling credit from invoicing
Next, we designed with the premise that the unit of credit is not the same as the unit of invoicing:
- For credit, we manage the amount available for a given partner credit line (CreditLine).
- For invoicing, we manage invoicing the outstanding amount for a given invoice account (InvoiceAccount)
From these observations, we can see that tightly coupling credit and invoicing would force us into a situation where merely changing the invoicing granularity would lead to rebuilding the credit side as well. They are fundamentally different concerns and should remain loosely coupled.
Here’s how we achieved it: when Credit Service consumes credit and registers a receivable, it passes aggregation attributes to Debt Service—namely “which invoice account this belongs to” and “which credit line this belongs to.” Debt Service supports listing and aggregating receivables by multiple axes, so:
- Credit Service can calculate usage from outstanding receivables on the credit-line axis
- Invoice Service can issue invoices from receivables for a period on the invoice-account axis

With this, we can manage credit at the partner level while invoicing at, for example, a branch level. The key is that Debt Service treats aggregation axes as a core part of its domain model. Credit Service cares only about the credit-line axis; Invoice Service cares only about the invoice-account axis; and Debt Service performs the aggregation per axis. As a result, we can design credit granularity (CreditLine) and billing granularity (InvoiceAccount) independently. [1]
3. Allow a single partner to have multiple credit lines
Instead of having only one credit line per partner, we designed the system so that each partner can have multiple credit lines (CreditLine). The Credit Service API allows products to control credit-line granularity per partner—for example, by creating separate lines per store or per department—enabling flexible usage controls per product.
However, even with multiple lines, the partner’s overall credit limit (CreditLimit) must not be exceeded. Therefore, the effective available amount is the smaller of the credit line’s availability and the partner-wide availability:
Effective available amount = min(available for CreditLine, available for partner CreditLimit)
Here, it’s important to distinguish two similar-but-different “limits”:
| CreditLimit | CreditLine | |
|---|---|---|
| Meaning | The hard ceiling we must never advance beyond | A configurable operational line the partner can split/manage |
| How it’s set | Result of credit screening | Configured by products via the Credit Service API |
| Who can change it | No | Yes (products via API) |
By separating the “hard limit” determined by screening and the “flexible operational lines” used in day-to-day operations, we achieve both safety and flexibility.
4. Model credit usage as stateful transactions aligned with the lifecycle
Using credit is not a single-step operation. Real transactions often have a time gap between reserving credit and finalizing the transaction, and they may be canceled partway through. We therefore manage credit usage as credit transactions (CreditTransaction) with multiple phases.
We handle three phases: Authorize (reserve credit at the start), Capture (finalize as a receivable at confirmation), and Cancel (release reserved credit before capture). This allows us to manage credit consumption and release consistently even as a transaction’s state changes.

Make the reservation timing selectable (ReservationPolicy)
The timing and method of reserving credit vary by product. We therefore introduced ReservationPolicy so the same Credit Service can be used in different ways depending on requirements.
| Reservation style | Behavior |
|---|---|
| Provisional (PROVISIONAL) | Reserve credit with a provisional receivable at request time, convert it to a finalized receivable on capture, and release it on cancel |
| Check then capture (CHECK_THEN_CAPTURE) | Only check availability at request time, then reserve and capture in one step at confirmation time |
| Immediate (IMMEDIATE) | Reserve and capture simultaneously at request time |
Support cancellations after capture (Reversal)
Operationally, cancellations may occur after a reservation has been captured. In that case, it’s not enough to simply release credit; we must also decide how to handle the already-registered receivable. We support post-capture cancellations as Reversal.
In Reversal, we split the amount to be reversed into an unpaid portion and a paid portion based on the receivable’s remaining balance. The unpaid portion can be voided by canceling the receivable itself. The paid portion cannot be canceled, so we return it as the refund amount so the caller (Payment Service) can issue a refund. This provides consistent handling across the full lifecycle: authorize → capture → cancel/refund.
End-to-end view: making the entire platform work as one system
The Credit Service we’ve discussed is not stand alone system. The platform already had services with clear responsibilities—Payment, Debt, Invoice, Bank, Balance, Settlement, and so on. The addition of Credit Service allowed these services to keep focusing on their own scopes while enabling end-to-end support for payments, credit management, invoicing, and settlement across the entire platform.

With this architecture, new products can seamlessly support partner invoicing. To set it up, the only things a product needs to create are a credit line (CreditLine) and an invoice account (InvoiceAccount). Without modifying the rest of the platform services, the product’s transactions naturally fit into the lifecycle from credit check, to payment, invoicing, and repayment.
Conclusion
By introducing the credit-management microservice, we were able to realize partner invoicing as a Payment Platform capability.
The Payment Platform will continue to evolve, but our core design principle—“each service has clear responsibilities and collaborates through loose coupling”—will remain the same. Under this principle, we aim to keep building a safe, extensible payment foundation.
The next article is by nanacom. Stay tuned.
[1] This “aggregating receivables by arbitrary axes” is itself a separate design theme, and we plan to cover it in more detail in another article.




