logo

Are you need IT Support Engineer? Free Consultant

End-to-End API Automation of 5HP Advanced Intercompany Stock Transfer in SAP S/4HANA Cloud Public

  • By Sanjay
  • 23/09/2026
  • 5 Views



Scope Item: 5HP — Advanced Intercompany Stock Transfer
Document Type: NBIC (Cross-Company, Delivery-Linked)
Verified on: SAP S/4HANA Cloud Public Edition

Document chain (example):

STO (NBIC)
└─→ OBD
├─→ IV2 (auto-generated after PGI via Output Determination)
└─→ IBD (auto-generated after PGI)
└─→ GR Complete

1. Why 5HP Is Architecturally Different from Standard Stock Transfers

5HP uses the NBIC purchase order type. Three differences that break any assumption carried over from standard NB flows:

  1. No direct GR against the PO. The full delivery chain is mandatory — OBD → PGI → IBD → GR. Attempting to post GR directly against the intercompany PO returns error M7/036.

  2. IV2 is auto-generated, not API-driven. After PGI, Output Determination automatically creates the intercompany invoice (IV2). API_BILLING_DOCUMENT_SRV is read-only — there is no API to create IV2, and none is needed.

  3. Session-bound ETag on all FunctionImports. Every write operation in API_OUTBOUND_DELIVERY_SRV requires the CSRF token fetch, entity GET, and FunctionImport POST to share the same HTTP session (cookie jar). Stateless calls return 412 or 428. (See SAP Note 3539067.)


2. Authentication and Session Architecture

All write operations use a Communication User via Basic Auth, provisioned through the relevant Communication Arrangement (e.g., SAP_COM_0106 for Delivery Processing Integration, SAP_COM_0209 for Inbound Delivery).

$user      = “<comm-user>”
$pass=”<password>”
$base = “https://<your-tenant>.s4hana.cloud.sap”
$cookieJar = “$env:TEMP\obd_cookies_$(Get-Date -Format ‘HHmmss').txt”

The session rule: Every POST / PATCH / DELETE must use curl -c/-b <cookie-jar> to maintain session continuity across calls. PowerShell Invoke-WebRequest and stateless REST clients do not preserve the server-side session and will fail with CSRF or ETag errors.

BTP Integration Suite: Configure a persistent HTTP Receiver Adapter with a Cookie Session Handler policy. The iFlow must model the CSRF token fetch as an explicit preceding step — do not assume the token survives across integration flow restarts or parallel executions.


3. Step 1 — Create STO ( API Verified)

Service: api_stocktransportorder (OData V4)
Available from: Release 2602
Reference: SAP Community — Stock Transport Orders via API in SAP S/4HANA Cloud Public Edition

POST https://<your-tenant>.s4hana.cloud.sap/sap/opu/odata4/sap/api_stocktransportorder/srvd_a2x/sap/stocktransportorder/0001/StockTransportOrder
Content-Type: application/json
x-csrf-token: <fetched-token>

Request body:

{
“StockTransportOrderType”: “NBIC”,
“CompanyCode”: “<receiving-company-code>”,
“PurchasingOrganization”: “<purchasing-org>”,
“PurchasingGroup”: “<purchasing-group>”,
“SupplyingPlant”: “<supplying-plant>”,
“DocumentCurrency”: “<currency>”,
“Language”: “<language-key>”,
“_StockTransportOrderItem”: [
{
“StockTransportOrderItem”: “00010”,
“Product”: “<product-number>”,
“Plant”: “<receiving-plant>”,
“StorageLocation”: “<storage-location>”,
“OrderQuantity”: 1,
“OrderQuantityUnit”: “ST”,
“OrderQuantityUnitISOCode”: “PCE”,
“NetPriceAmount”: 60.00,
“DocumentCurrency”: “<currency>”,
“DeliveryDocumentType”: “NCC3”
}
]
}

Response (HTTP 201) — key fields:

Field Notes

StockTransportOrderGenerated STO number
StockTransportOrderTypeMust be NBIC for 5HP
PurchasingInfoRecordAuto-resolved from master data
EffectiveAmountNet price + applicable tax

Five things that will break this call:

  • OrderQuantityUnitISOCode is required — omitting it returns “ISO unit must be provided”
  • StockTransportOrderItem must be a string (“00010”), not an integer (10)
  • Fetch the CSRF token in a separate preceding GET with header x-csrf-token: fetch
  • Write the JSON body to a file and use –data-binary @file — avoids PowerShell escape issues with nested quotes and special characters
  • API_PURCHASEORDER_PROCESS_SRV (OData V2) does not support NBIC STO document types — use the dedicated V4 service

Note: Account assignment at the item level is not supported for NBIC. The process is designed exclusively for stock-to-stock transfers between company codes. (→ KBA 3744416)


4. Step 2 — Create OBD (⚠️ Constraints for NBIC)

Service: API_OUTBOUND_DELIVERY_SRV (OData V2)

The standard API supports OBD creation via POST /A_OutbDeliveryHeader with ReferenceSDDocument pointing to the STO. However, for NBIC specifically, two prerequisites must be in place before this path is viable:

  1. Value Chain Monitoring must be enabled for PO type NBIC. If value chains are not activated in the configuration activity Enable Value Chain Monitoring for Purchase Orders, OBD creation will fail at the backend. → KBA 3413153

  2. Only a small set of fields is accepted on create. The API rejects any field not in the explicit allowlist: ReferenceSDDocument, ReferenceSDDocumentItem, ActualDeliveryQuantity, DeliveryQuantityUnit, ShippingPoint, DeliveryDocument, SerialNumber. All other fields must be set via a subsequent PATCH. → SAP Note 2899036

Alternative (tested in this flow): Application Job API — schedule a backend job to create OBDs in bulk against the STO. This is the SAP-recommended approach for high-volume scenarios and avoids the prerequisites and field constraints above.

Design rationale: For 5HP, OBD creation is a scheduled, bulk-oriented operation. Real-time per-STO OBD creation via REST is a secondary path and adds operational risk at scale.


5. Step 3 — OBD Picking and Goods Issue ( API Verified, curl Required)

The Session-Bound ETag Mechanism

All FunctionImport operations in API_OUTBOUND_DELIVERY_SRV require the CSRF token and ETag to be acquired within the same HTTP session as the subsequent POST. A stateless client that fetches a CSRF token and then calls PostGoodsIssue without session persistence will receive:

  • 428 Precondition Required — no ETag provided
  • 412 Precondition Failed — ETag is outdated or not seeded in the session

SAP Note 3539067Error when posting goods issue via API: 412 = ETag is outdated (re-GET the delivery and retry); 428 = ETag header is missing entirely.

Client Type Result Reason

Stateless (Postman, MCP, iFlow without session handler)428 / 412No shared session between CSRF fetch and POST
curl + cookie jar (same session)200 CSRF fetch → entity GET → POST share one session

Correct call sequence:

$svcRoot = “https://<your-tenant>.s4hana.cloud.sap/sap/opu/odata/sap/API_OUTBOUND_DELIVERY_SRV”
$obd = “<outbound-delivery-number>”

# Step 0: Fetch CSRF token
# Important: target the entity set URL, NOT the service root
$fetchOut = & curl.exe -s -D – -o NUL `
-u “${user}:${pass}” `
-H “x-csrf-token: fetch” `
-H “Accept: application/json” `
-c $cookieJar `
“$svcRoot/A_OutbDeliveryHeader”
$csrf = ($fetchOut | Select-String “(?i)x-csrf-token:\s*(.+)”).Matches.Groups[1].Value.Trim()

# Step 1: GET entity in same session
# This seeds the ETag in the server-side session cache
& curl.exe -s -D – -o NUL `
-u “${user}:${pass}” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
“$svcRoot/A_OutbDeliveryHeader(‘${obd}')?\`$format=json”

3a. PickAllItems — If-Match: not required

& curl.exe -s -X POST `
-u “${user}:${pass}” `
-H “x-csrf-token: $csrf” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
-w “`nHTTP:%{http_code}” `
“$svcRoot/PickAllItems?DeliveryDocument=”${obd}”&\`$format=json”
# Expected: HTTP 200

3b. ConfirmPickingAllItems — If-Match: do NOT include

& curl.exe -s -X POST `
-u “${user}:${pass}” `
-H “x-csrf-token: $csrf” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
-w “`nHTTP:%{http_code}” `
“$svcRoot/ConfirmPickingAllItems?DeliveryDocument=”${obd}”&\`$format=json”
# Expected: HTTP 200

Warning: Including If-Match in this call returns 412 unconditionally. This is not a configuration problem — the operation explicitly rejects the header.

3c. PostGoodsIssue — If-Match: * is mandatory

& curl.exe -s -X POST `
-u “${user}:${pass}” `
-H “x-csrf-token: $csrf” `
-H “If-Match: *” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
-w “`nHTTP:%{http_code}” `
“$svcRoot/PostGoodsIssue?DeliveryDocument=”${obd}”&\`$format=json”
# Expected: HTTP 200, OverallGoodsMvtStatus = C

Material documents created after PGI (NBIC-specific):

Movement Type Plant Stock Change

MT681Supplying plantUnrestricted → in-transit
MT107 (WL-linked)Receiving plantGR blocked stock +1

6. Step 4 — OBD Actual Posting Date (⚠️ Manual Step Required)

KBA 3794858 confirms that the Internal Actual Transfer of Control Date (Header → Shipping tab → Internal Transfer of Control Dates → Actual Date) is not exposed as an updatable field in API_OUTBOUND_DELIVERY_SRV. After PGI, all header date fields are locked by the system.

Manual steps:

  1. Open the OBD in Manage Outbound Deliveries (Fiori) or transaction VL02N
  2. Header → Shipping tab → Internal Transfer of Control Dates
  3. Set Actual Date to the current system date
  4. Save

Why this is a blocker: The IBD PostGoodsReceipt FunctionImport validates this date as a precondition. Without it, the GR call will fail.

Enhancement path: If end-to-end automation of this date is required, raise an Enhancement Request referencing KBA 3794858 as the documented product limitation.


7. Step 5 — IBD Putaway Confirmation ( API Verified)

The IBD is auto-generated by the system immediately after PGI. Use API_INBOUND_DELIVERY_SRV for putaway.

$ibdRoot = “https://<your-tenant>.s4hana.cloud.sap/sap/opu/odata/sap/API_INBOUND_DELIVERY_SRV”
$ibd = “<inbound-delivery-number>”

Reuse the $csrf token and $cookieJar from Step 3 if still within the same session. If the session has expired, re-execute the CSRF fetch and entity GET sequence for the IBD service root.

5a. PutawayAllItems — If-Match: not required

& curl.exe -s -X POST `
-u “${user}:${pass}” `
-H “x-csrf-token: $csrf” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
“$ibdRoot/PutawayAllItems?DeliveryDocument=”${ibd}”&\`$format=json”

5b. ConfirmPutawayAllItems — If-Match: not required

& curl.exe -s -X POST `
-u “${user}:${pass}” `
-H “x-csrf-token: $csrf” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
“$ibdRoot/ConfirmPutawayAllItems?DeliveryDocument=”${ibd}”&\`$format=json”

8. Step 6 — Post Goods Receipt ( API Verified)

& curl.exe -s -X POST `
-u “${user}:${pass}” `
-H “x-csrf-token: $csrf” `
-H “If-Match: *” `
-H “Accept: application/json” `
-b $cookieJar -c $cookieJar `
“$ibdRoot/PostGoodsReceipt?DeliveryDocument=”${ibd}”&\`$format=json”
# Expected: HTTP 200, OverallGoodsMovementStatus = C

Prerequisite: Step 4 (OBD Actual Posting Date) must be completed first.

Two-step material document movement unique to NBIC:

Movement Type Plant Stock Change Notes

MT107 (WL-linked)Receiving plantGR blocked +1Linked to OBD — cannot be directly cancelled via MatDoc Cancel API (M7/492)
MT109Receiving plantGR blocked -1 → unrestricted +1Moves stock from restricted to unrestricted

MT107 being WL-linked to the OBD is expected NBIC behaviour, not an error. It does not indicate a problem with the preceding GI.


9. Step 7 — Intercompany Invoice IV2 (Auto-Generated, No Action Required)

After PGI, Output Determination automatically creates the IV2 intercompany invoice. No API call, job trigger, or manual action is needed.

Verify via query:

GET https://<your-tenant>.s4hana.cloud.sap/sap/opu/odata/sap/API_BILLING_DOCUMENT_SRV/A_BillingDocumentItem
?$filter=ReferenceSDDocument eq ‘<outbound-delivery-number>'
&$select=BillingDocument,BillingDocumentItem,ReferenceSDDocument,
Material,BillingQuantity,NetAmount
&$format=json

Expected response — key fields:

Field Expected Value Notes

BillingDocumentTypeIV2Intercompany invoice
CompanyCodeSupplying company codeIssuing entity
PartnerCompanyReceiving company codeRecipient entity
AccountingPostingStatusCFI document fully posted
OverallSDProcessStatusCSD flow complete
CreationDatePGI dateSame-day auto-generation

API limitation: Both A_BillingDocument and A_BillingDocumentItem carry sap:creatable=”false” in API_BILLING_DOCUMENT_SRV. The IV2 is entirely system-driven — neither API creation nor manual creation is needed or supported.


10. If-Match Quick Reference

FunctionImport Service If-Match Rule What Happens If Wrong

PickAllItemsOBDNot required
ConfirmPickingAllItemsOBDMust NOT be included412 unconditionally if added
PostGoodsIssueOBDMust be *412 (outdated) / 428 (missing)
ReverseGoodsIssueOBDMust be *Same as above
PutawayAllItemsIBDNot required
ConfirmPutawayAllItemsIBDNot required
PostGoodsReceiptIBDMust be *
ReverseGoodsReceiptIBDMust NOT be included501 if added
CancelMaterial DocumentNot requiredWL-type (MT107): M7/492 — cancel via Fiori instead
CancelBilling DocumentN/A428 — SD-BIL-BD rejects at business layer; cancel via Fiori

Source: SAP Help — ETag handling for Outbound Delivery (A2X); SAP Note 3539067


11. API Capability Summary

Step Automatable via API Notes

Create STOapi_stocktransportorder V4 (release 2602+)
Create OBD⚠️Standard API requires value chain config (KBA 3413153); Application Job API recommended for bulk
OBD Picking + GIAPI_OUTBOUND_DELIVERY_SRV — requires curl + cookie jar session
OBD Actual Posting DateKBA 3794858 — manual Fiori step required
IBD Putaway + ConfirmationAPI_INBOUND_DELIVERY_SRV
IBD Post Goods ReceiptAPI_INBOUND_DELIVERY_SRV
IV2 Intercompany InvoiceAutoOutput Determination after PGI — no action needed
Direct GR against NBIC POM7/036 — delivery chain is non-negotiable

12. Complete Document Chain

STO [NBIC — Supplying Plant → Receiving Plant]

└─→ OBD [Shipping Point: Supplying Plant]

│ PGI material documents:
│ ├── MT681: Supplying plant unrestricted → in-transit
│ └── MT107 (WL-linked): Receiving plant GR blocked +1

├─→ IV2 [Auto-generated by Output Determination after PGI]
│ Supplying Co. Code bills Receiving Co. Code
│ FI document: AccountingPostingStatus = C

└─→ IBD [Auto-generated after PGI]

│ GR material documents:
│ ├── MT107 (WL-linked to OBD): GR blocked +1
│ └── MT109: GR blocked -1 → unrestricted +1

GR Complete — OverallGoodsMovementStatus = C

13. Implementation Recommendations

For SI teams and integration developers:

Session management is the critical path. All OBD and IBD FunctionImport operations must execute within a single HTTP session. The sequence is always: CSRF token fetch → entity GET → FunctionImport POST, without breaking the session between calls. In BTP Integration Suite, use a persistent HTTP Receiver Adapter with Cookie Session Handler enabled. Do not invoke these operations from stateless middleware.

The OBD creation gap is the biggest automation blocker in 5HP. The standard API can create OBDs with STO reference, but the NBIC-specific prerequisite — value chain configuration for PO type NBIC — must be active first (KBA 3413153). For production-scale automation, use the Application Job API to batch-create OBDs rather than issuing per-document REST calls. This avoids the configuration dependency and scales better.

Regression-test after every FPS update. The ETag and session-binding behaviour of OBD FunctionImports has changed between patch levels. The If-Match rules documented above reflect the tested state as of 2026-09-23. Validate the full API chain after each FPS delivery — specifically the ConfirmPickingAllItems (rejects If-Match) and PostGoodsIssue (requires If-Match: *) asymmetry.

IV2 requires zero intervention. The intercompany invoice is fully owned by Output Determination. Do not add any trigger logic around billing — it creates race conditions and duplicate documents.

KBA 3794858 is an enhancement candidate. If your process requires fully automated OBD-to-GR flow, the OBD Actual Posting Date is the only remaining manual gate. Raise an Enhancement Request with SAP referencing this KBA if the business case warrants it.


Reference SAP Notes

Note / KBA Title Where Relevant

KBA 3794858Internal Actual Control Transfer Date not updatable via API_OUTBOUND_DELIVERY_SRVStep 4 — manual workaround required
SAP Note 3539067Error when posting goods issue via API — 412 / 428 ETag handlingStep 3 — ETag behaviour
SAP Note 3778784“State of the resource already changed” on PostGoodsIssueStep 3 — duplicate PGI scenario
SAP Note 2899036Wrong input parameters on OBD creation — allowed fields listStep 2 — OBD create payload
KBA 3413153OBD creation fails for NBIC — value chains not enabledStep 2 — prerequisite configuration
KBA 3744416MMPUR_PO_INTERCOMP111 — account assignment not supported in NBICStep 1 — STO creation constraint
KBA 3699051NBIC STOs not appearing in Monitor Value ChainsOperational monitoring

The features covered in this article are based on SAP S/4HANA Cloud, Public Edition 2608, please refer to the latest information for changes in subsequent versions.

Hope you LIKE it if it addresses your issue. After that, please feel free to comment after following my account and I will reply ASAP.





Source link

Leave a Reply

Your email address will not be published. Required fields are marked *

Chat with us on WhatsApp!