Skip to content

Commit

Permalink
feat: SDK support for request-to-pay documented (#413)
Browse files Browse the repository at this point in the history
* 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
PaulGregoryBaker and mdebarros authored Jun 26, 2023
1 parent d87a770 commit 6ad904d
Show file tree
Hide file tree
Showing 7 changed files with 2,420 additions and 17,987 deletions.
4 changes: 4 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,10 @@ module.exports = {
title: "Integration Flow Patterns",
path: "sdk-scheme-adapter/IntegrationFlowPatterns"
},
{
title: "Request To Pay - support",
path: "sdk-scheme-adapter/RequestToPay"
},
{
title: "Bulk Integration Flow Patterns",
path: "sdk-scheme-adapter/IntegrationBulkFlowPatterns"
Expand Down
29 changes: 29 additions & 0 deletions docs/technical/sdk-scheme-adapter/RequestToPay.md
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)


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 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.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6ad904d

Please sign in to comment.