Integration landscape

The map

There is no API gateway. The application holds ~15 base URLs and each service wrapper reads the one it needs from AppConfigService.

                          ┌────────────────────────────────┐
                          │        Internal Admin          │
                          └──┬──────┬───────┬──────┬───────┘
        X-Session-Token ─────┘      │       │      │
                                    │       │      │
  ┌─────────────────────────────────▼──┐    │      │
  │ internalApiUrl   database_v2/internal   │      │
  │  suppliers, marketplaces links, payment │      │
  │  configs, deposit accounts, fees,       │      │
  │  reserves, reports, logins, perms,      │      │
  │  lookups, advances, UCC, pending_review,│      │
  │  paymentBatches, search2/search3        │      │
  └─────────────────────────────────────────┘      │
  ┌───────────────────────┐  ┌─────────────────────▼──────┐
  │ cliApiUrl             │  │ actionsToolsUrl            │
  │  database_v2/cli      │  │  CRM activity + settings   │
  │  scripted/bulk ops    │  │  notes, tasks, files,       │
  └───────────────────────┘  │  filters, global settings   │
                             └────────────────────────────┘
  ┌───────────────────────┐  ┌────────────────────────────┐
  │ eventLoggerUrl        │  │ eventRulesOldUrl           │
  │  event stream,        │  │  event rules v1 +           │
  │  es-changelog, track  │  │  Elasticsearch em_events    │
  └───────────────────────┘  └────────────────────────────┘
  ┌───────────────────────┐  ┌────────────────────────────┐
  │ messagingUrl          │  │ authToolsApiUrl            │
  │  outbound email/SMS   │  │  supplier tokens, SMS nums  │
  └───────────────────────┘  └────────────────────────────┘
  ┌───────────────────────┐  ┌────────────────────────────┐
  │ workflowApiUrl (+GCI) │  │ automaticMarketplaceApiUrl │
  │  b2btaskmanager       │  │  automatic UW tool,         │
  │  jobs + SSE stream    │  │  real-time validation       │
  └───────────────────────┘  └────────────────────────────┘
  ┌───────────────────────┐  ┌────────────────────────────┐
  │ marketplaceApiUrl     │  │ supWidgetsApiUrl           │
  │  marketplace service  │  │  onboarding widgets         │
  └───────────────────────┘  └────────────────────────────┘
  ┌──────────────────────────────────────────────────────┐
  │ Four document/file backends                          │
  │  b2bDocumentsApiUrl · pybDocumentsApiUrl ·           │
  │  documentsApiUrl · s3FilesProviderApi                │
  └──────────────────────────────────────────────────────┘
  ┌───────────────────────┐  ┌────────────────────────────┐
  │ evaApiUrl (iframes,   │  │ supplierUrl /               │
  │  postMessage, cookie) │  │ supplierReferralUrl         │
  └───────────────────────┘  └────────────────────────────┘

  Third parties reached directly from the browser:
    Google Identity (SSO) · Segment analytics.js · Google Analytics ·
    TinyMCE assets (self-hosted) · Sentry DSN configured but unused in code

Payability backends

Base URL key Service Primary consumers

internalApiUrl

The main internal API (database_v2/internal, bin/internal on prod). The system of record for suppliers, money and configuration.

~35 services — SupplierService, PaymentConfigService, DepositAccountService, SupplierFeesService, SupplierAdvancesService, SupplierMarketplacesService, UsersService, LookupRepository, ReportsRepositoryService, ExternalReportsService, PaymentBatchRepositoryService, BalanceApprovalService, PendingReviewService, UccService, SearchEngineService, VersionService, CardManagementService, FeeSettingsService, WinbackService, SupplierComplianceActionService, SupplierEmailPreferencesService, LongTermContractsService, PybDocumentsService, and others.

cliApiUrl

The CLI service (database_v2/cli) — scripted and bulk operations.

CliService, CliActionService, BatchImportService, SupplierService.

actionsToolsUrl

Actions Tools — CRM activity storage and the global key/value settings store.

CrmService, CommentsService, TasksService, TasksFiltersService, GlobalSettingsService, BatchImportService, WaitingSuppliersReportComponent.

eventLoggerUrl

Event logger v2 — the domain event stream, the Elasticsearch changelog (es-changelog) and the analytics track endpoint.

CrmService (event stream), MonitorService (tracking).

eventRulesOldUrl

Event logger v1 — event-rule CRUD (event_rules/), rule history (event_rules/history/) and a raw Elasticsearch endpoint (es, index em_events).

EventsService (manage/event-rules/).

messagingUrl

Messaging — outbound email and SMS.

EmailsService, CrmService, SmsNumbersProviderService.

authToolsApiUrl

Auth tools — supplier auth-token issuance and SMS number provisioning.

SupplierAuthTokenService, SmsNumbersProviderService.

workflowApiUrl + workflowGciId

B2B task manager — long-running jobs (earnings/remittance loads) plus a server-sent-events progress stream (tasksMonitoring) and getLastExecution. workflowGciId is a build-time correlation id generated by deployment/generate_gci.py (hardcoded to 1 on production).

B2bWorkflowService, BatchImportService.

marketplaceApiUrl

Marketplace service — supplier-marketplace data.

SupplierMarketplacesService.

automaticMarketplaceApiUrl

Automatic underwriting tool web API.

SupplierUnderwritingService, RealTimeValidatorService.

supWidgetsApiUrl

Supplier widget endpoints used during onboarding.

SupplierOnboardingService.

b2bDocumentsApiUrl

B2B document service.

B2bDocumentService, BatchImportService.

pybDocumentsApiUrl

PYB documents service — behind the PYB_DOCUMENTS feature flag.

PybDocumentsService.

documentsApiUrl

Documents Lambda — deposit-account documents.

DepositAccountService.

s3FilesProviderApi

S3 file provider.

Configured in IEnvironment; used by file-download paths.

supplierUrl

The supplier self-service site — target for "log in as supplier".

LoginAsSupplierService.

supplierReferralUrl

Referral link base.

SupplierReferralService.

evaApiUrl

EVA micro-front-end origin. Not an HTTP API from this app’s perspective — it is an iframe src plus a postMessage channel plus a shared-domain cookie.

EvaService, EvaCommunicationService, CommunicationService.

Endpoint-level detail is in services and endpoints; the environment values per stage are in environment configuration keys.

Authentication across integrations

Mechanism Where

X-Session-Token: <jwt>

Added to every HttpClient request by AuthInterceptor, regardless of which host it goes to. All Payability backends accept it.

Authorization: Basic <base64>

Only the login call (internalApiUrl + auth/login), constructed inline in AuthEffects.

Authorization: <jwt> (no scheme)

CrmService sets the raw token as Authorization for Actions Tools, in addition to the interceptor’s header.

Authorization: Token <literal>

`MonitorService’s event-logger call — a hardcoded credential. Known debt.

X-InstanceId / X-EventLogger-InstanceId

env.instanceId (8001) for event rules, global settings and CRM; MonitorService hardcodes 8003.

X-Actions-TargetUUID / X-EventLogger-TargetUUID

The CRM "what is this about" key — kept in sync by a store subscription inside CrmService.

EVA cookie

EvaService writes the token into a cookie on environment.domain so the iframe can read it; on localhost it appends ?auth=<token> to the iframe URL instead.

Google ID token

Exchanged for a Payability JWT via LookupRepository.getAuthGoogleLogin.

See authentication for the flows.

Third parties in the browser

Provider Integration

Google Identity

googleAuthClientId in IEnvironment (the same client id in dev and prod templates). The login component uses gapi.auth2 typings; the credential is posted to the internal API for exchange. Only specific localhost ports are registered with Google — see local development.

Segment (analytics.js)

MonitorService inlines the standard Segment snippet, loading cdn.segment.com/analytics.js/v1/<frontendSegmentIOCode>analytics.min.js. Used for identify and track. window.onerror in main.ts also tracks WINDOW ERROR.

Google Analytics

MonitorService inlines the classic analytics.js GA snippet under the global name fga.

Elasticsearch

The elasticsearch npm client runs in the browser against eventRulesOldUrl + 'es', index em_events, passing X-Session-Token explicitly. Only manage/event-rules/events.service.ts does this.

TinyMCE

Self-hosted: the build copies node_modules/tinymce to /tinymce/.

Sentry

sentryUrl is present in IEnvironment and identical across templates, but no Sentry SDK is installed and no code reads the key. AppErrorHandler merely advises "Check sentry logs or run in dev mode." Treat Sentry as not wired up from this application.

Plaid

Reached indirectly — bank-transaction data arrives through the internal API’s external-report endpoints (ExternalReports.PLAID = 'PLAID-D') and the supplier-payment Plaid information service, not via a Plaid browser SDK.

Marqeta / Airwallex / EFS

Card issuing. All reached through the internal API’s card-management endpoints — the app never calls the issuers directly. See cards.

Real-time and cross-window channels

Channel Detail

Server-sent events

SseService uses EventSourcePolyfill from ng-event-source so that the X-Session-Token header can be sent (native EventSource cannot). It reads the token by subscribing to the auth slice and marshals messages back into the Angular zone with NgZone.run. Consumed by B2bWorkflowService.taskMonitoring(). See real-time streams.

postMessage

The EVA protocol: CommunicationService with a typed MESSAGE_TYPE enum, origin checks against environment.domain, per-iframe pluginIframeId addressing, and document.domain assignment. See iframe messaging and EVA.

Browser extension

messageCodes.installExtension and the "Payability Extension not Installed" message indicate a companion browser extension used by the login-as-supplier and Amazon-login flows (PybExtensionService).

VPN gating

VpnTesterService, started by AppComponent when the CHECK_VPN flag is on, probes whether the operator is on the corporate network. It is a soft check that warns rather than blocks; the authoritative network restriction is enforced upstream of the application.

Adding a new integration

  1. Add the base URL to IEnvironment (src/environments/environment.interface.ts).

  2. Add the corresponding export to both deployment/setup_template-dev.cfg and deployment/setup_template-production.cfg.

  3. Add the field to the generated template in deployment/set-env.ts.

  4. Regenerate your local environment (./deployment/setenv.sh exp) — do not hand-edit src/environments/environment.ts, it is overwritten.

  5. Read it in the service via AppConfigService, never import { environment }.

  6. Document it here and in environment configuration keys.

Missing any of steps 2–3 produces the classic failure: the key is undefined in CI/deployed builds while working locally. See environments.