Overview
This section provides annotated payload examples for error scenarios and edge cases, focusing on how responses must be interpreted and handled in production environments.
While previous sections focus on successful execution paths, real-world integrations must correctly handle:
- Validation errors
- Business declines
- Asynchronous timeouts
- Inconsistent or partial states
The objective of this section is to establish a clear interpretation model for non-success scenarios, ensuring robust and predictable integration behavior.
Scope and Context
This section focuses strictly on response payload interpretation and error handling patterns.
For:
- End-to-end flow sequencing → see F.1 End-to-End Integration Examples
- Payment flow definitions → see D. Payment Methods
- Status and error semantics → see C. Meta Information, Codes and Transaction States
- Webhook structures → see E.1 Webhooks (Notifications)
1. Validation Errors (Request Rejected)
Response (Annotated)
{
"returnStatus": {
"statusCode": "10.100.0001",
"statusMsg": "Invalid request payload"
}
}
Interpretation
- The request was rejected at validation level
- No transaction was created
transactionIDis not present
Typical Causes
- Missing required fields
- Invalid field formats (e.g., timestamp, currency)
- Unsupported combinations (paymentType vs paymentMethod)
Handling Guidance
- Do not retry blindly
- Correct the payload before resubmitting
- Log full request/response for diagnostics
2. Technical Success with Business Decline
Response (Annotated)
{
"returnStatus": {
"statusCode": "000",
"statusMsg": "Success"
},
"paymentStatus": "Declined",
"transactionID": "txDECLINE123456"
}
Interpretation
- API call succeeded (
returnStatus = 000) - Payment was not approved (
paymentStatus = Declined)
Typical Causes
- Insufficient funds
- Card issuer rejection
- Risk or fraud rules
Handling Guidance
- Treat as final state
- Do not retry automatically
- Provide clear feedback to the customer
- Allow alternative payment method
3. Pending / InProcessing States
Response (Annotated)
{
"returnStatus": {
"statusCode": "000",
"statusMsg": "Success"
},
"paymentStatus": "Pending",
"transactionID": "txPENDING123456"
}
Interpretation
- Request accepted
- Transaction is not yet finalized
Typical Scenarios
- 3DS authentication required (CARD)
- Customer confirmation pending (MB WAY)
- Deferred payment (REFERENCE)
Handling Guidance
- Do not assume success or failure
- Wait for:
- Webhook notification
- Status inquiry confirmation
4. Timeout / Expired Transactions
Response (Annotated)
{
"returnStatus": {
"statusCode": "000",
"statusMsg": "Success"
},
"paymentStatus": "Timeout",
"transactionID": "txPENDING123456"
}
Interpretation
- Transaction was not completed within allowed time
- Considered final non-success state
Typical Scenarios
- MB WAY user did not confirm
- Multibanco reference expired
- 3DS challenge abandoned
Handling Guidance
- Treat as final
- Allow user to retry with a new transaction
- Do not reuse the same
transactionID
5. Inconsistent or Partial States
Scenario
A webhook is received with a final state, but local system is out of sync.
Example Webhook
{
"returnStatus": {
"statusCode": "000"
},
"paymentStatus": "Success",
"transactionID": "txSYNC123456",
"notificationID": "notif123"
}
Handling Guidance
- External system indicates success
- Local system may not reflect this state yet
- Always confirm with:
GET <ROOT_URL>/api/v2/payments/{transactionID}/status
- Use status endpoint as source of truth
- Ensure idempotent processing of webhooks
6. Duplicate or Idempotency Conflicts
Response (Annotated)
{
"returnStatus": {
"statusCode": "10.200.0001",
"statusMsg": "Duplicate transaction"
},
"transactionID": "txDUPLICATE123456"
}
Interpretation
- Request reused an existing
merchantTransactionId - SPG may return:
- Existing transaction
- Or reject the request
Handling Guidance
- Ensure uniqueness of
merchantTransactionId - Implement idempotency logic on merchant side
- Avoid retrying with the same identifier
7. Error Handling Model (Recommended)
Decision Model
- Check
returnStatus.statusCodestatusCode != "000"→ validation or technical error
- If
"000"→ checkpaymentStatusSuccess→ final successDeclined/Timeout→ final failurePending/InProcessing→ non-final
- For non-final states
- Wait for webhook
- Confirm with status endpoint
Key Takeaways
returnStatusandpaymentStatusmust always be interpreted separately- A technically successful API call does not guarantee payment success
- Many payment methods are inherently asynchronous
- Final state must always be confirmed via:
- Webhooks
- Status endpoint
Robust handling of error scenarios and edge cases is essential to ensure:
- Accurate transaction state management
- Reliable reconciliation
- Resilient production integrations
This section provides the reference foundation for implementing defensive and reliable error handling in SPG integrations.