---
title: "Observe or enforce one ERP vendor payment against the tenant's payment checks"
method: POST
path: "/v1/guard/payments/validate"
deprecated: true
---

# Observe or enforce one ERP vendor payment against the tenant's payment checks

`POST /v1/guard/payments/validate`

## Request

- Base URL: `https://api.decionis.com`
- URL: `https://api.decionis.com/v1/guard/payments/validate`
- Auth: API key in header `X-Decionis-API-Key`

> **Deprecated.**

Deprecated alias of `POST /v1/connections/{connectionId}/executions`: the same handler, which answers this payment contract unchanged for the installed Business Central extension 1.0.2.3. The Payment Release Guard. A native ERP shell states one vendor payment it is releasing and the facts it holds; Commerce Gate asks Decionis to evaluate it as a commerce-preflight-v2 PAYMENT_RELEASE with the caller's own organization key and answers the tenant's policy for P12 payment release authority, P13 duplicate invoice, P14 beneficiary change window and P15 liquidity floor. In OBSERVE mode the shell asks after posting, Decionis records a Shadow decision and `enforced` is false: nothing is blocked. In ENFORCE mode the shell asks before posting, Decionis records an enforced decision, `enforced` is true, and the shell stops the posting on HOLD or BLOCK; an enforced request states no posted entry (400 PAYMENT_ENFORCE_AFTER_POSTING). Commerce Gate only answers: nothing here initiates, holds, routes or settles a payment. Account numbers never cross this boundary; the beneficiary facts carry only when the vendor's bank account last changed and whether that change was verified. Business Central requires the full native_context captured from the context endpoint. Core rechecks the current workspace key, connection and native read grant; every organization, workspace environment, tenant, company, environment name and revision assertion must match. Registration metadata does not independently verify the native shell's payment facts or authorize posting. The resolved metadata and its evidence boundary remain in the saved evidence and response. Exact OBSERVE retries return the saved receipt; ENFORCE retries recheck the original upstream decision without replacing it. A separate after-post OBSERVE result does not change an earlier ENFORCE decision. F&SCM retains its existing credential/tenant binding and does not accept native_context. A 502 means Decionis did not return a bound evaluation in the requested mode, and a 503 PAYMENT_ENFORCEMENT_DISABLED means enforcement is switched off centrally; an observing shell retries and an enforcing shell applies its own fallback mode. This is an unreleased source candidate that needs the matching backend and a tenant policy whose allowed sources include the ERP's source name.

## Headers

- `X-ERP-Region` string, required

## Request body

- PaymentGuardRequest
  - `transaction_id` string, required
  - `erp_type` 'D365_BC' | 'D365_FSCM', required
  - `tenant_id` string, uuid, required
  - `native_context` NativeContext: Pinned non-secret expectations from the registered connection. Organization and workspace fields are assertions only; the current workspace key supplies authority. workspace_environment is Core's current classification of its synchronized Accounts workspace, not refreshed provider evidence, and is distinct from environment_name.
    - `version` 'commerce-native-context-v1', required
    - `org_id` string, uuid, required
    - `workspace_environment` 'sandbox' | 'production', required
    - `connection_id` string, uuid, required
    - `expected_revision` integer, required
    - `environment_name` string, required
    - `company_id` string, uuid, required
  - `timestamp` string, date-time, required
  - `agent_id` string, required
  - `mode` 'OBSERVE' | 'ENFORCE', required
  - `payment` object, required: Exactly the commerce-preflight-v2 PAYMENT_RELEASE payload. Each field maps from the ISO 20022 pain.001.001.09 credit transfer the ERP already produces for its bank (paths relative to PmtInf); account elements are never read.
    - `payment_id` string, required: pain.001 CdtTrfTxInf/PmtId/EndToEndId
    - `vendor_id` string, required: pain.001 CdtTrfTxInf/Cdtr/Id/OrgId/Othr/Id, the creditor's id in the ERP
    - `invoice_id` string: pain.001 CdtTrfTxInf/RmtInf/Strd/RfrdDocInf/Nb, only when exactly one referred document is a commercial invoice (CINV)
    - `amount` number, required: pain.001 CdtTrfTxInf/Amt/InstdAmt
    - `currency` string, required: pain.001 CdtTrfTxInf/Amt/InstdAmt/@Ccy
    - `due_at` string, date-time: pain.001 ReqdExctnDt/DtTm, else ReqdExctnDt/Dt at 00:00 UTC
    - `rail` 'ach' | 'wire' | 'card' | 'stablecoin' | 'other': pain.001 PmtTpInf/SvcLvl/Cd URGP or SDVA is wire; LclInstrm/Cd CCD, PPD or CTX is ach; SvcLvl/Cd SEPA or NURG is other; otherwise omitted
  - `facts` object, required
    - `observed_at` string, date-time, required
    - `payment` object
      - `prior_payment_count` integer
    - `beneficiary` object
      - `changed_at` string, date-time, nullable
      - `verification` 'verified' | 'unverified' | 'pending'
    - `treasury` object
      - `cash_position` number
      - `run_total` number
  - `payment_evidence` PaymentEvidence: A complete native snapshot with exact journal, payable invoice, beneficiary and funding revisions. Core independently reads the same source and current managed case before authorizing the payment. This envelope is evidence, never caller-provided approval.
    - `version` 'commerce-payment-evidence-v1', required
    - `method` 'ledger_cash_same_currency_single_payment_v1', required
    - `source` object: Fresh native environment and company observations, included in the stable snapshot and pre-posting comparison. Optional for earlier records; absence does not prove isolation. Both must be true for the separately authorized self-reviewed sandbox test.
      - `sandbox` boolean, required
      - `evaluation_company` boolean, required
    - `journal_id` string, uuid, required
    - `journal_revision` string, required
    - `batch_id` string, uuid, required
    - `batch_revision` string, required
    - `invoice_entry_id` string, uuid, required
    - `invoice_revision` string, required
    - `invoice_remaining_amount` number, required
    - `funding_bank_id` string, uuid, required
    - `funding_bank_revision` string, required
    - `beneficiary_bank_id` string, uuid, required
    - `beneficiary_bank_revision` string, required
    - `source_revisions` object, required
      - `run` string, required
      - `invoice` string, required
      - `treasury` string, required
    - `snapshot_sha256` string, required
  - `posted` object: The ledger entry the payment produced, stated by the ERP after posting. Commerce reconciles it against the evaluated payment and records drift when the payment posted while the answer was HOLD or BLOCK, or posted with a different amount, currency or vendor. Never a policy fact; never sent to Decionis.
    - `entry_id` string, required
    - `vendor_id` string, required
    - `amount` number, required
    - `currency` string, required
    - `posted_at` string, date-time, required

## Response `200`

The tenant's policy answer; enforced exactly when the request was ENFORCE

- PaymentGuardResponse
  - `authorization` PaymentAuthorization
    - `attempt_id` string, uuid, required
    - `expires_at` string, date-time, required
    - `source_snapshot_sha256` string, required
  - `mode` 'OBSERVE' | 'ENFORCE', required
  - `enforced` boolean, required
  - `transaction_id` string, required
  - `disposition` 'PROCEED' | 'HOLD' | 'BLOCK', required
  - `reason_code` string, required
  - `message` string, required
  - `policy_version` string, required
  - `dossier_id` string, uuid, required
  - `checks` object[], required
    - `id` string, required
    - `status` 'evaluated' | 'missing_facts' | 'unsupported', required
    - `verdict` 'PROCEED' | 'HOLD' | 'BLOCK', required
    - `reason_codes` string[], required
    - `missing_facts` string[], required
  - `execution_time_ms` number, required
  - `native_context` NativeConnectionContext: Current registered company metadata checked by Core. It does not verify payment facts through Microsoft, refresh provider authority, or grant posting permission.
    - `version` 'commerce-native-context-v1', required
    - `org_id` string, uuid, required
    - `workspace_environment` 'sandbox' | 'production', required
    - `connection_id` string, uuid, required
    - `expected_revision` integer, required
    - `environment_name` string, required
    - `company_id` string, uuid, required
    - `erp_type` 'D365_BC', required
    - `tenant_id` string, uuid, required
    - `basis` 'persisted_connection_and_native_grant', required
    - `provider_read_authority` 'not_checked', required
    - `execution_available` boolean, required

## Other responses

- `400`: Bounded error response
- `401`: Bounded error response
- `409`: Bounded error response
- `429`: Bounded error response
- `502`: Bounded error response
- `503`: Bounded error response

---

[API](https://skmtc.dev/decionis/apis/decionis-commerce-gate-api.md) · [All operations](https://skmtc.dev/decionis/apis/decionis-commerce-gate-api/llms.txt) · [OpenAPI document](https://skmtc.dev/decionis/apis/decionis-commerce-gate-api/revisions/9fecb7109bf8?raw)
