Change Request: Notify Payee FSP in case of failure to commit on a Switch
elnyry-sam-k opened this issue · comments
Open API for FSP Interoperability - Change Request
Table of Contents
1. Preface
___This section contains basic information regarding the change request.
1.1 Change Request Information
| Requested By | Sam Kummary |
| Change Request Status | In review ☒ / Approved ☐ / Rejected ☐ |
| Approved/Rejected Date | |
1.2 Document Version Information
Version | Date | Author | Change Description |
---|---|---|---|
1.0 | 2021-10-03 | Sam Kummary | Initial version of the change request. Sent out for review. |
2. Problem Description
___2.1 Background
This issue is about handling error cases that happen during processing of PUT /transfers/{ID}
calls. Specifically, about how a Switch should deal with a scenario when a validation error occurs during processing of a PUT /transfers/{ID}
call. The API Error Handling section of the FSPIOP API Definition doesn't seem to touch on the error scenarios that happen during processing of PUT calls (validation or processing errors in a message that passes schema validation).
The FSPIOP API patterns do not support responding to a PUT with another PUT call. Inline with this, the current (Mojaloop) Switch implementation doesn't support sending an error callback (PUT /transfers/{ID}/error
) to the Payee FSP in case of failures that happen because of validation issues of a PUT /transfers/{ID}
call. However the Payer FSP is notified. However, if a Payee FSP requests for the final notification (by sending transferState as 'RESERVED' introduced with FSPIOP API v1.1: https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#6726-commit-notification)), it will receive a notification on finalization of the transfer.
Based on feedback from current adopters and implementers of Mojaloop, there is a need for Payee FSPs to be notified of failures in committing a transfer, which from the Payee FSP's perspective are COMMITTED, even in cases where the Payee FSP doesn't explicitly request to receive a final notification (using transferState as 'RESERVED').
2.2 Current Behavior
Explain how the API currently behaves.
Currently, if a validation error occurs during processing of a PUT /transfers/{ID}
call, there is no error notification or callback to the Payee FSP. Only the Payer FSP will be notified. (In implementation, an error will be logged, which will need to be followed-up manually or separately).
2.3 Requested Behavior
To support this request, as discussed on the FSPIOP SIG call on the 2nd of November 2021, a new notification will be introduced with the next version of the FSPIOP API (v1.2 or 2.0 depending on whichever is published first, TBD by the SIG).
A PATCH /transfers/{ID}/error
notification will be made to the Payee FSP in case of a processing failure resulting in a transfer being 'ABORTED' following a PUT /transfers/{ID}
From a Payee FSP.
Example:
When a PUT /transfers/{ID}
is sent from a Payee FSP in response to an earlier POST /transfers
call, with an invalid completedTimestamp
value which the Switch considers invalid (value passes schema validation, but is in the future, for example), then - currently the Switch doesn't make any additional call or send out any notification to the Payee FSP (only the Payer FSP receives an error callback and the error is logged internally).
With the proposed change, the Payee FSP receives a PATCH notification on the /transfers/{ID}/error
end-point
3. Proposed Solution Options
___Proposed solution: The Switch sends a PATCH notification on the /transfers/{ID}/error
end-point to a Payee FSP when processing errors such as validation issues happen while processing a PUT /transfers/{ID}
request from the Payee FSP.
This is in addition to the usual PUT error callback made to the Payer FSP on failures and also separate from the PATCH notification made to the Payee FSP when it explicitly requests a notification on finalization of a transfer (introduced in v1.1 by sending transferState=RESERVED)
Example:
If this change is approved and implemented,
- A
POST /transfers
request is sent by a Payer FSP
{
"transferId": "3f2be6ce-f2d7-4202-bd7b-1f33c5f979d9",
"payerFsp": "testingtoolkitdfsp",
"payeeFsp": "mojapayeefsp",
"amount": {
"amount": "100",
"currency": "USD"
},
"expiration": "2021-11-03T17:35:37.373Z",
"ilpPacket": "AYIDIgAAAAAAACcQIWcubW9qYXBheWVlZnNwLm1zaXNkbi4yNzcxMzgwMzkxMoIC9GV5SjBjbUZ1YzJGamRHbHZia2xrSWpvaU0yWXlZbVUyWTJVdFpqSmtOeTAwTWpBeUxXSmtOMkl0TVdZek0yTTFaamszT1dRNUlpd2ljWFZ2ZEdWSlpDSTZJakppTVRZMU1EWTJMVFkxWlRjdE5HTXhOaTFpWWpCa0xXWTRPV1l6WmpoaU5qWmtaU0lzSW5CaGVXVmxJanA3SW5CaGNuUjVTV1JKYm1adklqcDdJbkJoY25SNVNXUlVlWEJsSWpvaVRWTkpVMFJPSWl3aWNHRnlkSGxKWkdWdWRHbG1hV1Z5SWpvaU1qYzNNVE00TURNNU1USWlMQ0ptYzNCSlpDSTZJbTF2YW1Gd1lYbGxaV1p6Y0NKOWZTd2ljR0Y1WlhJaU9uc2ljR0Z5ZEhsSlpFbHVabThpT25zaWNHRnlkSGxKWkZSNWNHVWlPaUpOVTBsVFJFNGlMQ0p3WVhKMGVVbGtaVzUwYVdacFpYSWlPaUkwTkRFeU16UTFOamM0T1NJc0ltWnpjRWxrSWpvaWRHVnpkR2x1WjNSdmIyeHJhWFJrWm5Od0luMHNJbkJsY25OdmJtRnNTVzVtYnlJNmV5SmpiMjF3YkdWNFRtRnRaU0k2ZXlKbWFYSnpkRTVoYldVaU9pSkdhWEp6ZEc1aGJXVXRWR1Z6ZENJc0lteGhjM1JPWVcxbElqb2lUR0Z6ZEc1aGJXVXRWR1Z6ZENKOUxDSmtZWFJsVDJaQ2FYSjBhQ0k2SWpFNU9EUXRNREV0TURFaWZYMHNJbUZ0YjNWdWRDSTZleUpoYlc5MWJuUWlPaUl4TURBaUxDSmpkWEp5Wlc1amVTSTZJbFZUUkNKOUxDSjBjbUZ1YzJGamRHbHZibFI1Y0dVaU9uc2ljMk5sYm1GeWFXOGlPaUpVVWtGT1UwWkZVaUlzSW1sdWFYUnBZWFJ2Y2lJNklsQkJXVVZTSWl3aWFXNXBkR2xoZEc5eVZIbHdaU0k2SWtOUFRsTlZUVVZTSW4xOQA",
"condition": "9ee-caNM-FwogFXc3wV6T_Wgw0OATckyfAgJrQPBqx0"
}
- The Payee FSP receives it and responds with a corresponding
PUT /transfers/3f2be6ce-f2d7-4202-bd7b-1f33c5f979d9
message with an invalidcompletedTimestamp
value that follows the data type pattern but is invalid (is in the future according to the Switch), or some other validation failure happens on the Switch (the fulfilment is invalid, etc).
{
"completedTimestamp": "2023-11-03T17:34:37.786Z",
"transferState": "COMMITTED",
"fulfilment": "dLsfm72QFTgzIo5SteCWwqoB4yIZt3RLmG7k4fIH84k"
}
- The Switch logs it as an error and marks the transfer as ABORTED.
- An error callback
PUT /transfers/3f2be6ce-f2d7-4202-bd7b-1f33c5f979d9/error
is sent to the Payer FSP and an error notificationPATCH /transfers/3f2be6ce-f2d7-4202-bd7b-1f33c5f979d9/error
is sent to the Payee FSP.
{
"errorInformation": {
"errorCode": "3100",
"errorDescription": "Generic validation error"
}
}
This issue is about handling error cases that happen during processing of
PUT /transfers/{ID}
calls. Specifically, about how a Switch should deal with a scenario when a validation error occurs during processing of aPUT /transfers/{ID}
call. The API Error Handling section of the FSPIOP API Definition doesn't seem to touch on the error scenarios that happen during processing of PUT calls (validation or processing errors in a message that passes schema validation).
I would clarify the kind of validations, i.e. business
validations error occurs during processing of a PUT /transfers/{ID}
call.
Other validations like Interface, etc are done elsewhere during the sync response.
@elnyry-sam-k I think we also need to address how this will impact the "RESERVED" use-case.
I.e. If there is a similar business validation failure in that situation, will we respond with a PATCH /transfers/{transferId}
or do we use the new PATCH /transfers/{transferId}/error
endpoint instead?
I think it needs to be clear as to when each should be used.
I feel that in both scenarios the PATCH /transfers/{transferId}/error
endpoint should be used, and in the "RESERVED" use-case a notification is sent to the PATCH /transfers/{transferId}
if-and-only-if the transfer is already in an aborted state. Let me know your thoughts here?
@sri-miriyala this is very much related to the point that you brought up during standup.
This issue is about handling error cases that happen during processing of
PUT /transfers/{ID}
calls. Specifically, about how a Switch should deal with a scenario when a validation error occurs during processing of aPUT /transfers/{ID}
call. The API Error Handling section of the FSPIOP API Definition doesn't seem to touch on the error scenarios that happen during processing of PUT calls (validation or processing errors in a message that passes schema validation).I would clarify the kind of validations, i.e.
business
validations error occurs during processing of aPUT /transfers/{ID}
call.Other validations like Interface, etc are done elsewhere during the sync response.
Thanks Miguel; yes - I mentioned that these messages pass schema validation, so hoping that should take care of that.. please let me know if we need to be more explicit.
I agree, @mdebarros: all error responses should go to the /error endpoint rather than the success endpoint. I think that this will make everything more consistent and easier for implementers to understand.
I kind of assumed, @elnyry-sam-k, that schema validation occurs as part of the synchronous validation and that a failure will result in an immediate 400 response. Is that not true?
@elnyry-sam-k I think we also need to address how this will impact the "RESERVED" use-case.
I.e. If there is a similar business validation failure in that situation, will we respond with a
PATCH /transfers/{transferId}
or do we use the newPATCH /transfers/{transferId}/error
endpoint instead?I think it needs to be clear as to when each should be used.
I feel that in both scenarios the
PATCH /transfers/{transferId}/error
endpoint should be used, and in the "RESERVED" use-case a notification is sent to thePATCH /transfers/{transferId}
if-and-only-if the transfer is already in an aborted state. Let me know your thoughts here?@sri-miriyala this is very much related to the point that you brought up during standup.
This is a good item to specify , @mdebarros .
Yes - I agree with you that in a scenarios where a PUT /transfers/{ID}
that uses transferState=RESERVED has an error (not schema validation) a PATCH /transfers/{ID}/error
endpoint should be used..
However would like to discuss this part further: "and in the "RESERVED" use-case a notification is sent to the PATCH /transfers/{transferId} if-and-only-if the transfer is already in an aborted state. "
I agree, @mdebarros: all error responses should go to the /error endpoint rather than the success endpoint. I think that this will make everything more consistent and easier for implementers to understand.
I kind of assumed, @elnyry-sam-k, that schema validation occurs as part of the synchronous validation and that a failure will result in an immediate 400 response. Is that not true?
Thanks @MichaelJBRichards. Yes it is true; schema validation will indeed result in an immediate, synchronous error in case of failure with a 400 HTTP code (and some additional details as to which required fields are missing or which fields do not follow the required data type, etc)..
Why can't we just return a PUT /transfers/{ID}/error
? To the Payee DFSP? Why does it need to be a PATCH
?
hi @lewisdaly , the architecture and patterns we adopted do not support responding to a PUT callback with another PUT callback; the patterns discussed here: https://docs.mojaloop.io/mojaloop-specification/fspiop-api/documents/API%20Definition%20v1.1.html#323-http-sequence-flow
Hence the need for a PATCH for notifications
@elnyry-sam-k I think we also need to address how this will impact the "RESERVED" use-case.
I.e. If there is a similar business validation failure in that situation, will we respond with aPATCH /transfers/{transferId}
or do we use the newPATCH /transfers/{transferId}/error
endpoint instead?
I think it needs to be clear as to when each should be used.
I feel that in both scenarios thePATCH /transfers/{transferId}/error
endpoint should be used, and in the "RESERVED" use-case a notification is sent to thePATCH /transfers/{transferId}
if-and-only-if the transfer is already in an aborted state. Let me know your thoughts here?
@sri-miriyala this is very much related to the point that you brought up during standup.This is a good item to specify , @mdebarros .
Yes - I agree with you that in a scenarios where a
PUT /transfers/{ID}
that uses transferState=RESERVED has an error (not schema validation) aPATCH /transfers/{ID}/error
endpoint should be used..However would like to discuss this part further: "and in the "RESERVED" use-case a notification is sent to the PATCH /transfers/{transferId} if-and-only-if the transfer is already in an aborted state. "
I'm fine with using PATCH /transfers/{ID}/error when there is an error in the PUT /transfers/{ID} sent from the Payee FSP, both when RESERVED
and COMMITTED
is used. I would like to avoid using PATCH /transfers/{ID}/error when RESERVED
is used and the transfer is not committed due to some other error, like lack of funds in Payer FSP account, as this would be a change in logic.
Using RESERVED
state in the PUT /transfers/{ID} callback as it is defined today is logically similar to a question if this transfer can be committed. The result of that question can yes (COMMITTED
), or no (ABORTED
). It is not an error to say that the transfer was aborted, as this is an expected possible outcome of the question.
By changing this to possibly return an error instead would mean that the current question if the transfer can be committed would be changed more into a demand to perform this commit, as you would get an error instead if it did not work out as expected. I would like to avoid change in logic if there is not a very good reason to do so, to minimize impact on existing implementers.
One possibility discussed in the SIG meeting today to avoid logic changes in a minor version:
- Version 1.2 of the API supports sending PATCH /transfers/{ID}/error from the Switch in case the Payee FSP is using PUT /transfers/{ID} with
COMMITTED
and the commit failed in the Switch.
No change for PUT /transfers/{ID} withRESERVED
as the Payee FSP is expecting a PATCH /transfers/{ID} with eitherCOMMITTED
orABORTED
in version 1.1. - Version 2.0 of the API adds same possibility of sending PATCH /transfers/{ID}/error from the Switch in case the Payee FSP is using PUT /transfers/{ID} with
RESERVED
and there is an error.
Thanks Henrik; hopefully this can be closed out today so that we can move to the Solution Proposal
I'm fine with using the earlier suggested possibility in #103 (comment). It should be fine to move on to a solution as there have been no other comments.
Thanks @ehenrka !