PayTo Staging Testing Suite
Preface
The goal of this document is to provide a comprehensive guide which enables clients to complete testing of Shaype’s PayTo product (Initiator side) and validate integration of services that make payments possible. A key difference between the PayTo test suite in Shaype's staging environment and Shaype's production environment is that some parts of the process have been replaced by mocks as to not work on actual payments rails and allow for validation of expected API mechanisms. This approach allows for additional steps to be taken when testing in order to simulate the designed flow. Below you can find detailed instructions on how these should be triggered.
Disclaimer: Current mock solution is supported for mandates with 'ad-hoc' frequency. It is recommended to use only this frequency for the moment
Mandate statuses
To create a mandate with a specific status, use the POST/v1/payto/initiator/mandates endpoint and input a specific description field status to inform the response type that is returned. Description should follow specific syntax – status:{input status here}. If no status is provided in the description, then mandates for mock solution will be given ‘active’ status. Below you can find list of statuses allowed for mandates with their codes:
Created – status:created
Active – status:active
(no requirement to provide description)
Suspended – status:suspended
Cancelled – status:cancelled
Mandates created this way for mock solution should return a message with the ID of a mandate.
Disclaimer: On production, status changes to mandates should send a notifications to both Initiator and Payer with specific MSCH
trigger'. To simulate this behaviour use following endpoints while providing described trigger in the request body:
POST/v0/utils/generate-mandate-notification-initiator
- for Initiator
POST/v0/utils/generate-mandate-notification-payer
- for Payer
Mandate actions
Due to the fact mocks are static, trying to change a mandate status will not actually change it - mocks identify their data based on a pattern in the mandate ID. When triggering a status change action against a mandate, the system will return a message based on the validation that is present in the production environment.
Initiator
1. Create (Initiator)
This step has been described before in the section focusing on mandate statuses. To test a scenario where mandate creation has been rejected, simply create a mandate with the status ‘Created’ and then use endpoint:
POST/v0/utils/generate-mandate-notification-initiator
with reason code MCRD
in ‘trigger field to simulate a notification about mandate creation rejection.
Scheduling of a payment is done when information about successful mandate creation is received by the system. To schedule a payment based on a mandate on mocks, simply send notification with MCRC
trigger using
POST/v0/utils/generate-mandate-notification-initiator
Disclaimer: Mandates with fixed frequency (different than ad-hoc) can be provided with different settings and they will return a generated ID, but only a mocked set of settings will be saved. Trying to read data of such mandate will return predefined saved data.
2. Amend
To amend an Initiator’s data, it is required that the account should be in ‘ACTIVE’ status and belong to the same account holder. Otherwise, an error will be returned that data validation hasn’t passed.
To amend mandate data on Initiator, call
PUT/v1/payto/initiator/mandates/{mandateId}
If everything was correct, response should return message about successful amendment. Provided data should be reflected when information about the mandate Creditor is fetched.
3. Amend payment terms
To amend payment terms as an Initiator, use
PATCH /v1/payto/initiator/mandates/{mandateId}/payment_terms
If there is an uninitiated scheduled payment for a mandate where payment terms have been amended then that scheduled payment is replaced by a new one which bases its content on new data. For mocks, this doesn’t happen automatically, as this action is triggered by receiving a notification in the system about amendment. To simulate replacement of uninitiated scheduled payment, call the endpoint which sends notification to initiator with ’MAMC’ trigger
POST/v0/utils/generate-mandate-notification-initiator
4. Suspend
Only mandates that are in ACTIVE
status can be successfully suspended, due to status transition flow. Trying to suspend a mandate in other statuses will result in receiving a message:
Validation of the request for suspension mandate with id: {mandate_id}: To suspend a mandate it must be in active status."
To suspend a mandate, use PATCH/v1/payto/initiator/mandates/{mandateId}/suspend
5. Release
Similarly to mandate suspension, mandates can be released only when suspended. Therefore, trying to release it for any other status than SUSPENDED
will result in the return of an error with a message:
Validation of the request for releasing mandate with id: 1212c8af-164e-11ee-bbae-ede34bac00ac failed. To release a mandate it must be in suspended status.
To release a mandate, use PATCH/v1/payto/payer/mandates/{mandateId}/release
6. Cancel
Mandates can be cancelled from any other status they’re in but canceling a mandate from ‘CREATED’ status is not done by the Initiator. Therefore, it wasn’t included in the mocks as a scenario available for testing.
To test this action, call PATCH/v1/payto/initiator/mandates/{mandateId}/cancel
To fail cancelation of a mandate, simply provide an ID of a mandate that doesn’t exist.
7. Recall action
This endpoint serves to recall a bilateral action which hasn’t been yet confirmed by Payer (is pending). Since mocks are static, this endpoint only shows a response that can be received:
PATCH/v1/payto/initiator/mandates/{mandateId}/resolve
Depending on which bilateral action is recalled, specific party should receive a notification with a trigger which indicates what event caused a notification to trigger. Actions which are available for recall right now on production are respectively mandate creation (trigger: MCRR) and bilateral amendment (trigger: MAMR). Current endpoints for notification creation doesn't allow to use this trigger.
Payer
1. Amend
When platform customer takes the role of a Payer in the mandate, then the only thing that is allowed is to amend it to change account from which payment amount is debited during payment realisation. For mocks, the same logic applies to a mandate, and it is possible to change the account using this request. To change account that is set against a mandate, the account that is provided through amend must belong to same account holder of previous account. Also, new account must be in ACTIVE
status within the platform for the operation to be valid. In addition to that, the mandate itself must be in either ACTIVE
or SUSPENDED
status.
To change a Payer account, call PUT/v1/payto/payer/mandates/{mandateId}
2. Suspend
To suspend a mandate use PATCH/v1/payto/payer/mandates/{mandateId}/suspend
Only mandates in ACTIVE
status can be suspended. Validations for mock solutions are same as production environments and trying to suspend mandate with a status other than ACTIVE
will return an error.
3. Release
To release a mandate, call PATCH/v1/payto/payer/mandates/{mandateId}/release
Similarily to suspend action, release can be called only for mandates in SUSPENDED
status. Doing so for mandates with different status will result in an error, in line with the production environment.
4. Cancel
Canceling a mandate is done by use of
PATCH/v1/payto/payer/mandates/{mandateId}/cancel
This endpoint works using the same principles as those for cancelation of a mandate from the Initiator’s side.
5. Resolve action
In production environment, this action is used by Payer to confirm either mandate creation or bilateral amendment of a mandate. Status of a mock mandate is bound to ID pattern, therefore mandate status cannot be changed by this action. Amendment of data on a mandate also happens without confirmation from the Payer, so the endpoint that is used here returns only a fixed response but it can be used on a non-existing mandate to check if expected error is returned. To do so, use endpoint provided below.
PATCH/v1/payto/payer/mandates/{mandateId}/resolve/
Do not confuse this endpoint with the one used for mandate action recall, as this one requires query parameter to be added in the URL. To check that, please refer to API documentation.
Payment statuses
Mocks allow us to simulate different payment statuses - it is possible to call for payment instruction status within the platform. To do that, use the endpoint given below.
GET/v1/payto/initiator/mandates/{mandateId}/instructions/{instructionId}/status
For mocks, status of a payment that should be returned, is controlled by the description within a mandate.
Disclaimer: If no description is provided for a mandate which that allows to recognise status of a payment, then default status 'Settlement aborted' is returned at the moment.
Supported BSBs
GET /v1/payto/supported-bsbs/{bsbNumber}
For the debtor, any BSB can be used when creating a mandate. Using external BSB is advised when simulating a payment to keep data consistency when trying to recreate an external payment.
In order to return a 'not supported' response for a BSB, please use the BSB '000 000'.
{
"supported": false
}
Aliases (PayID)
When mandate is created, instead of providing account_id
to identify creditor or debtor, an alias might be used instead. On production, there are 4 methods that can be used as PayID. It is possible to make a payment on mocks when alias is provided for either Creditor, Debtor or both but it has to be of email
payIdType. They can be also used to identify an external account. Below you can find an example of a mandate creation request which involves an alias.
Disclaimer: When creating a mandate on mocks, existing PayId cannot be used. Email alias should follow a specific syntax <bsb><account_number>@something.com
Request
{
"creditorDetails": {
"accountAliasIdentification": "[email protected]",
"accountAliasType": "EMAIL_ADDRESS"
},
"debtorDetails": {
"accountAliasIdentification": "[email protected]",
"accountAliasType": "EMAIL_ADDRESS"
},
"description": "orchid Computer",
"idempotencyKey": "7ade5ae9-e24e-49e3-808e-3f8bd8104a9a",
"paymentTerms": {
"amount": {
"amount": 5,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "2"
},
"purposeCode": "OTHER",
"validityEndDate": "2025-01-26",
"validityStartDate": "2023-08-14"
}
Response
{
"mandateId": "1212f88c-36ad-11ee-bedb-852569012ad8"
}
Test suite
Assumptions
- Accounts for both debtor and creditor have been previously created in the platform, they have been activated and they should contain money on those accounts
- Cuscal configuration must be set up on staging to use
external-services-mock
(Shaype action)
Ad-hoc end-to-end payment - steps
1. Creating a mandate:
To create a mandate, use the POST/v1/payto/initiator/mandates
endpoint. Successful mandate creation should return its ID as a response. It is important to know that mocks allow for creation of mandates of different payment frequencies and AD-HOC payments, but to test payment flow in later steps, ad-hoc should be input as the frequency.
For this request, idempotencyKey
must be provided manually and it accepts any UUID.
Notes:
- On production, mandates initially are in status
CREATED
, but for mock solution they’re always set asACTIVE
unless specified in the mandate description. - To test a scenario when payment is successful, provide 'paymentstatus:safd' in the description
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "example description",
"idempotencyKey": "0e374c5b-c2de-45c1-b983-2753610e6ce3",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "OTHER”,
"validityEndDate": "2024-12-26",
"validityStartDate": "2023-07-18"
}
2. Triggering notification for mandate authorization:
On Shaype's production environment, Cuscal will ask Payer party for a confirmation of mandate authorisation after it is initiated but this step is omitted in staging. Instead, as a next step after confirming the mandate creation as Payer, we can simulate that such authorisation was given but since mock mandates are always in Active status unless specified, then this step is not needed to realise payments via mocks.
3. Triggering ad-hoc payment request for created and authorised mandate
When a mandate with ad-hoc frequency is created, to simulate start of payment realisation, POST /v1/payto/payments/adhoc
endpoint should be used. When doing so, make payment initiation request (MAPAIN) to the wire mock server. On production, remainder of the payment is realised by Cuscal but mocks require a simulation of this, found in the next steps.
Successful MAPAIN for mocks should return payment data with a message that payment has been executed successfully but this response is mocked and should be returned at payment finalisation.
Request
{
"amount": {
"amount": 2.00,
"currency": "AUD"
},
"idempotencyKey": "0e374c5b-c2de-45c1-b983-2753610e6ce3,
"description": "description",
"mandateId": "1212c23a-255c-11ee-9a8e-5d3239591cd9”
}
Response
{
"mandateId": "1212c23a-255c-11ee-9a8e-5d3239591cd9",
"instructionId": "ANNCAU22XXXI20230718000000000077240",
"transactionStatus": "SENT",
"transactionStatusDisplay": "Sent",
"statusIsFinal": false,
"message": "Adhoc payment executed successfully."
}
4. Initialisation of resources transfer between accounts - debtor
On production, Cuscal sends an instruction to the mandate manager for sending a payment (RAPAIN), which is later carried by it to the payment manager. For mocks, such instruction must be manually triggered by user, by using utility endpoint POST /v0/utils/generate-receive-a-payment-instruction
; Such request should have ACCP
transaction status.
Later in the process, Cuscal should automatically generate make a payment (MAP) and retract money from debtor account but for mocks, amount is extracted in the same step.
To check a debtor’s account, refer to Platform API documentation section on accounts.
Request
{
"creditorInformation": {
"accountIdentification": "63610027487941",
"partyName": "JOE BLOGGS"
},
"debtorInformation": {
"accountIdentification": "63610079412687",
"partyName": "JOHN MAXIMILLIAN DOE"
},
"mandateInformation": {
"initiatingPartyName": "string",
"mandateIdentification": "1212c23a255c11ee9a8e5d3239591cd9"
},
"paymentInformation": {
"instructedAmount": "2",
"instructionIdentification": " ANNCAU22XXXI20230718000000000077240”,
"remittanceInformationUnstructured": "This is a payment for invoice number 123456."
},
"transactionStatusInformation": {
"transactionStatus": "ACCP"
}
}
Response
{
"message": "Receive A Payment Instruction generated."
}
Notes:
MandateIdentification
field should include a mandate ID without hyphens
InstructedAmount
can be different from amount given in ad-hoc payment initialisation andinstructedAmount
will be used for resource extraction but on production it should be the same amount as initial payment amount, and so we advise to do the same.
5. Initialisation of resources transfer between accounts - creditor
In the live process, receiving a payment (RAP) is carried out by Cuscal asynchronously from MAP. To simulate a process of receiving a payment and assigning correct amount of resources to creditor’s account, RAP needs to be manually initiated. Use, POST /v0/utils/generate-inbound-npp-transaction-v2
to do so. A message about successful payment reception should be returned as well.
To check creditor’s account, refer to Platform API documentation section on accounts.
Request
{
"creditorInformation": {
"accountIdentification": "63610027487941",
"accountIdentificationTypeCode": "BBAN",
"ultimatePartyName": "JOE BLOGGS"
},
"debtorInformation": {
"accountIdentification": "63610079412687",
"accountIdentificationTypeCode": "BBAN",
"partyName": "JOHN MAXIMILLIAN DOE"
},
"initgPtyIdOrgId": "NPBOAU21XXX",
"mandateInformation": {
"initiatingPartyName": "string",
"instructionIdentification": "ANNCAU22XXXI20230718000000000077240”,
"mandateIdentification": "12125151256111ee9a8e4b632ff6f510"
},
"paymentId": "ANNCAU22XXX20230718000000000077240",
"paymentInformation": {
"categoryPurposeCode": "SALA",
"endToEndIdentification": "string",
"instructedAmount": "2",
"originalMessageIdentification": "ANNCAU22XXX20230718000000000077240",
"remittanceInformationUnstructured": "This is a payment for invoice number 123456.",
"transactionIdentification": "ANNCAU22XXXN20230718000000000077240"
}
}
Response
{
"message": "Receive A Payment generated."
}
Notes:
- For this request,
instructionIdentification
field should be the same as the ID generated when triggering ad-hoc payment PaymentID
andoriginalMessageIdentification
should have the same ID asinstructionIdentification
but after first part of the ID that indicates Business Identifier Code (BIC - ANNCAU22XXXI2) should be removedOriginalMessageIdentification
should contain additional letter N after BIC code
Fixed schedule end to end payment - steps
On the production environment, mandates of frequency different from ADHOC
which are in ACTIVE
status, have payments based on mandate payment terms scheduled in time. Currently, only the next upcoming payment is scheduled. When the time of the payment comes, scheduled payment is initiated, and another scheduled payment is created in place of the previously existing one that just triggered.
For mocks, it is possible to create a mandate with a frequency different to ad-hoc and simulate the process of payment scheduling, but actual transfer of money between accounts is carried out in the same way as ad-hoc payments.
1. Creating non ad-hoc payment
Simply call an endpoint to create a mandate. For mock solution there is no real status transition, so a mandate with ACTIVE
status should be created for the process. To see how to create mandate with specific status, see the ‘Mandate statuses’ section.
2. Triggering creation of a scheduled payment initiation request
On the production environment, when mandate creation proposal is accepted by the other party, the mandate status is switched to ACTIVE
and a new scheduled payment is created. Mock solutions don’t schedule a payment automatically. To create a scheduled payment initiation request for a mandate on mocks, a notification with MCRC
trigger should be sent. This way we’re simulating default flow where the mandate that was proposed has been accepted and payment is scheduled right after that fact
3. Transfer of funds between accounts
From this point, money transfer looks in the same way as ad-hoc payments. Check step 4 of ad-hoc payments.
Unhappy path scenarios
1. Technical timeout when mandate creation is not accepted by Payer
When mandate creation is proposed by Initiator, then action is required by the Payer to accept such a mandate. When no action is taken by Payer, then after 6 days mandate should be automatically rejected and set into CANCELED
status by MMS (Mandate Management System). Initiator then receives a notification that the action has expired. To simulate this behaviour, simply create a mandate in CREATED
status, then manually trigger a notification to Initiator by using POST/v0/utils/generate-mandate-notification-initiator
endpoint with MCRX
trigger.
Step 1: Create mandate with CREATED status
Request
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "status:created",
"idempotencyKey": "cabff7ef-2ee5-433b-80bc-bc72cd2125b5",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "MORTGAGE",
"validityEndDate": "2025-07-02",
"validityStartDate": "2023-07-19"
}
Response
{
"mandateId": "1212c423-262b-11ee-844d-95ee6a0c000c"
}
Step 2: Get mandate – checking that it has been created properly (optional)
Request
GET/v1/payto/mandates/{mandateId}
Response
{ "mandateId": "1212c423-262b-11ee-844d-95ee6a0c000c",
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4",
"partyReference": "Creditor party reference",
"partyType": "PERSON",
"ultimatePartyName": "JOE BLOGGS"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51",
"accountNumber": "8020016999999",
"partyName": "JOHN MAXIMILLIAN DOE",
"partyReference": "Debtor party reference",
"partyType": "PERSON",
"ultimatePartyName": "JOHN DOE"
},
"description": "Pending-Amend/Port-PMTI/Port-DEBT, Debtor-BBAN, Creditor-BBAN, Payment-Monthly/BALN/Amount/first/last",
"purposeCode": "RETAIL",
"registrationDateTime": "2021-02-25T09:25:52.556Z",
"status": "CREATED",
"paymentTerms": {
"amount": {
"amount": 500.00,
"currency": "AUD"
},
"maximumAmount": {
"amount": 900.00,
"currency": "AUD"
},
"firstPayment": {
"amount": {
"amount": 500.00,
"currency": "AUD"
},
"date": "2020-10-07"
},
"lastPayment": {
"amount": {
"amount": 900.00,
"currency": "AUD"
},
"date": "2024-10-06"
},
"type": "FIXED",
"frequency": "ADHOC",
"pointInTime": "09",
"countPerPeriod": "10"
},
"transferArrangement": "Transfer arrangement test",
"validityStartDate": "2020-10-06",
"validityEndDate": "2025-05-25"
}
Step 3: Sending MCRX Notification
Request
POST/v0/utils/generate-mandate-notification-initiator
{
"trigger": "MCRX",
"actionDetails": {
"actionId": "34927ba11a6811ee84e91d8ebf04eef2"
},
"mandateDetails": {
"mandateId": "1212c423262b11ee844d95ee6a0c000c",
"creditorInformation": {
"accountIdentification": "63663630855474"
},
"debtorInformation": {
"accountIdentification": "63663672104323"
},
"paymentInformation": {
"amount": "1.00",
"countPerPeriod": "1",
"firstPaymentAmount": "2.00",
"firstPaymentDate": "2023-06-15",
"lastPaymentAmount": "3.00",
"lastPaymentDate": "2024-06-15",
"maximumAmount": "4.00",
"paymentAmountType": "VARI",
"paymentFrequency": "DAIL",
"pointInTime": "10"
},
"validityStartDate": "2023-06-15",
"validityEndDate": "2024-06-15"
}
}
Response
{
"message": "Mandate Notification for Initiator generated."
}
2. Mandate creation is rejected
When creating a mandate, there is a possibility that it will be rejected. The mandate can be rejected on Payer’s side or by the system if there is a discrepancy detected. Mocks allow us to simulate what kind of response can be expected on both types of rejection.
a) Mandate creation rejected by Payer
Step 1: Create mandate with CREATED status
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "status:created",
"idempotencyKey": "9ecb3732-6a3e-457f-aadc-0c8cc07e66ca",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "LOAN",
"validityEndDate": "2023-07-23",
"validityStartDate": "2023-07-21"
}
Response
{
"mandateId": "12128135-27cb-11ee-80be-e35c1e0c000c"
}
Step 2: Debtor is rejecting the mandate
Use PATCH/v1/payto/payer/mandates/{mandateId}/resolve
endpoint to simulate a reject action taken by Payer. Make sure to add information in the URL about action resolution, as per the provided request template:
Request
PATCH /v1/payto/payer/mandates/12125940-2ab0-11ee-b219-1515620c000c/resolve?resolution={resolution_value}
Response
{
"message": "Mandate resolved successfully."
}
Step 3: Initiator is receiving a notification about mandate being rejected by the debtor
In the last step, generate a notification with PCRD
trigger which simulates a received response about a mandate being rejected by Payer, by using POST/v0/utils/generate-mandate-notification-initiator
endpoint
Request
POST/v0/utils/generate-mandate-notification-initiator
{
"trigger": "PCRD",
"actionDetails": {
"actionId": "34927ba11a6811ee84e91d8ebf04eef2"
},
"mandateDetails": {
"mandateId": "1212813527cb11ee80bee35c1e0c000c",
"creditorInformation": {
"accountIdentification": "63663630855474"
},
"debtorInformation": {
"accountIdentification": "63663672104323"
},
"paymentInformation": {
"amount": "1.00",
"countPerPeriod": "1",
"firstPaymentAmount": "2.00",
"firstPaymentDate": "2023-06-15",
"lastPaymentAmount": "3.00",
"lastPaymentDate": "2024-06-15",
"maximumAmount": "4.00",
"paymentAmountType": "VARI",
"paymentFrequency": "DAIL",
"pointInTime": "10"
},
"validityStartDate": "2023-06-15",
"validityEndDate": "2024-06-15"
}
}
Response
{
"message": "Mandate Notification for Initiator generated."
}
b) Mandate creation rejected by the system
Mandates can be rejected for various reasons, so only one response has been mocked to show where a reason for rejection can be found. To generate a rejection response by the system, create a mandate while providing mandate_rejected
value in the description field.
Mandate Creation Failure
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "mandate_rejected",
"idempotencyKey": "4db4d85d-dbff-4a52-9fd7-9e38d5a9949c",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "GOVERNMENT",
"validityEndDate": "2023-07-23",
"validityStartDate": "2023-07-21"
}
Response
{
"message": "NOT_FOUND: CUS.API.100522 - Creditor account details incorrect (M900 - No matching record found)",
"details": "Please refer to the API documentation or contact Shaype for more info with the traceId.",
"status": "422",
"traceId": "9b8fa212-d655-487e-bf91-4406957bb584"
}
3. Payment initiation request (PIR) is initiated but is not proceeding further because time limit of 15 seconds for realisation has passed
When a payment is initiated then it is possible to call an endpoint which will check the status of a payment instruction. Depending on phase in which payment instruction is, different statuses could be returned for the production environment. But for mocks, payment is not processed. Therefore to simulate a response from different points in time, mocks return initial status of a payment instruction that should be expected in the response of a created mandate, upon which payment status is based. Then calling for a payment status, it should return a status that is expected to exist at the ending stage of a scenario.
Step 1: Create a mandate with description for time-out scenario
To create a mandate for which a payment instruction will return the required statuses, paymentstatus:safd&undv
should be provided in the description field of a request using the endpoint
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "paymentstatus:timeout_rjct",
"idempotencyKey": "5205b30b-b93a-4a6b-8d87-c5f9ee51df3b",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "GAMBLING",
"validityEndDate": "2025-04-15",
"validityStartDate": "2023-07-31"
}
Response
{
"mandateId": "1212ab33-2fa9-11ee-a1a4-8f2d060a000b"
}
Step 2 - Make adhoc payment based on a description-controlled mandate
Request
POST/v1/payto/payments/adhoc
{
"amount": {
"amount": 10.00,
"currency": "AUD"
},
"idempotencyKey": "7627d076-6ca9-4e90-99eb-1ed05dc7ed51",
"description": "test",
"mandateId": "1212ab33-2fa9-11ee-a1a4-8f2d060a000b"
}
There will be entry present in the logs:
url: http://external-services-mock/npp/mandates/payments/initiator/v2/ANNCAU22XXX/mandates/1212ab332fa911eea1a48f2d060a000b/instructions/ANNCAU22XXXI20230731000000000078880
status: 200
decoded content:
class InlineResponse200 {
transactionStatus: RJCT
transactionStatusReasonCode: AB01
}
Response to the request will be received after a 15 second timeout:
{
"mandateId": "1212ab33-2fa9-11ee-a1a4-8f2d060a000b",
"instructionId": "ANNCAU22XXXI20230731000000000078880",
"transactionStatus": "REJECTED",
"transactionStatusDisplay": "Rejected",
"statusIsFinal": true,
"message": "Adhoc payment executed successfully."
}
4. Payment request has been sent but is not delivered
Step 1 - Create a mandate with description paymentstatus:sent&undv
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "paymentstatus:sent&undv",
"idempotencyKey": "b31de3dc-dd22-47d3-8996-455cabf79bdf",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "RETAIL",
"validityEndDate": "2025-06-21",
"validityStartDate": "2023-08-01"
}
Response
{
"mandateId": "12120aef-3061-11ee-bd98-43435c0a000d"
}
Step 2 - Make adhoc payment
Request
POST/v1/payto/payments/adhoc
{
"amount": {
"amount": 10.00,
"currency": "AUD"
},
"idempotencyKey": "79f8a40d-c469-4a4e-b7d8-3e74278c3418",
"description": "test",
"mandateId": "12120aef-3061-11ee-bd98-43435c0a000d"
}'
Response:
{
"mandateId": "12120aef-3061-11ee-bd98-43435c0a000d",
"instructionId": "ANNCAU22XXXI20230801000000000079280",
"transactionStatus": "SENT",
"transactionStatusDisplay": "Sent",
"statusIsFinal": false,
"message": "Adhoc payment executed successfully."
}
Step 3 - get mandate payment status
Request
GET /v1/payto/initiator/mandates/112120aef-3061-11ee-bd98-43435c0a000d/instructions/ ANNCAU22XXXI20230801000000000079280/status
Response
{
"transactionStatus": "UNDELIVERED"
}
5. Payment request is stored due to participant being unavailable and fails
In the same way as the previous case, to simulate this scenario, a mandate with description paymentstatus:safd&undv
must be created. SAFD
status of a payment informs that payment participant is unavailable and payment has been saved by the system to be processed at a later date. In this scenario, UNDV
is returned as a final result after technical retries.
Step 1 - Create a mandate with specified description
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "paymentstatus:safd&undv",
"idempotencyKey": "46e9fdd6-af31-4206-98e0-afbb4693f94c",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "LOAN",
"validityEndDate": "2024-10-04",
"validityStartDate": "2023-08-01"
}
Response
{
"mandateId": "1212de1e-3061-11ee-bd98-49ab2e0a000c"
}
Step 2 - Make adhoc payment
Request
POST/v1/payto/payments/adhoc
{
"amount": {
"amount": 10.00,
"currency": "AUD"
},
"idempotencyKey": "43cf8d84-d9dd-44e6-bd56-5a6cf557b68e",
"description": "test",
"mandateId": "1212de1e-3061-11ee-bd98-49ab2e0a000c"
}
Response
{
"mandateId": "1212de1e-3061-11ee-bd98-49ab2e0a000c",
"instructionId": "ANNCAU22XXXI20230801000000000079270",
"transactionStatus": "STORE_AND_FORWARD",
"transactionStatusDisplay": "Store & Forward",
"statusIsFinal": false,
"message": "Adhoc payment executed successfully."
}
Step 3 - get mandate payment status
Request
GET /v1/payto/initiator/mandates/1212de1e-3061-11ee-bd98-49ab2e0a000c/instructions/ ANNCAU22XXXI20230801000000000079270/status
Response
{
"transactionStatus": "UNDELIVERED"
}
6. Payment instruction has been accepted and is in pending status, but is finally rejected
Step 1: Create a mandate with description paymentstatus:recv&rjct
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "596fb54d-2b88-4245-a793-08a5f7a6d6d4"
},
"debtorDetails": {
"accountId": "fd33a68c-4fc2-4cfa-a16a-e65d9709ac51"
},
"description": "paymentstatus:recv&rjct",
"idempotencyKey": "4cff79d5-c026-4cb1-835f-13c34795f1ea",
"paymentTerms": {
"amount": {
"amount": 2.10,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "7"
},
"purposeCode": "MORTGAGE",
"validityEndDate": "2025-05-21",
"validityStartDate": "2023-08-01"
}
Response
{
"mandateId": "12120260-3061-11ee-bd98-977d250a000e"
}
Step 2 - Make adhoc payment
Request
POST/v1/payto/payments/adhoc
{
"amount": {
"amount": 10.00,
"currency": "AUD"
},
"idempotencyKey": "095e17b0-8adb-4c10-be96-468fed71de9a",
"description": "test",
"mandateId": "12120260-3061-11ee-bd98-977d250a000e"
}
Response:
{
"mandateId": "12120260-3061-11ee-bd98-977d250a000e",
"instructionId": "ANNCAU22XXXI20230801000000000079290",
"transactionStatus": "RECEIVED",
"transactionStatusDisplay": "Received",
"statusIsFinal": false,
"message": "Adhoc payment executed successfully."
}
Step 3 - get mandate payment status
Request
GET /v1/payto/initiator/mandates/112120260-3061-11ee-bd98-977d250a000e/instructions/ ANNCAU22XXXI20230801000000000079290/status
Response
{
"transactionStatus": "REJECTED"
}
Testing end-to-end identification of a payment
Platform has means to provide an 'end-to-end' identification of a payment. This identification depends on type of a payment, which is determined by frequency of a mandate. On production, for ad-hoc payments when payment request endpoint is called, it allows to provide a string which limited from 1 to 35 characters. For payments which are scheduled based on mandate frequency (non ad-hoc) then this identification is automatically filled for scheduled payments by information stored within partyReference provided when mandate is created.
This identification information is optional. When it is not provided, then system will assume value 'Not provided' in both cases of frequencies for mandates.
Mocks allow to test this for ad-hoc mandates. To do so, you need to do following steps:
Ad-hoc mandates
Step 1 - create an ad-hoc mandate
Request
POST/v1/payto/initiator/mandates
{
"creditorDetails": {
"accountId": "0ee7980e-6df9-4d3c-b01b-2fe9d369de07"
},
"debtorDetails": {
"accountId": "d11ad058-e12b-4e02-81fd-ba306663b601"
},
"description": "salmon Table",
"idempotencyKey": "2c4bfa27-7dd6-407d-9d2d-13fec379c94a",
"paymentTerms": {
"maximumAmount": {
"amount": 5,
"currency": "AUD"
},
"frequency": "ADHOC",
"type": "USAGE_BASED",
"countPerPeriod": "2"
},
"purposeCode": "UTILITY",
"validityEndDate": "2025-05-27",
"validityStartDate": "2023-11-29"
}
Response
{
"mandateId": "12120428-8eb3-11ee-8d7c-c9dd305f4280"
}
Step 2 - make ad-hoc payment
Request
POST/v1/payto/payments/adhoc
{
"amount": {
"amount": 1.28,
"currency": "AUD"
},
"idempotencyKey": "4688ec46-e862-4a87-98f9-a323a81322e7",
"description": "salmon Table",
"endToEndId": "NET-1724",
"mandateId": "12120428-8eb3-11ee-8d7c-c9dd305f4280"
}
Response
{
"mandateId": "12120428-8eb3-11ee-8d7c-c9dd305f4280",
"instructionId": "ANNCAU22XXXI20231129000000000093410",
"transactionStatus": "SENT",
"transactionStatusDisplay": "Sent",
"statusIsFinal": false,
"message": "Adhoc payment executed successfully."
}
Step 3 - Create stub for search payment instructions for a mandate
Request
POST/v0/utils/create-stub-search-payment-instructions
{
"mandateIdentification": "121204288eb311ee8d7cc9dd305f4280",
"paymentInstructionSummaries": [
{
"creationDateTime": "2023-11-29T12:33:59.833Z",
"instructedAmount": 1.28,
"instructionIdentification": "ANNCAU22XXXI20231129000000000093410",
"transactionStatus": "RECV",
"transactionStatusReasonCode": "AB01"
}
]
}
Response
{
"message": "Stub mapping for search payment instruction request created."
}
Step 4 - Search payment instructions by Mandate ID
Request
GET/v1/payto/initiator/mandates/{mandateId}/search
Response
{
"paymentInstructions": [
{
"id": "ANNCAU22XXXI20231129000000000093410",
"amount": 1.28,
"creationDateTime": "2023-11-29T12:33:59.833Z",
"transactionStatus": "RECEIVED",
"transactionStatusReasonCode": "AB01",
"endToEndId": "NET-1724"
}
]
}