Open mjbrichards opened 3 years ago
With apologies for the delay, I attach a revised sequence diagram and API definition document which are intended to address the problem of privacy relating to currency conversion information, while still allowing the transfer information to contain sufficient information to allow the switch to record the correct obligations. The base idea is that the debtor and creditor FSPs maintain an optional list of one or more dependents. Each dependent is the creditor party in a part of the transfer, which will have been committed before the transfer as a whole is committed, but whose obligations are not finally recorded by the switch until the main transfer has completed. The dependent contains the condition and fulfilment which refer to the subsidiary task, and sufficient information to allow the switch correctly to record the obligations associated with all the subsidiary tasks as well as the main task itself.
API Candidate for currency conversion support in Mojaloop v2.3.docx
Thanks @MichaelJBRichards,
Comments including some follow up on earlier discussions, sorry if I'm repeating myself:
dependents
still part of the POST /quotes? The Payee FSP shouldn't care about the FX as the amount is already in the Payee FSP's currency, if the Payer FSP has already decided to use the FXP's service of performing the FX. As stated in earlier comments, the Payee FSP can't decide to offer any new terms in the quote callback, it can just either agree with an optional payeeFspFee
, or reject the quote.dependents
part of POST /transfers? The FX transfer is already reserved in the POST /fxTransfers part (Step 42 to Step 53), it should just need to be committed. The condition and fulfillment for the FX transfer part should be enough for that?By removing these two, you would remove potential business sensitive information containing the FX rate from the Payer FSP to the Payee FSP, while still allowing the message to be signed.
But surely both parties will always know the exchange rate, because the quote response contains both the send amount and the payee receive amount? And the sending customer needs to know both.
I still think that the currency conversion, whichever party executed it (and both might), needs to form part of the terms on which the payment was agreed; not least because one of our RESTful principles is that a message should contain all of the information which the recipient needs to act on it. This means, I think that the PUT /transfers message needs to contain all of the information that the switch will need to assign the values correctly to its ledgers. You will note that I have restricted the definition of a dependent to include only the participant and the amount; but these are, I think, necessary for the switch to be able correctly to distribute the obligations incurred as a consequence of the payment. So the payee institution will definitely need to know which FXP performed the conversion; and, since this is the case, I saw no good reason not to include the information in the terms of the payment.
But surely both parties will always know the exchange rate, because the quote response contains both the send amount and the payee receive amount? And the sending customer needs to know both.
No, the quote callback only contains the amounts in the Payee's currency (see note between Step 34 and 35 in your flow, where all amounts are in RWF). The Payer FSP already knows the currency conversion required from the POST /fxQuotes and its callback (see Steps 20 to 28), and can as such show the amounts in both currencies to the Payer in Step 39. The Payer FSP will then use POST /fxTransfers to perform the required conversion (see note between step 42 and 43). This way there is no need for the Payee FSP to know anything about if or how a currency conversion has been performed, perhaps the Payer FSP had an account in both currencies that could be used for the transfer.
I still think that the currency conversion, whichever party executed it (and both might), needs to form part of the terms on which the payment was agreed; not least because one of our RESTful principles is that a message should contain all of the information which the recipient needs to act on it.
We are not sending all information in all requests today. For example in the POST /transfers, we are relying on information that has earlier been agreed in the POST /quotes. We are not stating that we are fully RESTful compliant. Why is it necessary for the Payee FSP in the flow above to know that a currency conversion has been performed, as long as it receives the required funds in the correct currency in some way from the Payer FSP? Maybe there is some very important reason, but then I would like to understand it.
You will note that I have restricted the definition of a dependent to include only the participant and the amount; but these are, I think, necessary for the switch to be able correctly to distribute the obligations incurred as a consequence of the payment.
The Switch has already reserved the transfers related to the currency conversion in earlier steps (POST /fxTransfers and its related callback, Steps 42 to 53), now it just needs to commit what has earlier been reserved? Sending the same thing again in POST /transfers as in POST /fxTransfers would just introduce potential errors in my view. Minimizing the information in POST /transfers would also minimize the changes needed for existing implementers.
So the payee institution will definitely need to know which FXP performed the conversion; and, since this is the case, I saw no good reason not to include the information in the terms of the payment.
Is this necessary per transfer in the Payee FSP? What I as a Payee FSP is interested in per transfer is that I have received the funds from the Payer FSP in my account at the Switch in some way so that I can be assured that I can perform the transfer to my account holder. As a Payee FSP I don't really care about the internal accounting in the Switch, i.e. if there were some other participant in between, such as the FXP, that actually sent the funds to me. In the Switch it is vital information to keep track of the internal accounting. But in the integration between the Payer FSP and Payee FSP, I don't see it as required information. But maybe there are other principles in Mojaloop that requires this?
I like the fx flow above. Doing the POST \fxQuote before the POST \transfers only works for the transfer amount type 'RECEIVE'. To support receive transfer type presumably the POST \quotes would have to be called before the POST \fxQuote. Maybe we should build another sequence diagram for that.
Thanks for your comments, @PaulGregoryBaker. I'm afraid we shan't be able to call quotes before we call fxQuotes, since the condition returned by fxQuotes forms part of the terms of the payment. Since this is the case, generation of a new condition in the process of re-quoting for currency conversion would invalidate the condition in the quote response for the transfer. In the case where the amountType was RECEIVE and the creditor party added fees, the debtor party would have to go round another quotation and approval cycle including the new conversion.
I've done some further thinking around the points raised by @henrka. Essentially, I think that reducing the information in the message to preserve the privacy of the conversion, as @henrka rightly proposes, implies further effort on the part of the switch. In previous incarnations, the burden on the switch (and especially the code changes required) were relatively light. I think that they are now more extensive, so I've included a separate document where I set out what I think they might be.
I've also revised the sequence diagram, and have aligned it with the latest state of the API document - in our various modifications it had got somewhat our of kilter. I attach all three documents, and await your comments with interest.
Converting dependencies to obligations.docx API Candidate for currency conversion support in Mojaloop v2.4.docx
Nice. There is a small error in the text description on 39.
A version of the sequence diagram showing currency conversion being initiated by the creditor participant.
Thanks @MichaelJBRichards,
Please find my initial comments/questions on the new flow where the Payee FSP performs the currency conversion:
validity
field according to the Word document.ilpPacket
in note between Steps 35 and 36, shouldn't that be named transaction
instead, as in note between Steps 42 and 43 for POST /transfers?transferAmount
in note between Steps 35 and 36 should use currency MWK, not MWS.payeeFspFee
should preferably be in Payer FSP's currency (MWK), as the Payer FSP in this case wouldn't like to deal with the Payee's currency (ZMW). In Step 39-40 the fee of 5 ZMW is magically converted to 250 MWK, without the Payer FSP knowing the FX rate.transaction
object (that is called ilpPacket
in POST /quotes, see earlier comment) differs between PUT /quotes and POST /transfers, this should be the same.targetAmount
is different from the targetAmount
in PUT /fxQuotes/, which is a bit confusing logic (3 ZMW in charges has been withdrawn). To me, the logical thing would be to have the same targetAmount
, but also including the same charges as before.Thank you, @henrka , for your usual careful review. I have been doing some refactoring in order to align the FX API more closely with the way in which I would expect the ISO 20022 version of the FX API to work, and I will describe that later; but I will start, as usual, by commenting on your comments:
When I started thinking about how we might represent currency conversions in ISO 20022, it seemed to me that we wanted to make the content of the currency conversion endpoints as close as we could to the ordinary payment endpoints. So a currency conversion execution would be strongly analogous to an ordinary payment execution. The main obstacle to this seemed to me to be the dependents structure. I therefore propose that we should replace the dependents structure, in which the payment contains all the information about the subordinates (such as the conversion), with an additional field in the subordinate which links it to the master payment, using the master payment's transaction ID. This would, I think, achieve the same effect but with greater simplicity for the data structures (and it removes your reservation about using the condition...) I have produced a new version of the draft API specification incorporating this idea, and attach it, together with a new sequence diagram which shows the flow for a payment where conversion is done by the payee, but the amount is a RECEIVE amount (i.e. something like a merchant payment.) Let me know what you think.
API Candidate for currency conversion support in Mojaloop v2.6.docx
Thanks @MichaelJBRichards,
The changed flow without dependents is better! Please find my comments as usual (now with numbers instead to make it easier to relate to which one it is):
receiveCurrencies
to supportedCurrencies
, or just currencies
instead. The currency information of the Payer would then be sent as part of the Party
information in the POST /quotes in Step 13.conversion
type, and have its parameters on the root level of POST /fxQuotes instead? The conversion
type doesn't seem to be reused, so I don't know if there is a need to have a specific type for it? This would make the PUT /quotes more similar to data models for other requests in the FSPIOP API.conversionRequestId
and conversionId
? Neither seems to be reused outside of the scope of the POST/PUT /fxQuotes.governingTx
:). POST /fxTransfers seems to use relatedTransactionId
, can we please change to that or governingTransaction
or similar? Also related to governingTx
, how does FDH FX know the transaction ID, it is not sent in the POST /fxQuotes?conversionTerms
type, and have its parameters on the root level of PUT /fxQuotes instead? The conversionTerms
type doesn't seem to be reused, so I don't know if there is a need to have a specific type for it? This would make the PUT /fxQuotes more similar to data models for other requests in the FSPIOP API.Transaction
type (at least in current version) doesn't contain a payeeReceiveAmount
, is this something that should be added or is the payeeReceiveAmount
in the PUT /quotes enough?payeeReceiveAmount
.payeeReceiveAmount
in Transaction
type.relatedTransactionId
, is this same as the earlier governingTx
? Can we stick to one?relatedTransactionId
)? For the Switch the transaction ID is probably more important, but for the FXP the FX Quote should be the important key, so for me it would be logical to include both.New version of the FX functionality, which now supports conversion via a reference currency. The basic thinking behind this is:
I attach the revised draft API and a sequence diagram illustrating this. Any comments you might have would be most welcome. API Candidate for currency conversion support in Mojaloop v2.7.docx
My comments on your comments on the previous version of the sequence diagram:
I also made a couple of adjustments so that the creditor DFSP asks for its fee to be converted. This means that in the execution of the conversion the sums come out right...
In a belated attempt to make this issue easier for all of us, I have uploaded current versions of the documentation to our own repo in GitHub.
I attach the revised draft API and a sequence diagram illustrating this. Any comments you might have would be most welcome. API Candidate for currency conversion support in Mojaloop v2.7.docx
Just some review comments:
POST /quotes
has a typo suppoertedCurrencies
-> suppoertedCurroencies
@MichaelJBRichards FYI
My comments on your comments on the previous version of the sequence diagram:
- 1, 2, 3, 4: fixed.
- 5 and 8: I kind of like the idea of a conversion object, which I think of as containing the terms of the conversion in the same way as the transaction object contains the terms of the transfer. But I wouldn't die for it...
- 6, 7, 9: fixed.
- 10, 13: You are correct; I propose adding it to the transaction object in Section 7.1.3 of the API candidate.
- 11, 12: fixed
- 14: all instances now changed to determiningTransactionId
- 15: I had thought to use the condition as the key for the FXP to recognise the terms it was being asked to execute: please execute the conversion for which these are the signed terms. But I'm open to persuasion.
- 16: fixed
I also made a couple of adjustments so that the creditor DFSP asks for its fee to be converted. This means that in the execution of the conversion the sums come out right...
In a belated attempt to make this issue easier for all of us, I have uploaded current versions of the documentation to our own repo in GitHub.
Thanks @MichaelJBRichards,
payeeReceiveAmount
will then be duplicated and sent both in root level of PUT /quotes and in the transaction object. If we are moving away from ILP1 and the ASN1 encoded ILP packet, then we could probably remove it from the root level to avoid duplication if it is required in the transaction object instead, as this should be easily read directly in the JSON instead of in ASN1 encoded ILP packet.. Let's discuss."converter": "PAYER"
to inform that the Payer FSP has performed a currency conversion? This information is part of the PUT /quotes, so I guess this is just missed to be updated?Thanks very much for your comments, @henrka and @mdebarros .
On the sequence diagrams:
Conversion by the payee
Conversion by the payer
Reference currency (per MdB)
I will upload new copies of the sequence diagrams to the repository, together with a copy of the new draft of the API and some further sequence diagrams.
Some issues with the markdown document (possible conversion issues?):
Functions of an FXP
title: https://github.com/mojaloop/Currency-conversion/blob/main/APICandidate%20for%20currency%20conversion%20support%20in%20Mojaloop.md#functions-of-an-fxpI had a closer look at the optional converter field, and realised that it was no required for the reference currency flow that I was concerned about. I no longer have any concerns.
Also, just adding a comment from todays CCB discussion:
Raised issue on the implementation of the FX specification, specifically that Transfer prepare processing will ALWAYS have to check if there is an associated fxTransfers using the transactionId from the transaction-object.
As discussed this would be resolved in two ways:
@MichaelJBRichards please review the above comment, and let me know if we require any corrections.
I have uploaded a revised version of the candidate API document (MD version, natch) to the repository. It addresses comments made by Vijay in his review of the document.
Hmm… one of the original design principles separates the transaction logic from the simple transfer of money. I’m reluctant to start down the slippery slope of consulting the transaction details from the transfer logic. Should it be possible to encode the currency and fx details that are relevant for transfer as instructions to the clearing engine (in the transfer object)? We should not pierce the veil of the transaction object from within the clearing engine.
In this case there are two (or possibly even three) transaction objects. Well, one (or possibly two) of those are Conversion objects, which are the FX version of a transaction object. The set of objects are available to the switch in the same way as the transaction object is; and the switch checks that all the objects have been received and the associated requests approved before it finalises the payment and records all the obligations. So I don't think that there is a requirement to pierce the veil of the transaction object: it's just that this is a dance of the two (or possibly three) veils.
The concept of a Transfer Set seems natural and obvious to me. If the set of related transfers (including the conversions and local transfers) are organized into a set object with deterministic processing rules we build on the Interledger guarantees. That suggests all-or-none, two-phase clearing and commit across the set, but should not necessarily require ordering of transfers.
And I am happy to report that I think that's just what our proposed switch processing does. I would look forward to explaining how at the convening, but Cici wants to go big on cross-scheme currency conversion scenarios (and I, of course, concur). However, I am available to give, for a small fee, my famed explanation in which transfers are semi-convincingly played by beer bottles.
I am all for prototypes using read-at-hand materials, especially when beer is involved.
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
1.2 Document Version Information
2. Problem Description
2.1 Background
There has been discussion for some time in the Mojaloop community about how to manage currency conversion as part of funds transfers. A version of this has been implemented by Mowali, but this has operational drawbacks which have prompted a search for a simpler and more robust alternative. Following discussions with interested parties, an initial statement of a proposed solution has been created and is attached to this document.
This solution (like any solution to the problem of currency conversion) will require some changes to the FSPIOP API, and these are described in Section 6.1 of the attached document. It is proposed that the required changes should be non-breaking, but this is a matter for review.
2.2 Current Behaviour
The API does not support currency conversion at present.
Explain how you would like the API to behave.
The attached document explains the proposed behaviour
3. Proposed Solution Options
API Candidate for currency conversion support in Mojaloop.docx