Integration
1. Sister Services
Direction:→calls /←called by /↔bidir.
| Sister | Direction | Surface | Contract | Auth | Failure Mode |
|---|---|---|---|---|---|
@nx/sale | ← | Kafka PAYMENT_SUCCESS | TSalePaymentSuccess | — | at-least-once; guard on non-COMPLETED / existing invoice |
@nx/commerce | ← | Kafka Merchant CDC (Debezium) | TDebeziumMessage<TMerchantPgRow> (metadata.tax) | — | at-least-once; op=u diff-skip |
@nx/commerce | ← | HTTP webhook /webhooks (commerce callback) | HMAC-SHA256 signed | WEBHOOK_INTERNAL_SECRET | reject on bad/missing signature |
@nx/identity | → | JWT verification via JWKS | VerifierApplication | JWT (ES256) | request rejected if unverifiable |
2. External Systems
Two adapter layers wrap the external e-invoice providers; the DB provider enum maps to the iiapi enum via
InvoiceProviderMapper(src/common/providers.ts).
| System | Layer | Direction | Surface | Auth | Credential source |
|---|---|---|---|---|---|
| VNIS | @nx/iiapi | → | e-invoice issuance | client id/secret | core Configuration row VNIS_DEFAULT_CONNECTION (encrypted) + APP_ENV_VNIS_* defaults |
| VNPAY | @nx/iiapi | ↔ | issuance + inbound webhook callbacks | per-merchant username/password | InvoiceProvider row (AES-256-GCM encrypted) |
| T-VAN (VNPAY provider) | @nx/t-van | → | transaction-VAN gateway | API key | core Configuration row TVAN_DEFAULT_CONNECTION (encrypted credential) |
Adapter registration (at boot):
| Component | Registers | With |
|---|---|---|
InvoiceProviderConnectionComponent | VNIS + per-merchant InvoiceProvider clients | @nx/iiapi |
TVanConnectionComponent | T-VAN client from TVAN_DEFAULT_CONNECTION | @nx/t-van |
Provider mapping (InvoiceProviderMapper):
DB (InvoiceProviders) | iiapi (IIAPIProviders) |
|---|---|
VNPAY | VNPAY |
Only
VNPAYis in the DB↔iiapi map today;toIIAPI/toDBthrow on unknown providers.
3. Critical Cross-Service Flows
3.1 Merchant tax-info (MST) — input → authoritative TaxInfo
Contract:
metadata.taxin commerce is the input;TaxInfo (principalType=Merchant)is the authoritative record.- Change detection diffs against the persisted
TaxInfo, not Debezium's before-image (correct regardless of REPLICA IDENTITY). - The frontend reads the
merchant.taxInforelation, nevermetadata.tax. op=uupsert is tax-only;op=c/ralso creates the profile and (ifmetadata.eInvoicepresent and merchant eligible) a VNPAYInvoiceProvider.
3.2 Issuance via provider adapters
Contract: eligibility is gated by (businessType, taxMethod) → ALLOWED_INVOICE_TYPES. REAL_TIME / BUYER_SELF_SERVICE modes require TaxMethods.DIRECT.
3.3 Inbound webhooks
| Webhook | Secret env | Verification |
|---|---|---|
VNPAY/iiapi callback (vnpayIIAPICallback) | APP_ENV_INVOICE_WEBHOOK_SECRET | provider signature header |
Commerce callback (commerceCallback) | APP_ENV_INVOICE_WEBHOOK_INTERNAL_SECRET | HMAC-SHA256 verifyWebhookSignature |
4. Contract Stability
| Surface | Stability | Versioning |
|---|---|---|
HTTP /v1/api/* | stable | URL prefix /v1/ |
Kafka PAYMENT_SUCCESS (consume) | stable | field-additive |
Kafka Merchant CDC (consume) | stable | Debezium envelope |
| iiapi / t-van adapter | external | provider-versioned (VNIS/VNPAY/T-VAN APIs) |
Webhook /webhooks | stable | signature header |
5. Related Pages
- API Events
- T-VAN Integration — provider feature detail
- Decisions