TL;DR
The SAP SuccessFactors IM pipeline has 5 stages: Import (CSC_CREDIT), Classify, Calculate (produces CSC_RESULTS), Approve, and Pay. Each stage has a table and status field to track progress.
Pipeline runs are logged in CSC_PIPELINE_RUN with RUN_ID, STATUS, START_TIME, END_TIME, ROWS_PROCESSED. Monitor health by querying SECONDS_BETWEEN duration and error counts.
Results are stored in CSC_RESULTS with PARTICIPANT_ID, PLAN_ID, PERIOD_ID, RESULT_AMOUNT, INCENTIVE_AMOUNT, STATUS, ATTAINMENT_PCT. Only approved results are sent to payroll.

Now you have plans and participants. The pipeline is the engine that turns sales transactions (credits) into incentive payouts. This lesson covers the five stages of the pipeline, how to monitor it, how to read results, and how to troubleshoot when things break.

The Five Stages of the Pipeline

The SAP SuccessFactors IM pipeline is a sequential, multi-stage process. Each stage transforms data:

Stage 1: Import (CSC_CREDIT)

Raw transaction data arrives from the business systems. A credit is a single compensable event: a deal closed, a customer signed, a support ticket resolved. The CSC_CREDIT table stores:

  • CREDIT_ID — Unique identifier
  • PARTICIPANT_ID — Who earned this credit
  • PLAN_ID — Which plan this credit applies to
  • AMOUNT — The transaction value (revenue, units, points, etc.)
  • CREDIT_DATE — When the transaction occurred
  • PERIOD_ID — Which period it belongs to
  • SOURCE_REF — External identifier (e.g., "ORDER-12345" from CRM)
  • STATUS — 'PENDING', 'PROCESSED', 'ERROR', 'REVERSED'

Credits come from diverse sources: SAP Sales Cloud (CRM), SAP S/4HANA (ERP), a custom REST API feed, even manual uploads. The system doesn't care about the source — it just needs PARTICIPANT_ID, PLAN_ID, AMOUNT, CREDIT_DATE, PERIOD_ID. Missing these fields causes import failure.

Stage 2: Classify

The pipeline matches each credit to a participant and plan. If a credit has PARTICIPANT_ID=JSMITH001, PLAN_ID=COMMISSION-2026, the classifier checks: Does this participant exist? Is this plan active? Is the participant assigned to this plan during the credit date? If yes, the credit is classified. If no, STATUS='ERROR'. Classification failures are routed to a queue for manual review (missing plan assignment, typo in PARTICIPANT_ID, etc.).

Stage 3: Calculate

The calculation engine reads the classified credit, looks up the participant's quota for the period, retrieves the plan's rate/tier configuration, and computes the incentive amount. Example:

  • Credit: JSMITH001, AMOUNT=$50K, PERIOD_ID=2026-Q2
  • Quota lookup: JSMITH001's quota for 2026-Q2 is $500K
  • Plan config: Commission Plan says 2% on revenue, capped at $50K per quarter
  • Calculation: $50K * 2% = $1K, cap applies but amount is below cap, so INCENTIVE_AMOUNT=$1K
  • Result is written to CSC_RESULTS with STATUS='CALCULATED'

If a credit can't be calculated (quota lookup fails, missing rate table), STATUS='ERROR'.

Stage 4: Approve

Results are held in STATUS='CALCULATED' until they're approved. An approval workflow (handled by SAP Advanced Workflow) routes results to designated approvers: the finance team, plan owner, or a manager. Approvers can accept, reject, or manually adjust results. Once approved, STATUS='APPROVED'. Unapproved results are never sent to payroll.

Stage 5: Pay

Approved results are exported to the payroll system (SAP S/4HANA Payroll, ADP, etc.) for processing. STATUS='PAID' indicates the result made it to payroll. The payroll system then calculates taxes, deductions, etc., and processes the payout on the next payroll cycle.

Credit Transactions: The Starting Point

Credits are imported from various systems. A typical daily import:

SAP HANA Database SQL — List credits imported today
-- Credits imported today, by status
SELECT
  STATUS,
  COUNT(*)              AS CREDIT_COUNT,
  SUM(AMOUNT)          AS TOTAL_AMOUNT,
  MIN(CREATED_DATE)    AS FIRST_IMPORT,
  MAX(CREATED_DATE)    AS LAST_IMPORT
FROM CSC_CREDIT
WHERE CAST(CREATED_DATE AS DATE) = CURRENT_DATE
GROUP BY STATUS
ORDER BY CREDIT_COUNT DESC;

If most credits are STATUS='PENDING', the pipeline hasn't run yet. If some are STATUS='ERROR', investigate: check the pipeline log (CSC_PIPELINE_ERROR) to see why they failed. Common issues:

  • PARTICIPANT_ID doesn't exist → typo or employee not loaded yet
  • PLAN_ID doesn't exist → plan not created in IM
  • PERIOD_ID doesn't exist → period not defined for the plan
  • NULL AMOUNT field → required field missing in source data

Pipeline Monitoring: The CSC_PIPELINE_RUN Table

Each pipeline execution creates a run record:

SAP HANA Database SQL — Pipeline run history with duration
-- Monitor pipeline execution health
SELECT
  RUN_ID,
  RUN_DATE,
  STATUS,
  ROWS_PROCESSED,
  ROWS_SUCCEEDED,
  ROWS_FAILED,
  START_TIME,
  END_TIME,
  SECONDS_BETWEEN(START_TIME, END_TIME) AS DURATION_SECONDS,
  ROUND(CAST(ROWS_PROCESSED AS FLOAT) /
        SECONDS_BETWEEN(START_TIME, END_TIME), 2)
                         AS ROWS_PER_SECOND
FROM CSC_PIPELINE_RUN
WHERE RUN_DATE >= ADD_DAYS(CURRENT_DATE, -7)
ORDER BY START_TIME DESC;

This query shows the last 7 days of pipeline runs. If DURATION_SECONDS is unusually long (e.g., a run that normally takes 5 minutes takes 30), the calculation engine may be stuck or querying slowly. Check if there are lock waits (use SAP HANA Database monitoring). If ROWS_FAILED is high, investigate the error log.

Reading CSC_RESULTS

Results are the outputs of the calculation engine. The CSC_RESULTS table has:

  • PARTICIPANT_ID — Who earned this
  • PLAN_ID — Which plan
  • PERIOD_ID — Which period
  • RESULT_AMOUNT — Total value of credits (before rates/tiers)
  • INCENTIVE_AMOUNT — Final payout after rates, tiers, caps, clawbacks
  • ATTAINMENT_PCT — (RESULT_AMOUNT / QUOTA_AMOUNT) * 100
  • STATUS — 'CALCULATED', 'APPROVED', 'REJECTED', 'PAID'

A query to view results for a period:

SAP HANA Database SQL — View results for Q2 2026 by plan and attainment band
-- Results summary: Q2 2026, breakdown by attainment tier
SELECT
  ccomp.NAME                    AS PLAN_NAME,
  CASE
    WHEN cr.ATTAINMENT_PCT < 50  THEN '0-50%'
    WHEN cr.ATTAINMENT_PCT < 100 THEN '50-100%'
    WHEN cr.ATTAINMENT_PCT < 150 THEN '100-150%'
    ELSE '150%+'
  END                           AS ATTAINMENT_BAND,
  COUNT(DISTINCT cr.PARTICIPANT_ID)
                                AS PARTICIPANT_COUNT,
  SUM(cr.RESULT_AMOUNT)          AS TOTAL_RESULTS,
  SUM(cr.INCENTIVE_AMOUNT)      AS TOTAL_INCENTIVES,
  ROUND(AVG(cr.ATTAINMENT_PCT), 1)
                                AS AVG_ATTAINMENT_PCT
FROM CSC_RESULTS cr
JOIN CSC_COMP_PLAN ccomp
  ON ccomp.ID = cr.PLAN_ID
WHERE cr.PERIOD_ID = '2026-Q2'
GROUP BY ccomp.NAME, ATTAINMENT_BAND
ORDER BY ccomp.NAME, ATTAINMENT_BAND;

This query shows how your population performed. If 70% of people are in the 100-150% band, that's excellent attainment. If 50% are in 0-50%, either quotas are too aggressive or there's a sales problem. Use this for business analysis and to validate results before final approval.

Calculating Attainment Percentage

Attainment % is critical for tier-based compensation:

SAP HANA Database SQL — Attainment calculation with tier payout logic
-- Detailed attainment calculation with tier mapping
SELECT
  cr.PARTICIPANT_ID,
  cp.NAME                       AS PARTICIPANT_NAME,
  cr.PLAN_ID,
  cr.PERIOD_ID,
  cq.QUOTA_AMOUNT,
  cr.RESULT_AMOUNT,
  CASE
    WHEN cq.QUOTA_AMOUNT = 0 THEN NULL
    ELSE ROUND((cr.RESULT_AMOUNT / cq.QUOTA_AMOUNT) * 100, 1)
  END                           AS ATTAINMENT_PCT,
  CASE
    WHEN ROUND((cr.RESULT_AMOUNT / cq.QUOTA_AMOUNT) * 100, 1) < 50  THEN 'No Payout'
    WHEN ROUND((cr.RESULT_AMOUNT / cq.QUOTA_AMOUNT) * 100, 1) < 100 THEN '50% of Base'
    WHEN ROUND((cr.RESULT_AMOUNT / cq.QUOTA_AMOUNT) * 100, 1) < 150 THEN '100% of Base'
    ELSE '125% of Base (Accelerator)'
  END                           AS TIER_DESCRIPTION,
  cr.INCENTIVE_AMOUNT
FROM CSC_RESULTS cr
JOIN CSC_PARTICIPANT cp
  ON cp.PARTICIPANT_ID = cr.PARTICIPANT_ID
LEFT JOIN CSC_QUOTA cq
  ON cq.PARTICIPANT_ID = cr.PARTICIPANT_ID
  AND cq.PLAN_ID = cr.PLAN_ID
  AND cq.PERIOD_ID = cr.PERIOD_ID
WHERE cr.PERIOD_ID = '2026-Q2'
ORDER BY cp.NAME;

Note the CASE statement: it handles zero quotas (div by zero protection) and maps attainment % to tier payouts. The TIER_DESCRIPTION column is for human review: "Why did JSMITH earn 125%? Because they hit 150% attainment and the plan includes a 25% accelerator." This query is useful for auditing and explaining payouts to reps.

Finding Pipeline Errors

When credits fail during pipeline runs, they're logged in error tables. Query to find them:

SAP HANA Database SQL — Retrieve recent pipeline errors
-- Recent pipeline errors: what failed and why
SELECT
  cpe.ERROR_ID,
  cpe.RUN_ID,
  cpe.CREDIT_ID,
  cpe.PARTICIPANT_ID,
  cpe.ERROR_CODE,
  cpe.ERROR_MESSAGE,
  cpe.CREATED_DATE,
  cc.AMOUNT,
  cc.SOURCE_REF
FROM CSC_PIPELINE_ERROR cpe
LEFT JOIN CSC_CREDIT cc
  ON cc.CREDIT_ID = cpe.CREDIT_ID
WHERE cpe.CREATED_DATE >= ADD_DAYS(CURRENT_DATE, -7)
ORDER BY cpe.CREATED_DATE DESC;

Common ERROR_CODE values:

  • PARTICIPANT_NOT_FOUND — PARTICIPANT_ID doesn't exist in CSC_PARTICIPANT
  • PLAN_NOT_FOUND — PLAN_ID doesn't exist
  • PLAN_ASSIGNMENT_MISSING — Participant isn't assigned to this plan for this period
  • PERIOD_NOT_FOUND — PERIOD_ID doesn't exist in CSC_PLAN_PERIOD
  • QUOTA_MISSING — No quota defined for this participant/plan/period
  • CALCULATION_FAILURE — Rate table lookup failed or formula error

Route PARTICIPANT_NOT_FOUND errors to the Data team (check if employee was loaded). Route PLAN_ASSIGNMENT_MISSING to the Plan Admin team (check if assignment date range matches credit date). These are your two highest-volume issues.

Full vs Incremental Pipeline Runs

The pipeline has two modes:

  • Full Run — Process ALL credits for the period, recalculate ALL results from scratch. Use this monthly at period close, or when you change plan configuration and need to recalculate existing results.
  • Incremental Run — Process only new/changed credits since the last run. Use this daily for ongoing feeds. Faster but riskier (if you miss an update in the source system, it won't be caught until the next full run).

Best practice: Run incremental daily, and a full run weekly (e.g., Sunday night) as a safety check. If the weekly full run produces different results than the incremental runs, you've found a data quality issue in the source system.

Pipeline Run Comparison: SAP SuccessFactors IM vs Callidus

Pipeline AspectCallidus CommissionsSAP SuccessFactors IM StagesLoad → Process → Calc → Approve → Export (5 stages, similar)Import → Classify → Calculate → Approve → Pay (same pattern) Run MonitoringLogs are file-based or in a process log table; hard to queryCSC_PIPELINE_RUN table with structured status fields; easy to monitor Error HandlingFailed records in a separate error file; manual resolutionCSC_PIPELINE_ERROR table with error codes; automated retry possible Results TableTransactional storage of credits and results intermixedSeparate CSC_RESULTS with clear PARTICIPANT/PLAN/PERIOD granularity Incremental SupportFull recalculation required for any config changeIncremental mode + full mode; can run both to validate Attainment CalcImplicit in result; no explicit ATTAINMENT_PCT fieldExplicit ATTAINMENT_PCT field; easier to aggregate and analyze

Approval Workflow Integration

After calculation, results sit in STATUS='CALCULATED' until approved. The approval process is handled by SAP Advanced Workflow (a separate product). The workflow:

  1. Routes calculated results to an approval queue (manager, finance team, plan owner)
  2. Approver reviews results (usually a summary dashboard or a list view)
  3. Approver can: Accept, Reject, or Manually Adjust
  4. If Accepted, STATUS changes to 'APPROVED' in CSC_RESULTS
  5. Only APPROVED results can be exported to payroll

This is a critical control. Without approval, there's no one accountable for payouts. An approver might notice: "Why did JSMITH earn $500K when the plan caps incentives at $50K?" They can reject and trigger a recalculation.

ℹ️Key distinction: SAP Advanced Workflow is a SEPARATE product from SAP SuccessFactors IM. You cannot build approval workflows inside IM. If your implementation skips AW, you have no approval step and all calculated results go straight to payroll. This is a common implementation gap — always scope AW as a separate workstream.

Querying Approved vs Unapproved Results

Before exporting to payroll, verify all results are approved:

SAP HANA Database SQL — Verify all results are approved before payroll export
-- Check approval status for Q2 2026
SELECT
  STATUS,
  COUNT(*)              AS RESULT_COUNT,
  SUM(INCENTIVE_AMOUNT) AS TOTAL_PAYOUT
FROM CSC_RESULTS
WHERE PERIOD_ID = '2026-Q2'
GROUP BY STATUS
ORDER BY RESULT_COUNT DESC;

If you see a large number of CALCULATED (not yet approved), escalate to the approval team. If you see REJECTED, investigate why and either correct the underlying data or re-submit for approval.

Credit Reversal and Adjustment Handling

Credits can be reversed (chargebacks, refunds, order cancellations). When a credit is reversed:

  1. A new credit record is created with AMOUNT < 0 (or a separate reversal record).
  2. The pipeline processes the reversal credit, reducing the RESULT_AMOUNT and INCENTIVE_AMOUNT.
  3. The participant's payout is reduced accordingly.

Important: If a payout was already PAID, reversals require a clawback (a negative adjustment to future payroll). This is handled by the payroll system, but IM must flag it. Query for reversals impacting already-paid results:

SAP HANA Database SQL — Identify reversals of already-paid results
-- Credits reversed AFTER results were paid (clawback scenario)
SELECT
  cc.PARTICIPANT_ID,
  cp.NAME,
  cc.PERIOD_ID,
  cc.SOURCE_REF,
  cc.AMOUNT,
  cr.STATUS                 AS RESULT_STATUS,
  cr.INCENTIVE_AMOUNT,
  cc.CREATED_DATE           AS REVERSAL_DATE
FROM CSC_CREDIT cc
JOIN CSC_PARTICIPANT cp
  ON cp.PARTICIPANT_ID = cc.PARTICIPANT_ID
JOIN CSC_RESULTS cr
  ON cr.PARTICIPANT_ID = cc.PARTICIPANT_ID
  AND cr.PLAN_ID = cc.PLAN_ID
  AND cr.PERIOD_ID = cc.PERIOD_ID
WHERE cc.AMOUNT < 0
  AND cr.STATUS = 'PAID'
ORDER BY cc.CREATED_DATE DESC;

These cases need manual attention. The clawback must be processed in payroll or the participant is overpaid.

Performance Tuning the Pipeline

If your pipeline runs are taking longer than expected, profile these areas:

  • Quota lookups — If CSC_QUOTA is not indexed on (PLAN_ID, PARTICIPANT_ID, PERIOD_ID), queries will scan the whole table. Add a composite index.
  • Rate table joins — If rate tables are complex (multi-level banded rates), the calculation engine will process each credit slowly. Test rate configurations before go-live.
  • Plan hierarchy depth — Recursive lookups on deeply nested plan hierarchies are slow. Flatten to 2 levels if possible.
  • Lock contention — If multiple processes are updating CSC_RESULTS simultaneously, writes block. Serialize pipeline runs or partition results by plan/period.

Next Steps

You now understand how the pipeline executes, how to monitor it, and how to read results. The final lesson covers how SAP SuccessFactors IM integrates with other tools to complete the incentive management ecosystem.