BAPI_PO_CHANGE — BAPI to Change an Existing Purchase Order
BAPI_PO_CHANGE changes an existing purchase order (business object BUS2012), mirroring transaction ME22N. It updates header, item, schedule line, account assignment, condition and text data using the X-structures to flag which fields are actually changed. It does not commit on its own and must be followed by BAPI_TRANSACTION_COMMIT. Its RETURN table must be scanned fully for message type E or A before assuming success.
This page covers BAPI_PO_CHANGE, the standard interface for updating purchase order header, item, schedule and pricing data outside of ME22N. It focuses on the parameter structures that actually matter in practice, the commit step that interfaces routinely forget, and the RETURN table handling mistakes that cause silent failures or partial updates. It also covers ownership split between functional and technical teams when a change appears to succeed but the order is unchanged.
Published 16 Sept 2026· 1,159 words
What it does
BAPI_PO_CHANGE acts on the purchase order object (BUS2012) and mirrors the change mode of transaction ME22N. It is used to update header fields such as terms of payment or currency, item-level fields such as quantity, price, delivery date, plant or account assignment, and to add, change or delete schedule lines, conditions and long texts on an existing order. It does not create a new order and does not release it; a separate release BAPI handles approval strategy release. It is the standard interface used by procurement middleware, EDI change messages from vendors, and custom programs that need to update purchase orders in bulk without going through the SAP GUI transaction, for example mass price updates driven by a contract change or a scheduling agreement delivery amendment.
Important parameters
- PURCHASEORDER - the ten-digit purchase order number being changed, mandatory on every call.
- POHEADER - header-level fields to update, such as payment terms, incoterms, currency or header text indicator.
- POHEADERX - the change flag structure matching POHEADER field by field; a field only updates if its corresponding X flag is set to X, regardless of what value is passed in POHEADER.
- POITEM - item data such as quantity, price, plant, storage location, delivery date and material group for the items being changed.
- POITEMX - the same field-by-field change indicator logic as POHEADERX, applied at item level; this is the most common source of ignored changes.
- POSCHEDULE and POSCHEDULEX - schedule line quantities and delivery dates, and their change flags, for items with multiple delivery schedules.
- POCOND and POCONDX - pricing condition changes at header or item level, again gated by the X structure.
- POTEXTHEADER and POTEXTITEM - long text updates for header and item texts.
- RETURN - the standard BAPI return table carrying messages, message type, and identifying information for every error or warning raised during processing.
Commit behaviour
BAPI_PO_CHANGE does not commit the database update itself. Like nearly all classic BAPIs, it performs the change in the update buffer and leaves the commit decision to the caller. The calling program must explicitly call BAPI_TRANSACTION_COMMIT afterward, and in most implementations should pass WAIT set to X so the commit is synchronous before the program continues or reports success. If the caller forgets the commit, the BAPI can return a clean RETURN table with no error messages and the order will still appear unchanged when checked in ME23N, because nothing was ever written to the database. This is one of the most common causes of what looks like an intermittent bug in custom interfaces but is actually a missing commit call every time.
Return handling
RETURN is a table, not a single structure, and BAPI_PO_CHANGE can return zero, one, or many entries in a single call, mixing informational, warning and error messages. The only reliable success check is looping over every row and confirming that none carry TYPE E or TYPE A; checking only the first row, or checking whether the table is initial, misses errors that appear on line two or three when multiple items fail independently. sy-subrc after the function call is meaningless here since BAPIs signal outcome through RETURN, not through the classic ABAP return code, and code that checks sy-subrc instead of RETURN will report false success on every call. Another frequent bug is treating any non-empty RETURN table as failure, which causes valid changes with only warning-level messages to be rejected by the calling interface and retried in a loop, generating duplicate change attempts against the same order. Log the full RETURN table, including MESSAGE, ID and NUMBER, before deciding success or failure, and surface it in interface monitoring rather than discarding it after a simple pass or fail flag.
ECC vs S/4HANA
BAPI_PO_CHANGE remains valid and commonly used on S/4HANA for purchase order updates; it has not been formally deprecated in favor of a newer BAPI. S/4HANA does expose purchase order maintenance through OData and API-based services intended for Fiori apps and modern integration scenarios, and new integration builds are generally steered toward those released APIs rather than classic BAPIs where one exists and covers the required fields. For custom ABAP development, background jobs and existing middleware already built on it, BAPI_PO_CHANGE continues to function against the same underlying purchase order object and data model.
Common pitfalls
- Sending a value in POITEM without setting the matching flag in POITEMX; the BAPI silently ignores the field and the order is left unchanged with no error raised.
- Changing item quantity or price on an order that already has goods receipt or invoice postings against it, which the BAPI rejects with a message rather than a hard dump, easily missed if RETURN is not fully checked.
- Attempting to change an item that has already been fully invoiced or blocked, which returns an error tied to the specific item number rather than the whole call, so partial success on a multi-item order is common and must be handled per item.
- Concurrent changes to the same purchase order from two processes, for example an EDI change message and a manual ME22N session, causing a lock wait or an enqueue error that surfaces in RETURN as a lock-related message rather than a field-level one.
- Deleting a schedule line or item by setting a deletion indicator without also setting the corresponding X flag, leaving the deletion silently unapplied.
- Forgetting BAPI_TRANSACTION_COMMIT after a batch loop, so the first few hundred orders in a mass run appear to fail intermittently depending on where the program terminates.
Whose problem this is
A change that silently fails to apply is almost always an interface or ABAP issue, not a master data or configuration issue on the functional side. The evidence functional needs to hand over is the exact purchase order number, the fields expected to change, and a screenshot of ME23N showing the unchanged value; the developer needs to trace whether the corresponding X flag was set and whether RETURN carried an error that was discarded.
Related SAP objects
Reviewed pages this object connects to in the ERPClimb knowledge graph.
Source: ERPClimb — https://erpclimb.com/sap-bapis/bapi-po-changeERPClimb is an independent platform and is not affiliated with SAP SE. Reference pages are written and reviewed by SAP consultants for learning and troubleshooting.