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

  1. 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
  2. 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 as ACTIVE 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 and instructedAmount 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 and originalMessageIdentification should have the same ID as instructionIdentification but after first part of the ID that indicates Business Identifier Code (BIC - ANNCAU22XXXI2) should be removed
  • OriginalMessageIdentification 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"
		}
	]
}