Skip to main content

Gateway Use Cases

This page provides real-world examples of how to use each gateway type in common business scenarios.

Table of Contents

  1. Loan Application Processing
  2. Customer Onboarding
  3. Transaction Approval Workflow
  4. Fraud Detection
  5. Document Processing
  6. Customer Notification System
  7. Risk Assessment
  8. Account Closure

Loan Application Processing

Complete Workflow

A comprehensive loan application process using all three gateway types.

BPMN Implementation

<!-- 1. EXCLUSIVE: Route by amount -->
<bpmn:exclusiveGateway id="Gateway_Amount" default="Flow_Standard">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
return loanAmount > 50000 ? 'Flow_Senior' : 'Flow_Standard';
" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_Senior</bpmn:outgoing>
<bpmn:outgoing>Flow_Standard</bpmn:outgoing>
</bpmn:exclusiveGateway>

<!-- 2. PARALLEL: Background checks -->
<bpmn:parallelGateway id="Gateway_ChecksSplit">
<bpmn:outgoing>Flow_ToCredit</bpmn:outgoing>
<bpmn:outgoing>Flow_ToEmployment</bpmn:outgoing>
<bpmn:outgoing>Flow_ToIdentity</bpmn:outgoing>
</bpmn:parallelGateway>

<bpmn:serviceTask id="Task_CreditCheck" name="Credit Bureau Check" />
<bpmn:serviceTask id="Task_Employment" name="Employment Verification" />
<bpmn:serviceTask id="Task_Identity" name="Identity Verification" />

<bpmn:parallelGateway id="Gateway_ChecksJoin">
<bpmn:incoming>Flow_FromCredit</bpmn:incoming>
<bpmn:incoming>Flow_FromEmployment</bpmn:incoming>
<bpmn:incoming>Flow_FromIdentity</bpmn:incoming>
<bpmn:outgoing>Flow_ToRisk</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- 3. EXCLUSIVE: Risk decision -->
<bpmn:exclusiveGateway id="Gateway_Risk">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
const riskScore = calculateRiskScore(creditScore, employmentYears, debtToIncome);
if (riskScore < 30) return 'Flow_Approve';
if (riskScore < 70) return 'Flow_Review';
return 'Flow_Reject';
" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_Approve</bpmn:outgoing>
<bpmn:outgoing>Flow_Review</bpmn:outgoing>
<bpmn:outgoing>Flow_Reject</bpmn:outgoing>
</bpmn:exclusiveGateway>

<!-- 4. INCLUSIVE: Notifications -->
<bpmn:inclusiveGateway id="Gateway_Notify" default="Flow_Email">
<bpmn:outgoing>Flow_Email</bpmn:outgoing>
<bpmn:outgoing>Flow_SMS</bpmn:outgoing>
<bpmn:outgoing>Flow_Push</bpmn:outgoing>
</bpmn:inclusiveGateway>

<bpmn:sequenceFlow id="Flow_SMS" sourceRef="Gateway_Notify" targetRef="Task_SMS">
<bpmn:conditionExpression>customerPhone !== null</bpmn:conditionExpression>
</bpmn:sequenceFlow>

<bpmn:sequenceFlow id="Flow_Push" sourceRef="Gateway_Notify" targetRef="Task_Push">
<bpmn:conditionExpression>hasMobileApp === true</bpmn:conditionExpression>
</bpmn:sequenceFlow>

Key Points:

  • Exclusive for routing decisions (amount threshold, risk assessment)
  • Parallel for independent checks that can run simultaneously
  • Inclusive for notifications through available channels

Customer Onboarding

Scenario

New customer registration with conditional verification steps.

Requirements

  • All customers: Email verification, basic profile setup
  • Corporate customers: Business verification, tax ID validation
  • High-value customers: Additional reference checks
  • International customers: Address verification via third-party

Implementation

<!-- Determine customer type -->
<bpmn:exclusiveGateway id="Gateway_CustomerType">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
return customerType; // 'INDIVIDUAL', 'CORPORATE', 'INTERNATIONAL'
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:exclusiveGateway>

<!-- For all customer types: Basic verification (parallel) -->
<bpmn:parallelGateway id="Gateway_BasicVerify">
<bpmn:outgoing>Flow_EmailVerify</bpmn:outgoing>
<bpmn:outgoing>Flow_ProfileSetup</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- Conditional additional checks (inclusive) -->
<bpmn:inclusiveGateway id="Gateway_AdditionalChecks" default="Flow_Complete">
<bpmn:outgoing>Flow_Complete</bpmn:outgoing>
<bpmn:outgoing>Flow_BusinessVerify</bpmn:outgoing>
<bpmn:outgoing>Flow_ReferenceCheck</bpmn:outgoing>
<bpmn:outgoing>Flow_AddressVerify</bpmn:outgoing>
</bpmn:inclusiveGateway>

<!-- Business verification for corporate -->
<bpmn:sequenceFlow id="Flow_BusinessVerify"
sourceRef="Gateway_AdditionalChecks"
targetRef="Task_BusinessVerify">
<bpmn:conditionExpression>
customerType === 'CORPORATE'
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

<!-- Reference check for high-value -->
<bpmn:sequenceFlow id="Flow_ReferenceCheck"
sourceRef="Gateway_AdditionalChecks"
targetRef="Task_ReferenceCheck">
<bpmn:conditionExpression>
estimatedTransactionVolume > 100000
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

<!-- Address verification for international -->
<bpmn:sequenceFlow id="Flow_AddressVerify"
sourceRef="Gateway_AdditionalChecks"
targetRef="Task_AddressVerify">
<bpmn:conditionExpression>
country !== 'US' &amp;&amp; country !== 'CA'
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

Execution Examples

Customer TypeAdditional Checks Activated
Individual, US, low-valueNone (just basic)
Corporate, US, low-valueBusiness verification
Individual, UK, high-valueAddress verification + Reference check
Corporate, International, high-valueAll three additional checks

Transaction Approval Workflow

Multi-Level Approval Based on Amount and Type

<bpmn:exclusiveGateway id="Gateway_AmountCheck">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
// Route based on amount and transaction type
if (transactionType === 'WIRE_INTERNATIONAL' &amp;&amp; amount > 10000) {
return 'Flow_ComplexApproval';
}

if (amount > 100000) {
return 'Flow_ExecutiveApproval';
} else if (amount > 50000) {
return 'Flow_ManagerApproval';
} else if (amount > 10000) {
return 'Flow_OfficerApproval';
} else {
return 'Flow_AutoApprove';
}
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:exclusiveGateway>

<!-- Complex approval requires parallel checks -->
<bpmn:parallelGateway id="Gateway_ComplexApproval">
<bpmn:outgoing>Flow_ToCompliance</bpmn:outgoing>
<bpmn:outgoing>Flow_ToFraud</bpmn:outgoing>
<bpmn:outgoing>Flow_ToManager</bpmn:outgoing>
</bpmn:parallelGateway>

<bpmn:userTask id="Task_ComplianceReview" name="Compliance Review">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="AssignedRole" value="ComplianceOfficer" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:userTask>

<bpmn:serviceTask id="Task_FraudCheck" name="Fraud Detection Check" />

<bpmn:userTask id="Task_ManagerApproval" name="Manager Approval">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="AssignedRole" value="TransactionManager" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:userTask>

<!-- All three must complete -->
<bpmn:parallelGateway id="Gateway_ComplexJoin">
<bpmn:incoming>Flow_FromCompliance</bpmn:incoming>
<bpmn:incoming>Flow_FromFraud</bpmn:incoming>
<bpmn:incoming>Flow_FromManager</bpmn:incoming>
<bpmn:outgoing>Flow_ToFinalDecision</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- Final decision based on all approvals -->
<bpmn:exclusiveGateway id="Gateway_FinalDecision">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
// All must approve
if (complianceApproved &amp;&amp; !fraudDetected &amp;&amp; managerApproved) {
return 'Flow_Execute';
} else {
return 'Flow_Decline';
}
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:exclusiveGateway>

Flow Diagram:


Fraud Detection

Real-Time Multi-Check System

<!-- Initial screening (parallel checks) -->
<bpmn:parallelGateway id="Gateway_FraudScreening">
<bpmn:outgoing>Flow_ToVelocityCheck</bpmn:outgoing>
<bpmn:outgoing>Flow_ToPatternMatch</bpmn:outgoing>
<bpmn:outgoing>Flow_ToBlacklistCheck</bpmn:outgoing>
<bpmn:outgoing>Flow_ToGeoCheck</bpmn:outgoing>
</bpmn:parallelGateway>

<bpmn:serviceTask id="Task_VelocityCheck" name="Velocity Check">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Command" value="CheckTransactionVelocity" />
<custom:property name="Parameters" value='{
"customerId": "{customerId}",
"timeWindowMinutes": 60,
"maxTransactions": 10
}' />
</custom:properties>
</bpmn:extensionElements>
</bpmn:serviceTask>

<bpmn:serviceTask id="Task_PatternMatch" name="Pattern Matching" />
<bpmn:serviceTask id="Task_BlacklistCheck" name="Blacklist Check" />
<bpmn:serviceTask id="Task_GeoCheck" name="Geolocation Check" />

<!-- Wait for all checks -->
<bpmn:parallelGateway id="Gateway_FraudJoin">
<bpmn:incoming>Flow_FromVelocity</bpmn:incoming>
<bpmn:incoming>Flow_FromPattern</bpmn:incoming>
<bpmn:incoming>Flow_FromBlacklist</bpmn:incoming>
<bpmn:incoming>Flow_FromGeo</bpmn:incoming>
<bpmn:outgoing>Flow_ToRiskScore</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- Calculate risk score -->
<bpmn:scriptTask id="Task_CalculateRisk" name="Calculate Risk Score">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Script" value="
let riskScore = 0;

if (velocityExceeded) riskScore += 30;
if (suspiciousPattern) riskScore += 25;
if (onBlacklist) riskScore += 40;
if (geoMismatch) riskScore += 20;

// Additional factors
if (newDevice) riskScore += 10;
if (unusualTime) riskScore += 5;

totalRiskScore = riskScore;
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:scriptTask>

<!-- Risk-based decision -->
<bpmn:exclusiveGateway id="Gateway_RiskDecision">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
if (totalRiskScore >= 60) {
return 'Flow_Block';
} else if (totalRiskScore >= 30) {
return 'Flow_Review';
} else {
return 'Flow_Allow';
}
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:exclusiveGateway>

<!-- If review needed, conditional additional checks (inclusive) -->
<bpmn:inclusiveGateway id="Gateway_AdditionalChecks" default="Flow_HumanReview">
<bpmn:outgoing>Flow_HumanReview</bpmn:outgoing>
<bpmn:outgoing>Flow_CustomerContact</bpmn:outgoing>
<bpmn:outgoing>Flow_DocumentRequest</bpmn:outgoing>
</bpmn:inclusiveGateway>

<bpmn:sequenceFlow id="Flow_CustomerContact"
sourceRef="Gateway_AdditionalChecks"
targetRef="Task_ContactCustomer">
<bpmn:conditionExpression>
totalRiskScore >= 40
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

<bpmn:sequenceFlow id="Flow_DocumentRequest"
sourceRef="Gateway_AdditionalChecks"
targetRef="Task_RequestDocuments">
<bpmn:conditionExpression>
totalRiskScore >= 50 || onBlacklist === true
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

Risk Scoring:

Risk ScoreActionAdditional Steps
0-29AllowNone
30-39ReviewHuman review only
40-49ReviewHuman review + Customer contact
50-59ReviewHuman review + Customer contact + Documents
60+BlockImmediate block, no additional steps

Document Processing

Parallel Document Validation

<!-- Customer uploads multiple documents -->
<bpmn:parallelGateway id="Gateway_ProcessDocuments">
<bpmn:outgoing>Flow_ProcessPassport</bpmn:outgoing>
<bpmn:outgoing>Flow_ProcessProofAddress</bpmn:outgoing>
<bpmn:outgoing>Flow_ProcessIncomeProof</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- Each document processed independently -->
<bpmn:serviceTask id="Task_ValidatePassport" name="Validate Passport">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Command" value="ValidateIdentityDocument" />
<custom:property name="Parameters" value='{
"documentType": "PASSPORT",
"documentId": "{passportDocumentId}",
"checks": ["OCR", "MRZ_VALIDATION", "EXPIRY_CHECK", "FRAUD_DETECTION"]
}' />
</custom:properties>
</bpmn:extensionElements>
</bpmn:serviceTask>

<bpmn:serviceTask id="Task_ValidateAddress" name="Validate Proof of Address" />
<bpmn:serviceTask id="Task_ValidateIncome" name="Validate Income Proof" />

<bpmn:parallelGateway id="Gateway_DocumentsJoin">
<bpmn:incoming>Flow_FromPassport</bpmn:incoming>
<bpmn:incoming>Flow_FromAddress</bpmn:incoming>
<bpmn:incoming>Flow_FromIncome</bpmn:incoming>
<bpmn:outgoing>Flow_ToReview</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- Review results -->
<bpmn:scriptTask id="Task_ReviewResults" name="Review Validation Results">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Script" value="
// Count passed validations
const passed = [
passportValid,
addressValid,
incomeValid
].filter(v => v === true).length;

allDocumentsValid = (passed === 3);
partiallyValid = (passed >= 2);
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:scriptTask>

<!-- Decision based on results -->
<bpmn:exclusiveGateway id="Gateway_DocumentDecision">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
if (allDocumentsValid) {
return 'Flow_Approve';
} else if (partiallyValid) {
return 'Flow_RequestResubmit';
} else {
return 'Flow_Reject';
}
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:exclusiveGateway>

Customer Notification System

Comprehensive Multi-Channel Notifications

<bpmn:inclusiveGateway id="Gateway_NotificationChannels">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
const channels = [];

// Email: Always included if available
if (customerEmail) {
channels.push('Flow_Email');
}

// SMS: For urgent notifications or if preferred
if (customerPhone &amp;&amp; (notificationUrgency === 'HIGH' || preferredChannel === 'SMS')) {
channels.push('Flow_SMS');
}

// Push: If app installed and notifications enabled
if (hasMobileApp &amp;&amp; pushNotificationsEnabled) {
channels.push('Flow_Push');
}

// In-App: If currently logged in
if (isActiveSession) {
channels.push('Flow_InApp');
}

// WhatsApp: For international customers with WhatsApp
if (hasWhatsApp &amp;&amp; country !== 'US') {
channels.push('Flow_WhatsApp');
}

return channels.join(',');
" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_Email</bpmn:outgoing>
<bpmn:outgoing>Flow_SMS</bpmn:outgoing>
<bpmn:outgoing>Flow_Push</bpmn:outgoing>
<bpmn:outgoing>Flow_InApp</bpmn:outgoing>
<bpmn:outgoing>Flow_WhatsApp</bpmn:outgoing>
</bpmn:inclusiveGateway>

Notification Matrix:

ScenarioEmailSMSPushIn-AppWhatsApp
Low urgency, US, logged out
High urgency, US, logged in
Low urgency, International, app user
High urgency, International, no app

Risk Assessment

Comprehensive Risk Evaluation

<!-- Parallel data collection -->
<bpmn:parallelGateway id="Gateway_DataCollection">
<bpmn:outgoing>Flow_ToCreditData</bpmn:outgoing>
<bpmn:outgoing>Flow_ToTransactionHistory</bpmn:outgoing>
<bpmn:outgoing>Flow_ToExternalData</bpmn:outgoing>
</bpmn:parallelGateway>

<bpmn:serviceTask id="Task_FetchCreditData" name="Fetch Credit Data" />
<bpmn:serviceTask id="Task_AnalyzeTransactions" name="Analyze Transaction History" />
<bpmn:serviceTask id="Task_FetchExternalData" name="Fetch External Risk Data" />

<bpmn:parallelGateway id="Gateway_DataJoin">
<bpmn:incoming>Flow_FromCredit</bpmn:incoming>
<bpmn:incoming>Flow_FromTransactions</bpmn:incoming>
<bpmn:incoming>Flow_FromExternal</bpmn:incoming>
<bpmn:outgoing>Flow_ToCalculation</bpmn:outgoing>
</bpmn:parallelGateway>

<!-- Calculate risk score -->
<bpmn:scriptTask id="Task_CalculateRisk" name="Calculate Risk Score">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Script" value="
// Weighted risk calculation
const creditRisk = (850 - creditScore) / 8.5; // 0-100 scale
const transactionRisk = calculateTransactionRisk(transactionHistory);
const externalRisk = externalRiskScore;

// Apply weights
totalRisk = (creditRisk * 0.4) + (transactionRisk * 0.35) + (externalRisk * 0.25);

// Categorize
if (totalRisk < 30) riskCategory = 'LOW';
else if (totalRisk < 60) riskCategory = 'MEDIUM';
else riskCategory = 'HIGH';
" />
</custom:properties>
</bpmn:extensionElements>
</bpmn:scriptTask>

<!-- Route based on risk -->
<bpmn:exclusiveGateway id="Gateway_RiskRouting">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="return 'Flow_' + riskCategory;" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_LOW</bpmn:outgoing>
<bpmn:outgoing>Flow_MEDIUM</bpmn:outgoing>
<bpmn:outgoing>Flow_HIGH</bpmn:outgoing>
</bpmn:exclusiveGateway>

<!-- Medium risk: Additional conditional checks (inclusive) -->
<bpmn:inclusiveGateway id="Gateway_MediumRiskChecks" default="Flow_ManagerReview">
<bpmn:outgoing>Flow_ManagerReview</bpmn:outgoing>
<bpmn:outgoing>Flow_AdditionalVerification</bpmn:outgoing>
<bpmn:outgoing>Flow_CreditEnhancement</bpmn:outgoing>
</bpmn:inclusiveGateway>

<bpmn:sequenceFlow id="Flow_AdditionalVerification"
sourceRef="Gateway_MediumRiskChecks"
targetRef="Task_AdditionalVerification">
<bpmn:conditionExpression>
transactionRisk > 50
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

<bpmn:sequenceFlow id="Flow_CreditEnhancement"
sourceRef="Gateway_MediumRiskChecks"
targetRef="Task_RequestCollateral">
<bpmn:conditionExpression>
creditRisk > 60
</bpmn:conditionExpression>
</bpmn:sequenceFlow>

Account Closure

Conditional Cleanup Tasks

<bpmn:inclusiveGateway id="Gateway_CleanupTasks">
<bpmn:extensionElements>
<custom:properties>
<custom:property name="Condition" value="
const tasks = [];

// Always close the account
tasks.push('Flow_CloseAccount');

// Transfer funds if balance > 0
if (accountBalance > 0) {
tasks.push('Flow_TransferFunds');
}

// Cancel cards if any active
if (hasActiveCards) {
tasks.push('Flow_CancelCards');
}

// Cancel standing orders if any
if (hasStandingOrders) {
tasks.push('Flow_CancelStandingOrders');
}

// Cancel direct debits if any
if (hasDirectDebits) {
tasks.push('Flow_CancelDirectDebits');
}

// Archive data
tasks.push('Flow_ArchiveData');

return tasks.join(',');
" />
</custom:properties>
</bpmn:extensionElements>
<bpmn:outgoing>Flow_CloseAccount</bpmn:outgoing>
<bpmn:outgoing>Flow_TransferFunds</bpmn:outgoing>
<bpmn:outgoing>Flow_CancelCards</bpmn:outgoing>
<bpmn:outgoing>Flow_CancelStandingOrders</bpmn:outgoing>
<bpmn:outgoing>Flow_CancelDirectDebits</bpmn:outgoing>
<bpmn:outgoing>Flow_ArchiveData</bpmn:outgoing>
</bpmn:inclusiveGateway>

Cleanup Matrix:

Account StateTasks Executed
Basic account, $0 balanceClose + Archive
Account with balanceClose + Transfer + Archive
Account with cardsClose + Cancel Cards + Archive
Full account with all featuresAll 6 tasks

Summary

Gateway Selection Guide

ScenarioUse GatewayReason
Choose approval levelExclusiveOne approver needed
Run background checksParallelIndependent, simultaneous
Send notificationsInclusiveMultiple optional channels
Route by amountExclusiveSingle path based on threshold
Collect data sourcesParallelIndependent data fetching
Additional verificationInclusiveConditional extra checks
Risk-based routingExclusiveOne risk category
Document validationParallelIndependent document checks
Cleanup tasksInclusiveConditional cleanup based on state

Best Practices from Use Cases

  1. Use Exclusive for binary/categorical decisions - Approve/Reject, Risk Level, Amount Ranges
  2. Use Parallel for independent tasks - Background checks, Data collection, Document processing
  3. Use Inclusive for optional parallel tasks - Notifications, Additional checks, Cleanup tasks
  4. Combine gateways for complex flows - Exclusive routing → Parallel checks → Inclusive notifications
  5. Calculate before deciding - Use ScriptTask to prepare data, then gateway to route
  6. Always have fallback - Set default flows on Exclusive and Inclusive gateways

Next Steps