Return Callback
Overviewโ
The ReturnCallbackCommand resumes a paused process by returning results from a callback. This command handles two types of callbacks:
- Subprocess Callbacks (CallActivity) - Parent process waits for child subprocess to complete
- External Callbacks (ReceiveTask) - Process waits for webhook, payment gateway, or third-party API response
API Endpointโ
POST /api/core/cmd
Headersโ
Content-Type: application/json
Authorization: Bearer {access_token}
X-Tenant-ID: {tenant_id}
Request Structureโ
The command accepts either childInstanceId or correlationKey, but not both. Choose based on your scenario:
childInstanceId: For subprocess (CallActivity) completionscorrelationKey: For external callbacks (ReceiveTask, webhooks, API responses)
Request Type 1: Subprocess Callback (Using childInstanceId)โ
When to Use: Parent process pauses for a child subprocess (CallActivity) to complete
{
"cmd": "ReturnCallbackCommand",
"data": {
"childInstanceId": "child-process-abc-123",
"results": {
"creditScore": 750,
"riskLevel": "Low",
"approved": true
},
"isFailed": false
}
}
Key Points:
childInstanceIdis the process instance ID of the child subprocess- Parent process will resume at the CallActivity that spawned the child
resultsobject is merged into parent process variables
Request Type 2: External Callback (Using correlationKey)โ
When to Use: Process waits for external system (webhook, email approval, payment gateway, third-party API)
{
"cmd": "ReturnCallbackCommand",
"data": {
"correlationKey": "APPROVAL-LOAN123-1736544000",
"results": {
"approved": true,
"decidedBy": "manager@bank.com",
"decidedAt": "2026-01-10T14:30:00Z",
"comments": "Application approved"
},
"isFailed": false
}
}
Key Points:
correlationKeyis defined in the BPMN ReceiveTask'scorrelationKeyproperty- Can be auto-generated (
${instanceId}_${taskId}) or custom (${approvalId}) - Process resumes at the ReceiveTask that registered the callback
resultsobject is stored in the variable specified by ReceiveTask'sresultVariable
Failed Callback (Works with Both Types)โ
Scenario: Callback indicates a failure (payment declined, approval rejected, subprocess error)
With childInstanceId:
{
"cmd": "ReturnCallbackCommand",
"data": {
"childInstanceId": "child-process-abc-123",
"isFailed": true,
"errorMessage": "Credit check service unavailable"
}
}
With correlationKey:
{
"cmd": "ReturnCallbackCommand",
"data": {
"correlationKey": "PAYMENT-TXN-987654",
"isFailed": true,
"errorMessage": "Payment declined - insufficient funds"
}
}
What Happens:
- Process resumes but takes error/rejection path
- Error boundary event can catch the failure
- Alternative flow can be triggered (e.g., retry logic, notification)
Request Fieldsโ
| Field | Type | Required | Description |
|---|---|---|---|
childInstanceId | string | Either this or correlationKey | ID of child subprocess (for CallActivity) |
correlationKey | string | Either this or childInstanceId | Correlation key (for external callbacks/ReceiveTask) |
results | object | Yes | Data to return to parent process. Will be stored in process variables |
isFailed | boolean | No | Whether the callback failed (default: false) |
errorMessage | string | No | Error message if callback failed |
childInstanceId: Used when a subprocess completes (CallActivity)correlationKey: Used when an external system sends a webhook (ReceiveTask)
Use Casesโ
1. Email Approval Callbackโ
Scenario: User clicks "Approve" link in email, webhook calls this command
{
"cmd": "ReturnCallbackCommand",
"data": {
"correlationKey": "APPROVAL-LOAN123-1736544000",
"results": {
"approved": true,
"decision": "approved",
"decidedBy": "manager@bank.com",
"decidedAt": "2026-01-10T14:30:00Z",
"comments": "Loan approved after review"
}
}
}
What Happens:
- Command finds CallbackRegistry record by
correlationKey - Deserializes parent process state from database
- Stores
resultsin process variables (e.g.,approvalResult) - Resumes process from ReceiveTask
- Process continues to next task
2. Payment Gateway Callbackโ
Scenario: Paystack sends payment confirmation webhook
{
"cmd": "ReturnCallbackCommand",
"data": {
"correlationKey": "TXN-987654",
"results": {
"status": "success",
"transactionId": "TXN-987654",
"reference": "PSK-ABC123",
"amount": 50000,
"currency": "NGN",
"paidAt": "2026-01-10T15:00:00Z",
"gateway": "paystack",
"metadata": {
"accountNumber": "0123456789",
"customerName": "John Doe"
}
}
}
}
3. Credit Check Subprocess Callbackโ
Scenario: Child subprocess completes credit check
{
"cmd": "ReturnCallbackCommand",
"data": {
"childInstanceId": "credit-check-subprocess-456",
"results": {
"creditScore": 750,
"riskLevel": "Low",
"creditHistory": "Good",
"recommendations": ["Approve up to รขโยฆ100,000", "Standard interest rate"],
"checkedBy": "CreditBureau-API",
"checkedAt": "2026-01-10T16:00:00Z"
}
}
}
4. Failed Callbackโ
Scenario: External system failed to process request
{
"cmd": "ReturnCallbackCommand",
"data": {
"correlationKey": "TXN-123456",
"isFailed": true,
"errorMessage": "Payment gateway timeout after 30 seconds",
"results": {
"status": "failed",
"errorCode": "GATEWAY_TIMEOUT",
"attemptedAt": "2026-01-10T17:00:00Z"
}
}
}
How It Worksโ
Step-by-Step Flowโ
Internal Processingโ
-
Find Callback Registration:
Code Removed
Implementation details removed for security.
Contact support for implementation guidance. :::
-
Check Expiry (if timeout configured):
Code Removed
Implementation details removed for security.
Contact support for implementation guidance. :::
-
Deserialize Parent State:
Code Removed
Implementation details removed for security.
Contact support for implementation guidance. :::
-
Store Results in Variables:
Code Removed
Implementation details removed for security.
Contact support for implementation guidance. :::
-
Resume Process:
Code Removed
Implementation details removed for security.
Contact support for implementation guidance. :::
-
Mark Callback Complete:
Code Removed
Implementation details removed for security.
Contact support for implementation guidance. :::
CallbackRegistry Database Structureโ
The command queries the CallbackRegistry table to find the paused process:
CREATE TABLE CallbackRegistry (
Id BIGINT PRIMARY KEY IDENTITY,
-- Callback identification
CallbackType INT NOT NULL, -- 1=Subprocess, 2=External
ChildInstanceId NVARCHAR(100), -- For subprocess callbacks
CorrelationKey NVARCHAR(200), -- For external callbacks
-- Parent process info
ParentInstanceId NVARCHAR(100) NOT NULL,
CallbackTaskId NVARCHAR(100) NOT NULL,
ParentProcessState NVARCHAR(MAX) NOT NULL, -- Serialized process state
-- Message configuration
MessageRef NVARCHAR(100),
ResultVariable NVARCHAR(100), -- Where to store results
-- Timeout
TimeoutMinutes INT,
RegisteredAt DATETIME2 NOT NULL,
-- Status
Status INT NOT NULL, -- 1=Pending, 2=Completed, 3=Expired
CompletedAt DATETIME2,
CallbackResults NVARCHAR(MAX), -- Stored results
ErrorMessage NVARCHAR(500),
-- Webhook info
WebhookUrl NVARCHAR(500),
INDEX IX_CorrelationKey (CorrelationKey, Status),
INDEX IX_ChildInstanceId (ChildInstanceId, Status)
);
Response Structureโ
Success Responseโ
{
"isSuccessful": true,
"message": "Callback processed successfully. Process resumed.",
"data": {
"parentInstanceId": "loan-approval-123",
"callbackId": 456,
"resumedAt": "2026-01-10T14:30:00Z"
}
}
Error Responsesโ
Callback Not Foundโ
{
"isSuccessful": false,
"message": "No pending callback registration found",
"errorCode": "CALLBACK_NOT_FOUND"
}
Callback Expiredโ
{
"isSuccessful": false,
"message": "Callback has expired",
"errorCode": "CALLBACK_EXPIRED",
"data": {
"expiredAt": "2026-01-08T14:30:00Z",
"timeoutMinutes": 2880
}
}
Deserialization Failedโ
{
"isSuccessful": false,
"message": "Failed to deserialize parent process state",
"errorCode": "DESERIALIZATION_ERROR"
}
Integration Examplesโ
1. Webhook Controller (Email Approval)โ
Implementation details removed for security.
Contact support for implementation guidance.
2. Payment Gateway Webhookโ
Implementation details removed for security.
Contact support for implementation guidance.
3. Subprocess Completion (Automatic)โ
When a subprocess completes, the BPMN engine automatically calls ReturnCallbackCommand:
Implementation details removed for security.
Contact support for implementation guidance.
Related Commandsโ
- Start Process - Start a new process instance
- Signal Process - Signal a UserTask (different from callbacks!)
- Resume Process - Resume a paused process manually
Related Task Typesโ
- ReceiveTask - Wait for external callback
- CallActivity - Invoke subprocess
Related Advanced Patternsโ
- Callbacks - Complete callback system guide
- Callback Patterns - Payment gateways, webhooks
- Email Approval - Email-based approvals
Best Practicesโ
1. Always Set Correlation Keysโ
<!-- รขยล BAD: Auto-generated correlation key -->
<bpmn:receiveTask id="Wait" name="Wait for Payment"/>
<!-- รขลโฆ GOOD: Explicit correlation key -->
<bpmn:receiveTask id="WaitForPayment" name="Wait for Payment">
<bpmn:extensionElements>
<custom:correlationKey>${transactionId}</custom:correlationKey>
</bpmn:extensionElements>
</bpmn:receiveTask>
2. Set Timeoutsโ
<bpmn:receiveTask id="WaitForApproval">
<bpmn:extensionElements>
<custom:correlationKey>${approvalId}</custom:correlationKey>
<custom:timeoutMinutes>2880</custom:timeoutMinutes> <!-- 48 hours -->
</bpmn:extensionElements>
</bpmn:receiveTask>
3. Store Results in Named Variablesโ
<bpmn:receiveTask id="WaitForPayment">
<bpmn:extensionElements>
<custom:resultVariable>paymentResult</custom:resultVariable>
</bpmn:extensionElements>
</bpmn:receiveTask>
<!-- Later, access in gateway -->
<bpmn:sequenceFlow condition="${paymentResult.status == 'success'}"/>
4. Validate Webhooksโ
Implementation details removed for security.
Contact support for implementation guidance.
5. Handle Failed Callbacksโ
Implementation details removed for security.
Contact support for implementation guidance.
Then in BPMN, handle the error:
<bpmn:receiveTask id="WaitForPayment" name="Wait for Payment">
<bpmn:outgoing>ToCheckPayment</bpmn:outgoing>
</bpmn:receiveTask>
<bpmn:exclusiveGateway id="CheckPayment" name="Payment Success?">
<bpmn:incoming>ToCheckPayment</bpmn:incoming>
<bpmn:outgoing sequenceFlow="${paymentResult.status == 'success'}">ToSuccess</bpmn:outgoing>
<bpmn:outgoing sequenceFlow="${paymentResult.status == 'failed'}">ToRetry</bpmn:outgoing>
</bpmn:exclusiveGateway>
Summaryโ
ReturnCallbackCommand is the key command for resuming processes that are waiting at:
- รขลโฆ ReceiveTask - External webhooks, payment gateways, third-party APIs
- รขลโฆ CallActivity - Subprocess completions
Key Features:
- Correlation key matching (for external callbacks)
- Child instance ID matching (for subprocesses)
- Automatic timeout handling
- Result variable storage
- Automatic process resumption
Common Use Cases:
- Email approval links
- Payment gateway webhooks
- Third-party API callbacks
- Subprocess completions
- Mobile app confirmations
Next Steps:
- Review ReceiveTask documentation to understand how processes pause
- Check Callback Patterns for complete integration examples
- Read Email Approval guide for practical implementation