-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: SDK support for request-to-pay documented (#413)
* feat: Describing the SDK support for R2P - mojaloop/project#3340 * feat: added Plant UML file * Update docs/technical/sdk-scheme-adapter/RequestToPay.md Co-authored-by: Miguel de Barros <[email protected]> * Update docs/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml Co-authored-by: Miguel de Barros <[email protected]> * Update docs/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml Co-authored-by: Miguel de Barros <[email protected]> * Update docs/technical/sdk-scheme-adapter/RequestToPay.md Co-authored-by: Miguel de Barros <[email protected]> * Update docs/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml Co-authored-by: Miguel de Barros <[email protected]> * updated r2p sequenceDiagram.svg to latest version --------- Co-authored-by: Miguel de Barros <[email protected]>
- Loading branch information
1 parent
d87a770
commit 6ad904d
Showing
7 changed files
with
2,420 additions
and
17,987 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Request To Pay (R2P) - use-case support | ||
|
||
This documentation describes how the SDK Scheme Adaptor supports the request to pay use case. The request to pay use case is the bases for all Payee initiated transfers. Support for this use-case requires every DFSP in a Mojaloop switch to automatically process a transfer once a request to perform a transfer is received and validated. Having support for this use-case in the SDK-scheme-adapter is important as it minimised the development effort that each DFSP needs to make if a Scheme mandates participant support for this use case. This use case is particularly interesting from a testing perspective, as it enables remote testing as both a Payer DFSP and a Payee DFSP. | ||
|
||
> Important: | ||
> | ||
> 1. Not all features have been fully tested and aligned to the FSPIOP Specification, please refer to the following epic for progress on this: [#3344 - Enhance SDK Scheme Adaptor to support the request to Pay use case](https://github.com/mojaloop/project/issues/3344); | ||
> 2. There are currently no end-to-end tests verifying the full functionality which includes Authentication via OTP. See the following [Testing Toolkit Test Case collection release](https://github.com/mojaloop/testing-toolkit-test-cases/releases) for what is currently tested: [[email protected]](https://github.com/mojaloop/testing-toolkit-test-cases/releases/tag/v15.0.1); and | ||
> 3. Not all failure cases may have been fully implemented. Once again refer to the epic [#3344](https://github.com/mojaloop/project/issues/3344). | ||
> | ||
## Sequence Diagram | ||
|
||
1. The Payee DFSP initiates the R2P use case with **POST** /RequestToPay API call. | ||
2. The Payee DFSP optionally can validate the Payer. | ||
3. The Payer DFSP executes the R2P request with a **POST** /requestToPayTransfer API call. If the Authentication type is not provided in this call, then the flow assumes that the Payer will confirm the transfer and terms through a **PUT** /requestToPayTransfer, otherwise the appropriate authentication flow is executed. | ||
|
||
The diagram summarises this flow. | ||
|
||
|
||
![R2P Sequence Diagram](./assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg) | ||
|
||
## Detailed sequence diagram | ||
|
||
Below is a more detailed sequence diagram for the request to pay use case and the SDK Scheme Adapter API calls. | ||
|
||
![R2P Detailed Sequence Diagram](./assets/sequence/SDKrequestToPay.svg) | ||
|
||
|
195 changes: 195 additions & 0 deletions
195
docs/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.plantuml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
@startuml | ||
|
||
actor "Payer" as Payer | ||
box Payer DFSP | ||
participant "Core Banking System" as PayerDFSP | ||
participant "SDK" as PayerSDK | ||
end box | ||
participant "Mojaloop" as Mojaloop #d4f2f9 | ||
|
||
box Payee DFSP | ||
participant "SDK" as PayeeSDK | ||
participant "Core Banking System" as PayeeDFSP | ||
end box | ||
actor "Payee" as Payee | ||
autonumber 1 "<b>[0]" | ||
|
||
alt if (User Initiated OTP) | ||
Payer->PayerDFSP: Generate an OTP for me | ||
PayerDFSP->PayerDFSP:Generate | ||
PayerDFSP-->Payer: Here is your OTP | ||
end | ||
=== Payee initiated request to pay (R2P) == | ||
Payee->PayeeDFSP: I would like \nto receive 1000 TZS\n from +1234567890 | ||
PayeeDFSP->PayeeDFSP: Payer not within Payee System | ||
|
||
PayeeDFSP->PayeeSDK: **POST** /requestToPayTransfer | ||
note right | ||
{ | ||
"requestToPayTransactionId": "string", | ||
"from": { | ||
"type": "CONSUMER", | ||
"idType": "MSISDN", | ||
"idValue": "+1234567890", | ||
"idSubValue": "string" | ||
}, | ||
"to": {...}, | ||
"amountType": "RECEIVE", | ||
"currency": "TZS", | ||
"amount": "1000.0", | ||
"scenario": {...}, | ||
"initiator": "PAYEE", | ||
"initiatorType": "CONSUMER", | ||
"note": "Note sent to Payee." | ||
} | ||
end note | ||
activate PayeeSDK | ||
|
||
PayeeSDK->>Mojaloop: **GET** /parties | ||
Mojaloop->>PayerSDK: **GET** /parties | ||
PayerSDK->PayerDFSP: **GET** /parties | ||
PayerDFSP->PayerDFSP: Lookup Validate Payer Account | ||
PayerDFSP-->PayerSDK: return Payer information | ||
note left | ||
Payer information | ||
end note | ||
PayerSDK->>Mojaloop: **PUT** /parties | ||
Mojaloop->>PayeeSDK: **PUT** /parties | ||
|
||
alt If AutoAcceptParty = false | ||
PayeeSDK-->PayeeDFSP: **POST**\n /requestToPayTransfer \n(synchronous return) | ||
note left | ||
{ | ||
"requestToPayTransactionId": "string", | ||
"from": { | ||
"type": "CONSUMER", | ||
"idType": "MSISDN", | ||
"idValue": "1234567890", | ||
"idSubValue": "string", | ||
"displayName": "ryZ037pWP'lHu,Tu9,Tjl MRMbdMSpRGAHt4m6 2jk5L4'ePRWT", | ||
"firstName": "Henrik", | ||
"middleName": "Johannes", | ||
"lastName": "Karlsson", | ||
"dateOfBirth": "1966-06-16", | ||
"fspId": "string", | ||
"extensionList": [] | ||
}, | ||
"to": {...}, | ||
"amountType": "RECEIVE", | ||
"currency": "TZS", | ||
"amount": "1000.0", | ||
"transactionType": "TRANSFER", | ||
"note": "Note sent to Payee.", | ||
"currentState": "WAITING_FOR_PARTY_ACCEPTANCE", | ||
} | ||
end note | ||
PayeeDFSP->PayeeSDK: **PUT** /requestToPay/\n{requestToPayId} | ||
note right | ||
{ | ||
acceptParty: true | ||
} | ||
end note | ||
else | ||
PayeeSDK->PayeeSDK: Automatically \nAcceptParty by updating\n status | ||
end | ||
|
||
PayeeSDK->>Mojaloop: **POST** /transactionRequests | ||
Mojaloop->>PayerSDK: **POST** /transactionRequests | ||
PayerSDK->PayerDFSP: **POST** /transactionRequests | ||
PayerDFSP->PayerDFSP: Validate request\n to pay request | ||
PayerDFSP-->PayerSDK: return | ||
PayerSDK->>Mojaloop: **PUT** /transactionRequests/{ID} | ||
note left | ||
{ | ||
"transactionId": "b51ec534-ee48-4575-b6a9-ead2955b8069", | ||
"transactionRequestState": "RECEIVED", | ||
"AuthenticationType": {} | ||
"extensionList": {extension:[]} | ||
} | ||
end note | ||
Mojaloop->>PayeeSDK: **PUT** /transactionRequests | ||
PayeeSDK-->PayeeDFSP: return | ||
deactivate PayeeSDK | ||
|
||
=== Payer DFSP executes R2P request == | ||
|
||
PayerDFSP->PayerSDK: **POST** /RequestToPayTransfer | ||
note left | ||
Initiate R2P with AuthType | ||
end note | ||
activate PayerSDK | ||
PayerSDK->>Mojaloop: **POST** /quotes | ||
Mojaloop->>PayeeSDK: **POST** /quotes | ||
PayeeSDK->PayeeDFSP: **POST** /quoterequest | ||
PayeeDFSP->PayeeSDK: return quote | ||
PayeeSDK->>Mojaloop: **PUT** /quotes | ||
Mojaloop->>PayerSDK: **PUT** /quotes | ||
|
||
PayerSDK-->PayerDFSP: return \n(**POST** /RequestToPayTransfer) | ||
deactivate PayerSDK | ||
|
||
alt if AuthenticateType is null | ||
PayerDFSP->Payer: Present payment terms\n to Payer for acceptance | ||
Payer->PayerDFSP: I accept the payment terms | ||
else if AuthenticateType is OTP | ||
alt if (Automatic generated OTP) | ||
|
||
PayerDFSP->PayerDFSP: Generate OTP | ||
PayerDFSP->Payer: Present OTP to Payer | ||
end | ||
|
||
loop x retries | ||
PayerDFSP->PayerSDK: **PUT** /RequestToPayTransfer | ||
note left | ||
accept quote = true | ||
retries left = x | ||
end note | ||
|
||
PayerSDK->>Mojaloop: **GET** \n/authorizations/\n{transactionRequestID} | ||
Mojaloop->>PayeeSDK: **GET** \n/authorizations/\n{transactionRequestID} | ||
PayeeSDK->PayeeDFSP: **GET** \n/auth/{authtype}/{requestToPayId} | ||
PayeeDFSP->Payee: Get Payee to get\n Payer to enter OTP\n on POS | ||
Payer->PayeeDFSP: Enter OTP | ||
PayeeDFSP-->PayeeSDK: return OTP | ||
note right | ||
{ | ||
"otpValue": "string" | ||
} | ||
end note | ||
PayeeSDK->>Mojaloop: **PUT** /authorizations/{ID} | ||
Mojaloop->>PayerSDK: **PUT** /authorizations/{ID} | ||
PayerSDK-->PayerDFSP: synchronous return \n **POST** /requestToPayTransfer/\n{requestToPayTransactionId} | ||
PayerDFSP->PayerDFSP: Validate OTP | ||
|
||
end loop | ||
|
||
end | ||
|
||
|
||
|
||
alt if can proceed with transfer | ||
PayerDFSP->PayerDFSP: Reserve funds against \nPayer's account | ||
PayerDFSP-->PayerSDK: **PUT** \n/requestToPayTransfer/\n{requestToPayTransactionId} | ||
|
||
PayerSDK->>Mojaloop: **POST** /transfers | ||
activate PayerSDK | ||
Mojaloop->>PayeeSDK: **POST** /transfers | ||
PayeeSDK-->PayeeDFSP: **PUT** / **POST**\n /requestToPayTransfer/\n{requestToPayTransactionId}\n return | ||
PayeeDFSP->Payee: Notify user | ||
PayeeSDK->>Mojaloop: **PUT** /transfers \nreturn fulfilment | ||
Mojaloop->>PayerSDK: **PUT** /transfers | ||
deactivate PayerSDK | ||
PayerSDK->PayerDFSP: **POST** \n/newAPI \nNotify payer of transfer | ||
PayerDFSP->PayerDFSP: Commit transfer \nto Payer's account | ||
PayerDFSP->Payer: Notify Payer | ||
|
||
else if rejected | ||
|
||
PayerDFSP-->PayerSDK: return | ||
PayerSDK->>Mojaloop: **PUT** \n/requestToPayTransfer/\n{requestToPayTransactionId}\n rejected | ||
Mojaloop->>PayeeSDK: **PUT**\n /requestToPayTransfer/\n{requestToPayTransactionId}\n rejected | ||
PayeeSDK-->X PayeeDFSP: return rejected | ||
end | ||
|
||
|
||
@enduml |
202 changes: 202 additions & 0 deletions
202
docs/technical/sdk-scheme-adapter/assets/sequence/SDKrequestToPay.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions
4
...ical/sdk-scheme-adapter/assets/sequence/requestToPaySDK-R2P-SequenceDiagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.