SK SKYVVA Documentation

8. How to create an inbound interface using Asynchronous mode with SkyvvaSalesforce Adapter

Overview

This document explains how to create a SKYVVA Inbound Interface in Salesforce that processes incoming record sets through Asynchronous mode — the SkyvvaSalesforce receiver channel's Mode = Asynchronous setting, which is the default/simplest V3 processing mode: no baskets, no Bulk API, no package-based direct-call chunking. It processes requests differently from every other mode covered in this tutorial series, built around creating IMessage__c records rather than baskets.

Note: Mode = Asynchronous is not the same thing as Processing Mode = Asynchronous on the interface record — the two fields share a name but control different things. The CPI channel's Mode value is what actually selects this processing path; the interface's own Processing Mode field is set to Asynchronous here mainly for consistency with the other tutorials in this series, not because it's what drives dispatch through this channel.

It covers the following steps:

  1. Create and configure a SKYVVA Inbound Interface in Salesforce, with the IMessage engine and package-size fields set.
  2. Create an integration flow in SAP CPI.
  3. Configure the HTTPS sender channel.
  4. Configure the SKYVVA Salesforce receiver channel with Skyvva API Version = V3 and Mode = Asynchronous.
  5. Deploy the integration flow.
  6. Send a test request from Postman through SAP CPI.
  7. Monitor the message in SAP CPI.
  8. Verify the resulting records in Salesforce.
In this example:
ItemValue
Salesforce ObjectAccount / Contact (nested)
Message SourcePostman
MiddlewareSAP CPI
SKYVVA API VersionV3
ModeAsynchronous
Processing ModeAsynchronous
Processing Behavior (CPI channel — the field that actually governs this, §2.3.2)None
Inbound Processing Behavior (Interface — overwritten at runtime, see §1.3)(left blank)

Context Before You Start

In short: Asynchronous mode creates one or more IMessage__c records for the incoming payload — one root message plus one child message per node in the hierarchical tree (each tagged with HLevel__c for its depth and ProcessMode__c = Hierarchical) — via a REST call to services/apexrest/skyvvasolutions/IMessages. What happens next depends entirely on the interface's Inbound Processing Behavior field (§1.3): by default, the adapter immediately triggers a second call to services/apexrest/skyvvasolutions/V3/processMessage in the same request, turning those messages into actual Account/Contact records before the HTTP response is returned. If Inbound Processing Behavior is set to Create Message Only, that second call never happens — the messages are created with Status__c = "New" and left for separate processing.

Reasons to pick this path:

auditing/troubleshooting an individual submission — rather than only seeing it inside a shared basket alongside other requests, as Batch and Bulk mode do. (§1.3) — this is the simplest of the four V3 modes covered across this tutorial series.

Good fit for:

example as the Bulk, Auto-Switch, and Batch tutorials, since External Mapping and the Hierarchical Mapping Tool are V3-interface-level features, independent of which Mode the receiver channel uses.

Note: Inbound Processing Behavior is a 14-value picklist (Queueable Apex, Batch Apex, Scheduled Apex, Event Trigger Apex, several ... - Large Message (non-transactional) variants, Create Message Only, plus some legacy-looking values like SYNC/FUTURE/BATCH/AUTO). This tutorial only documents the two values that directly affect the CPI adapter's own behavior — blank/default (auto-reprocess) and Create Message Only (defer processing). The other values select different Salesforce-side (Apex) execution strategies for the same reprocessing step, but that logic lives in the Salesforce package and isn't covered here — don't assume behavior for those values from this doc.

End-to-end sequence: the steps below — create and configure the Interface (including the Inbound Processing Behavior and package-size fields) in Salesforce, build the CPI iFlow (HTTPS sender → SkyvvaSalesforce receiver with Mode = Asynchronous), deploy, send a test payload from Postman, then confirm the resulting records in Salesforce.

POSTMAN
   ↓
SAP CPI (HTTPS Sender → SkyvvaSalesforce Receiver, Mode = Asynchronous)
   ↓
SKYVVA Inbound Interface
   ↓
IMessage__c record(s) created (root + hierarchical children)
   ↓
processMessage call (unless Inbound Processing Behavior = Create Message Only)
   ↓
Salesforce Account / Contact
image

Figure 1: End-to-end message flow using Asynchronous mode.

1. Salesforce Interface Development

1.1 Create the Interface

Create a SKYVVA Inbound Interface under Integration in Salesforce (create the parent Integration record first if you don't already have one).

For this example, create the interface AccountContactAsync_IN. Leave the Message Type field blank. For a V3 Inbound interface, leaving Message Type unset is what triggers Hierarchical Mapping — there is no MetaData Provider/Repository/Message Type hierarchy to build first; the Mapping Tool derives the parent/child tree directly from Salesforce's own schema instead.

Configure the interface:

SettingValue
Interface NameAccountContactAsync_IN
IntegrationYour SAP CPI Integration App record
Source/Target NameAccount
StatusDeployed
Interface DirectionInbound
Processing ModeAsynchronous
Operation TypeUpsert
Message Type(leave blank)
External MappingEnabled
image Figure 2: SKYVVA Inbound Interface AccountContactAsync_IN, no Message Type linked.

This is the main interface's own Inbound Setup section — with External Mapping enabled, set Salesforce External ID = skyvvasolutions__ERP_DEBTOR_ID__c, the Account-level external key used to match/upsert Account records:

image

Figure 3: Main interface AccountContactAsync_IN — Inbound Setup, External Mapping enabled with Salesforce External ID skyvvasolutions__ERP_DEBTOR_ID__c (Account).

1.2 Map Account → Contact in the Hierarchical Mapping Tool

Open the interface's Mapping Tool (Interface detail page → Open Mapping). Because Message Type is blank on a V3 Inbound interface, the Source tree is built live from the Account object's own schema rather than from a predefined Message Type — including its child relationships. Expand the tree down to the Contact(AccountId) child-relationship node to reach it.

With External Mapping enabled on the interface (§1.1), field-level mapping is not needed — External Mapping auto-maps fields by name on its own. All this step has to do is drag the two relationship nodes, top-down, to generate the chained sub-interface:

  1. Drag the Account root node onto the target Account root first. This is required, not optional — the target tree doesn't display a Contact(AccountId) node at all until Account itself has been mapped. Expanding the target Account node beforehand shows only Account's other child relationship nodes (no individual fields are ever listed here — with External Mapping enabled, the tree doesn't expose fields for manual dragging at all), never Contact(AccountId), so there is nothing to drag the child relationship onto until the root mapping is done.
  2. Expand Contact(AccountId) and drag it onto the target Contact(AccountId) node. No individual field needs to be dragged in either step — this is a node-to-node mapping, not a field-to-field one.
Important — this step is not optional and cannot be replaced by External Mapping alone. Dragging the Contact(AccountId) node auto-creates a chained sub-interface behind the scenes (internal, engine-managed — you don't create or configure it yourself), and that's the actual mechanism that makes the Account+Contact hierarchy work at runtime. External Mapping only flat-maps fields on an interface that already exists; it doesn't create this chained structure or walk into child relationships on its own. Skip this step, and posting nested Contact data will not produce Contact records, no matter how the payload is shaped.
image

Figure 4: Hierarchical Mapping Tool — Account → Contact(AccountId) node mapping, External Mapping handles field-level mapping.

Save the mapping. Doing so auto-generates the chained sub-interface for the child Contact object mentioned in the note above. That sub-interface has its own, separate Inbound Setup, with its own External Mapping keyed on the Contact-level external ID — skyvvasolutions__ERP_CONTACT_ID__c, not the Account-level ERP_DEBTOR_ID__c used on the main interface (§1.1). Don't confuse the two: they identify different objects, and the sub-interface's External Mapping has to be checked here independently — it is not inherited from the main interface just because External Mapping is enabled there.

image

Figure 5: Auto-generated sub-interface (Contact) — Inbound Setup, External Mapping enabled with Salesforce External ID skyvvasolutions__ERP_CONTACT_ID__c (Contact).

1.3 Configure the IMessage Engine

In the Basket Setting section of the interface, set the fields that control this mode specifically:

FieldValueWhy it matters
Inbound Processing Behavior (InboundPostingBehavior__c)(leave blank)Blank means the adapter creates the IMessage__c record(s) and then immediately calls processMessage in the same request — the request isn't confirmed done until Salesforce has turned the message(s) into actual records. Set to Create Message Only instead if you want the message created but not auto-processed (Status__c stays "New", left for separate/later processing) — see the note in Context Before You Start about the field's other values.
Number_of_Records_Per_Batch__c (Processing Package Size)e.g. 20The number of root records (Account, not counting nested Contact children) grouped into each IMessage__c creation call. Same precedence chain as every other mode in this series — see below.
Important: whatever you save in this field is not what actually governs the request once it arrives through this SkyvvaSalesforce receiver channel — the adapter always overwrites the interface's Inbound Processing Behavior with the CPI channel's own Processing Behavior field (Skyvva tab, §2.3.2) before processing, on every request. Setting it here is harmless (and useful for consistency / other trigger paths into this interface), but to actually control this mode's behavior for CPI-originated requests, configure Processing Behavior on the CPI channel instead — see the note under §2.3.2.
Note — package-size precedence chain: the part size is resolved as strict, short-circuit precedence, not a blend — the first non-blank field wins outright and nothing below it is read for that call:
  1. Package_Size__c (label "Transfer Package Size") — if set, wins outright.
  2. Number_of_Records_Per_Batch__c (label "Processing Package Size") — used only if #1 is blank.
  3. The parent Interface Group's own Number_of_Records_Per_Batch__c — used only if #1 and #2 are both blank.
  4. The Integration's Packet__c — used only if #1–#3 are all blank.
  5. A hardcoded default of 20 — only if all four above are blank.
image

Figure 6: Interface Basket Setting — Inbound Processing Behavior and Processing Package Size.

After completing the configuration and mapping in Skyvva, save the interface.

2. SAP CPI Development

2.1 Create the Integration Flow

Create the package in SAP CPI under Design and add the integration flow.

Example:

ItemExample
Integration PackageSkyvva Salesforce Adapter Testing
Integration FlowAccountContact_Skyvva_Asynchronous
The flow uses an HTTPS Sender, a Message Mapping step, and a **SkyvvaSalesforce Receiver** — the Message Mapping step is what transforms the payload before it reaches Salesforce, taking the place a separate Content Modifier would otherwise need to. image

Figure 7: Integration flow for the Asynchronous mode example.

Important: the Message Mapping step may show a warning icon. Hovering it reveals: "Http Sender Component may not pass XML or JSON message to Message Mapping. Message Mapping supports XML or JSON input only." This is CPI's design-time validator flagging that it can't statically prove the HTTPS Sender's output is XML/JSON — the standard HTTPS Sender adapter has no fixed content-type contract, so CPI can't guarantee it at design time. It's not about
incomplete field mapping, and it doesn't block deployment: this exact flow deploys and runs successfully despite it. Safe to leave as-is as long as callers actually send XML/JSON matching Request Format, as this tutorial's Postman example does.

Where the target schema comes from: export it via the Interface record's Generate MetaData button — Format = XSD Schema, API = V3/Integrate. Then, inside the Message Mapping step's own editor (double-click it on the iFlow canvas), go to the Target panel → SelectAdd → upload the downloaded .xsd → pick its root element as the Target Message Type. The file is stored as a resource on this specific integration flow, not somewhere interface/adapter-level or CPI-wide — any other iFlow needing it has to import its own copy.

Note: this interface uses External Mapping with Message Type left blank, so the exported schema comes from a live object describe rather than a curated tree — confirm it reflects the nested AccountContact structure before relying on it.

2.2 Configure the HTTPS Sender Channel

Select the standard SAP HTTPS sender adapter.

General tab: Direction Sender, Adapter Type HTTPS, Transport Protocol HTTPS, Message Protocol None — fixed values, identical in every tutorial that uses this sender.

Connection tab:

FieldExample value
Address/skyvva/AccountContactIntegrateAsynchronousV3
AuthorizationUser Role
User RoleESBMessaging.send
CSRF ProtectedUnchecked
Important: The configured User Role must already exist and be assigned to the CPI user/credential that Postman authenticates as, or the sender rejects the request with 403 Forbidden.
image

Figure 8: HTTPS sender channel — Connection tab.

2.3 Configure the SkyvvaSalesforce Receiver Channel

Select SkyvvaSalesforce as the receiver adapter. The receiver channel has three tabs: General, Connection, Skyvva.

General tab: Direction Receiver, Adapter Type SkyvvaSalesforce, Transport Protocol https, Message Protocol skyvva — fixed values, identical for every SkyvvaSalesforce receiver channel.

2.3.1 Connection Tab

FieldExample value
Authentication TypeOAuth2
OAuth2 FlowUsername-Password Credential (or Client Credential)
Login Urlhttps://test.salesforce.com
User CredentialYour CPI Security Material alias for the Salesforce user (shown only for the Username-Password flow)
Client CredentialYour CPI OAuth2 Client Credentials artifact (required for either flow)
Note: There is no separate "Client Id"/"Client Secret" pair on the current adapter — both are held inside the single Client Credential OAuth2 artifact deployed in the CPI keystore. For the full field reference see 1. SKYVVA CPI Salesforce Receiver Adapter in SAP Cloud Integration.md §3.

2.3.2 Skyvva Tab — Request Settings

FieldValue
Skyvva API VersionV3
IntegrationYour SKYVVA Integration
InterfaceAccountContactAsync_IN
ModeAsynchronous
Processing BehaviorNone (this example)
Request FormatXML
Response FormatXML
Skyvva App Versionyour Salesforce package version, e.g. 2.51.0
Salesforce Api Version59.0 (or your org's current API version)
Note: Processing Behavior is the CPI-side field that actually controls the reprocessing behavior described in §1.3 — see the Important note there. It has three values: None (default — creates the IMessage__c record(s), then immediately triggers processing, same effective behavior as leaving the interface's own Inbound Processing Behavior blank), Create Message Only (skips that processing step — messages stay Status__c = "New"), and Batch Apex - Large Message (non-transactional) (also processes; intended for large payloads — not independently traced beyond that in this tutorial).
image

Figure 9: SkyvvaSalesforce receiver channel — Skyvva tab, Mode = Asynchronous, Processing Behavior = None.

2.3.3 Skyvva Tab — Adapter Settings

FieldValue
Logging optionDefault
Enable retry for fatal connectivity errorsUnchecked (leave disabled for this test)
HTTP client timeout (sec)60
Once all channel parameters are defined, save the integration flow and deploy it. image

Figure 10: Integration flow deployed.

2.4 Get the SAP CPI Endpoint URL

Go to CPI → Monitoring → Manage Integration Content, locate the deployed integration flow, and copy its endpoint URL.

image

Figure 11: Manage Integration Content — endpoint URL.

Note: The endpoint URL shape depends on the tenant generation — Neo tenants use https://{{TenantId}}-iflmap.hcisbp.<region>.hana.ondemand.com/http/<Address>, current SAP BTP Integration Suite (Cloud Foundry) tenants use https://{{TenantId}}.<runtime-cluster>.cfapps.<region>.hana.ondemand.com/http/<Address>. Always copy the exact URL from your own tenant's Manage Integration Content panel rather than assembling it by hand.

3. Testing with Postman

Use the endpoint URL from step 2.4.

Create a new request with the following configuration:

SettingValue
MethodPOST
URLYour SAP CPI endpoint URL
AuthorizationAuthentication configured for the HTTPS Sender
Content-TypeMatch the configured Request Format
Because this example uses:
Request Format = XML

configure the header as:

Content-Type: application/xml
Note: For a small test payload, use Postman's raw body mode and paste the XML directly — the dropdown next to raw (Text/JSON/XML/…) sets the Content-Type header for you automatically. For a large payload, pasting that much text into the raw editor isn't practical; use Body → binary instead, select the XML file from disk, and set the Content-Type: application/xml header yourself on the Headers tab — binary mode has no type dropdown of its own, so nothing sets it for you. The file content sent is identical either way; only how you attach it to the request differs.

Because this interface's hierarchical shape (Account with nested Contact records, external IDs skyvvasolutions__ERP_DEBTOR_ID__c/skyvvasolutions__ERP_CONTACT_ID__c) is the same shape used in the Bulk, Auto-Switch, and Batch tutorials, the same sample payload works here too — the only difference is which interface it's addressed to, resolved on the CPI side via the receiver channel's Interface field (§2.3.2), not from anything in the body itself:

<?xml version="1.0" encoding="UTF-8"?>
<Accounts>
  <Account>
    <ERP_DEBTOR_ID__c>ACC-000001</ERP_DEBTOR_ID__c>
    <Name>CPI Test Account 1</Name>
    <Phone>+49-89-2867825</Phone>
    <BillingStreet>CPI Test Street</BillingStreet>
    <BillingCity>Frankfurt</BillingCity>
    <BillingPostalCode>42098</BillingPostalCode>
    <BillingCountry>DE</BillingCountry>
    <Contact>
      <ERP_CONTACT_ID__c>ACC-000001-C01</ERP_CONTACT_ID__c>
      <FirstName>Max</FirstName>
      <LastName>Mueller</LastName>
      <Email>max.mueller.1.1@example.com</Email>
      <Phone>+49-89-2719583</Phone>
    </Contact>
    <!-- ... more Contact elements for this Account ... -->
  </Account>
  <!-- ... more Account elements, same shape ... -->
</Accounts>

With Processing Behavior = None (the default — §2.3.2), a successful response for this small payload looks like:

{"Message":"Processing Integration With IMessage Successfully","StatusMsg":"Successful","StatusCode":"OK"}

This confirms both the IMessage__c creation step and the follow-up processMessage call succeeded.

Note: a large payload can produce a different response shape, converted to Response Format = XML. Captured below while testing this tutorial with a larger payload — 150 Account records, each with 10 nested Contact records — sent via Body → binary:
image

Figure 12: POSTMAN request (150 Accounts × 10 Contacts, binary body) and response — the asynchronous JobId response shape.

 <?xml version="1.0" encoding="UTF-8"?>
 <ns0:Response xmlns:ns0="http://soap.sforce.com/schemas/class/skyvvasolutions/IServices">
   <StatusCode>OK</StatusCode>
   <StatusMsg>Successful</StatusMsg>
   <JobId>7079K00001jbgycQAA</JobId>
   <Completed/>
   <PartialCompleted/>
   <Pending/>
   <New>
     <Message>
       <MessageId>a0T9K000000qEMBUA3</MessageId>
       <MessageStatus>New</MessageStatus>
       <SalesforceId/>
       <ExtValue/>
      <MessageComment/>
     </Message>
     <!-- ... one <Message> element per created IMessage__c record (root + hierarchical children) ... -->
   </New>
 </ns0:Response>
 

JobId identifies the asynchronous job the messages were queued under for that large run; every message is still listed under <New> because the HTTP response returns as soon as the job is queued, before it has actually run. Confirm the real outcome in **SAP CPI → Monitor Message Processing (§4.1) and Salesforce → Message Monitoring** (§4.2) rather than relying on the response body alone in this case.

4. Monitoring

4.1 SAP CPI

Go to CPI → Monitor → Monitor Message Processing and verify the message completed successfully.

image

Figure 13: CPI Monitor Message Processing.

4.2 Salesforce

Go to Salesforce → Message Monitoring to confirm the message and resulting Account/Contact records.

Unlike Batch and Bulk mode, Asynchronous mode doesn't queue a basket in the Batch Control Board or Bulk Control Board at all — the underlying IMessage__c record(s) are created and (by default) processed within the same request, so Message Monitoring is the primary place to confirm the result. This tutorial doesn't trace a dedicated Salesforce-side UI specifically for browsing IMessage__c records beyond Message Monitoring — if your org has one, use it, but its existence isn't verified here.

image

Figure 14: Salesforce Message Monitoring — processed message.


After confirming the message, verify that the Account and Contact records were created or updated successfully.

Summary

The complete integration flow is:

POSTMAN
   ↓
HTTPS Sender
   ↓
SAP CPI Integration Flow
   ↓
SkyvvaSalesforce Receiver (Mode = Asynchronous)
   ↓
SKYVVA Inbound Interface
   ↓
IMessage__c record(s) created (root + hierarchical children)
   ↓
processMessage call (unless Inbound Processing Behavior = Create Message Only)
   ↓
Salesforce Account / Contact

Configuration Summary

ComponentConfiguration
SKYVVA InterfaceInbound, Asynchronous, Upsert
Processing Behavior (CPI channel)None — auto-reprocesses immediately (governs actual behavior; overwrites the interface field below)
Inbound Processing Behavior (Interface)(left blank — no effect for CPI-originated requests, see §1.3)
Processing Package Sizee.g. 20
SKYVVA API VersionV3
ModeAsynchronous
Request/Response FormatXML
Asynchronous mode is the default, simplest V3 processing path — it tracks each request as its own IMessage__c record rather than folding it into a shared basket, and (unless Processing Behavior = Create Message Only on the CPI channel) processes that record into Account/Contact data as part of the same call.

The package size is controlled entirely by the interface's own field precedence chain (§1.3) and is independent of the CPI channel's own settings — once Mode = Asynchronous routes a request here, how many records get grouped into each IMessage__c creation call is Salesforce-side configuration, not something adjusted from SAP CPI.

Open this article in the interactive viewer →