# Run active mode sender tests This tutorial demonstrates how payment senders can use Test Harness as a mock receiver to validate payments against a real partner RPO. In the following tests cases, we use the RippleNet Server UI to send and settle payments. ## Prepare Test Harness To run the tests in this tutorial: 1. Save the provided [sample data](#sample-data) and upload to Test Harness. 2. On the **Passive Mode** tab, disable **AUTO LOCK ACCEPTED QUOTES** and **AUTO COMPLETE PAYMENTS**. Define your Test case ID To run tests in active mode, the **Test case ID** must be defined within the payment's `user_info` and it must be prepended by `TCID-`. For example, if a Test Profile defines `"test_case_id": "1.01"` then `user_info` in the payment must include `{"TxId":"TCID-1.01"}`. ### Sample data The sample data in this tutorial includes an RPO Schema to represent your receiving partner, four test profiles and one combined file that define a total of 14 test cases (1.01 through 1.14): * Sample Sender Test Profile (All Combined): 1.01 - 1.14 * Sample Sender Test Profile (COMPLETED): 1.01 - 1.03 * Sample Sender Test Profile (FAILED): 1.04 - 1.06 * Sample Sender Test Profile (RETURNED): 1.07 - 1.10 * Sample Sender Test Profile (Sub-states): 1.11 - 1.14 #### Test Harness data To save and upload the sample data into Test Harness: 1. Copy, paste, and save "Sample RPO Schema" locally as `sample_rpo_schema.json` 2. Copy, paste, and save the test profiles that test different payment states: * Save "Sample Sender Test Profile (Sub-states)" locally as `sample_test_profile_sendtest_all.json` * Save "Sample Sender Test Profile (COMPLETED)" locally as `sample_test_profile_sendtest_completed.json` * Save "Sample Sender Test Profile (FAILED)" locally as `sample_test_profile_sendtest_failed.json` * Save "Sample Sender Test Profile (RETURNED)" locally as `sample_test_profile_sendtest_returned.json` * Save "Sample Sender Test Profile (Sub-states)" locally as `sample_test_profile_sendtest_substates.json` 3. Log on to a Test Harness instance that receives payments and runs "sender tests". 4. Click **Test Content**. 5. On the **RPO Schemas** tab, upload the sample RPO schema. 6. On the **Test Profiles** tab, upload all sample profiles.  **RPO** details summary Click to expand ```json { "$schema": "http://json-schema.org/draft-07/schema", "type": "object", "title": "Sample RPO Schema", "description": "Sample RPO Schema used for 'aligned' testing (TH<>TH with corresponding test case IDs).", "default": {}, "additionalProperties": true, "required": [ "Cdtr", "CdtrAcct", "CdtrAgt", "Dbtr", "PmtTpInf", "ChrgBr" ], "properties": { "Cdtr": { "$id": "#/properties/Cdtr", "type": "object", "title": "The Cdtr Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "StrdNm": { "FirstNm": "Michael", "LastNm": "Scott" } } ], "additionalProperties": true, "required": [ "StrdNm" ], "properties": { "StrdNm": { "$id": "#/properties/Cdtr/properties/StrdNm", "type": "object", "title": "The Strdnm Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "FirstNm": "Michael", "LastNm": "Scott" } ], "additionalProperties": true, "required": [ "FirstNm", "LastNm" ], "properties": { "FirstNm": { "$id": "#/properties/Cdtr/properties/StrdNm/properties/FirstNm", "type": "string", "title": "The Firstnm Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Michael" ] }, "LastNm": { "$id": "#/properties/Cdtr/properties/StrdNm/properties/LastNm", "type": "string", "title": "The Lastnm Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Scott" ] } } } } }, "CdtrAcct": { "$id": "#/properties/CdtrAcct", "type": "object", "title": "The Cdtracct Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "Id": { "Othr": { "Id": "12345678" } } } ], "additionalProperties": true, "required": [ "Id" ], "properties": { "Id": { "$id": "#/properties/CdtrAcct/properties/Id", "type": "object", "title": "The Id Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "Othr": { "Id": "12345678" } } ], "additionalProperties": true, "required": [ "Othr" ], "properties": { "Othr": { "$id": "#/properties/CdtrAcct/properties/Id/properties/Othr", "type": "object", "title": "The Othr Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "Id": "12345678" } ], "additionalProperties": true, "required": [ "Id" ], "properties": { "Id": { "$id": "#/properties/CdtrAcct/properties/Id/properties/Othr/properties/Id", "type": "string", "title": "The Id Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "12345678" ] } } } } } } }, "CdtrAgt": { "$id": "#/properties/CdtrAgt", "type": "object", "title": "The Cdtragt Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "FinInstnId": { "ClrSysMmbId": { "MmbId": "ABC123" } } } ], "additionalProperties": true, "required": [ "FinInstnId" ], "properties": { "FinInstnId": { "$id": "#/properties/CdtrAgt/properties/FinInstnId", "type": "object", "title": "The Fininstnid Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "ClrSysMmbId": { "MmbId": "ABC123" } } ], "additionalProperties": true, "required": [ "ClrSysMmbId" ], "properties": { "ClrSysMmbId": { "$id": "#/properties/CdtrAgt/properties/FinInstnId/properties/ClrSysMmbId", "type": "object", "title": "The Clrsysmmbid Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "MmbId": "ABC123" } ], "additionalProperties": true, "required": [ "MmbId" ], "properties": { "MmbId": { "$id": "#/properties/CdtrAgt/properties/FinInstnId/properties/ClrSysMmbId/properties/MmbId", "type": "string", "title": "The Mmbid Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "ABC123" ] } } } } } } }, "Dbtr": { "$id": "#/properties/Dbtr", "type": "object", "title": "The Dbtr Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "StrdNm": { "FirstNm": "Bob", "LastNm": "Vance" }, "PstlAdr": { "AdrLine": [ "Dunder Mifflin Paper", "1725 Slough Avenue Ste 200" ], "TwnNm": "Scranton", "CtrySubDvsn": "PA", "Ctry": "USA", "PstCd": "18503" } } ], "additionalProperties": true, "required": [ "PstlAdr", "StrdNm" ], "properties": { "PstlAdr": { "$id": "#/properties/Dbtr/properties/PstlAdr", "type": "object", "title": "The Pstladr Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "Ctry": "USA", "PstCd": "18503", "AdrLine": [ "Dunder Mifflin Paper", "1725 Slough Avenue Ste 200" ], "TwnNm": "Scranton", "CtrySubDvsn": "PA" } ], "additionalProperties": true, "required": [ "AdrLine", "Ctry", "CtrySubDvsn", "PstCd", "TwnNm" ], "properties": { "AdrLine": { "$id": "#/properties/Dbtr/properties/PstlAdr/properties/AdrLine", "type": "array", "title": "The Adrline Schema", "description": "An explanation about the purpose of this instance.", "default": [], "examples": [ [ "Dunder Mifflin Paper", "1725 Slough Avenue Ste 200" ] ], "additionalItems": true, "items": { "$id": "#/properties/Dbtr/properties/PstlAdr/properties/AdrLine/items", "type": "string", "title": "The Items Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Dunder Mifflin Paper", "1725 Slough Avenue Ste 200" ] } }, "Ctry": { "$id": "#/properties/Dbtr/properties/PstlAdr/properties/Ctry", "type": "string", "title": "The Ctry Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "USA" ] }, "CtrySubDvsn": { "$id": "#/properties/Dbtr/properties/PstlAdr/properties/CtrySubDvsn", "type": "string", "title": "The Ctrysubdvsn Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "PA" ] }, "PstCd": { "$id": "#/properties/Dbtr/properties/PstlAdr/properties/PstCd", "type": "string", "title": "The Pstcd Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "18503" ] }, "TwnNm": { "$id": "#/properties/Dbtr/properties/PstlAdr/properties/TwnNm", "type": "string", "title": "The Twnnm Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Scranton" ] } } }, "StrdNm": { "$id": "#/properties/Dbtr/properties/StrdNm", "type": "object", "title": "The Strdnm Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "FirstNm": "Bob", "LastNm": "Vance" } ], "additionalProperties": true, "required": [ "FirstNm", "LastNm" ], "properties": { "FirstNm": { "$id": "#/properties/Dbtr/properties/StrdNm/properties/FirstNm", "type": "string", "title": "The Firstnm Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Bob" ] }, "LastNm": { "$id": "#/properties/Dbtr/properties/StrdNm/properties/LastNm", "type": "string", "title": "The Lastnm Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Vance" ] } } } } }, "PmtTpInf": { "$id": "#/properties/PmtTpInf", "type": "object", "title": "The Pmttpinf Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "CtgyPurp": { "Prtry": "A1" } } ], "additionalProperties": true, "required": [ "CtgyPurp" ], "properties": { "CtgyPurp": { "$id": "#/properties/PmtTpInf/properties/CtgyPurp", "type": "object", "title": "The Ctgypurp Schema", "description": "An explanation about the purpose of this instance.", "default": {}, "examples": [ { "Prtry": "A1" } ], "additionalProperties": true, "required": [ "Prtry" ], "properties": { "Prtry": { "$id": "#/properties/PmtTpInf/properties/CtgyPurp/properties/Prtry", "type": "string", "title": "The Prtry Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "A1" ] } } } } }, "ChrgBr": { "$id": "#/properties/ChrgBr", "type": "string", "title": "The Chrgbr Schema", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "DEBT" ] } } } ``` br **All** details summary Click to expand ```json { "profile_name": "Sample Sender Test Profile (14 Tests)", "version": "1.7", "customer_name": "Sample SCP", "profile_type": "SENDING", "cases": [ { "test_case_id": "1.01", "test_case_description": "This test passes if the payment is COMPLETED within 35 minutes. Test Harness completes the payment regardless of the user_info.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE" } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" } ] }, { "test_case_id": "1.02", "test_case_description": "This test passes if the payment is COMPLETED within 35 minutes. Test Harness validates the ACCEPTED payment against the RPO schema, locks or rejects with the appropriate ISO code, then completes the EXECUTED payment.", "execution_steps": [ { "state": "ACCEPTED", "action": "VALIDATE" }, { "state": "EXECUTED", "action": "COMPLETE" } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" } ] }, { "test_case_id": "1.03", "test_case_description": "This test passes if the payment is COMPLETED within 35 minutes. Test Harness rejects the ACCEPTED payment twice with ISO codes RC04 and FF06 respectively, then locks the third time.", "execution_steps": [ { "state": "ACCEPTED", "action": "REJECT_LOCK", "action_data": "2;RC04,FF06" }, { "state": "EXECUTED", "action": "COMPLETE" } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RECEIVER_LOCK_DECLINED_CODES", "value": "RC04,FF06" } ] }, { "test_case_id": "1.04", "test_case_description": "This test passes if the payment is FAILED within 35 minutes. Test Harness fails the ACCEPTED payment with ISO code AC08.", "execution_steps": [ { "state": "ACCEPTED", "action": "FAIL", "action_data": "AC08" } ], "expected_results": [ { "criterion": "STATE", "value": "FAILED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RECEIVER_FAILURE_CODES", "value": "AC08" } ] }, { "test_case_id": "1.05", "test_case_description": "This test passes if the payment is FAILED within 35 minutes. Test Harness locks the ACCEPTED payment. The sender must actively fail the LOCKED payment with ISO code CUST.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" } ], "expected_results": [ { "criterion": "STATE", "value": "FAILED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "SENDER_FAILURE_CODES", "value": "CUST" } ] }, { "test_case_id": "1.06", "test_case_description": "This test passes if the payment is FAILED within 35 minutes. Test Harness locks the ACCEPTED payment, then fails the EXECUTED payment with ISO code AC04.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "FAIL", "action_data": "AC04" } ], "expected_results": [ { "criterion": "STATE", "value": "FAILED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RECEIVER_FAILURE_CODES", "value": "AC04" } ] }, { "test_case_id": "1.07", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks/completes the payment, then returns the COMPLETED payment with ISO code MD06. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE" }, { "state": "COMPLETED", "action": "RETURN", "action_data": "MD06" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RETURN_REASON_CODES", "value": "MD06" } ] }, { "test_case_id": "1.08", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks the payment, then returns the EXECUTED payment with ISO code AC03. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "RETURN", "action_data": "AC03" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RETURN_REASON_CODES", "value": "AC03" } ] }, { "test_case_id": "1.09", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks/fails the payment with ISO code RR06, then returns the FAILED payment with ISO code RR06. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "FAIL_RETURN", "action_data": "RR06;RR06" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RECEIVER_FAILURE_CODES", "value": "RR06" }, { "criterion": "RETURN_REASON_CODES", "value": "RR06" } ] }, { "test_case_id": "1.10", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks/completes the payment, then returns the COMPLETED payment with no reason code. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE" }, { "state": "COMPLETED", "action": "RETURN" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" } ] }, { "test_case_id": "1.11", "test_case_description": "This test passes if the payment is COMPLETED. Test Harness locks the ACCEPTED payment, then adds the FORWARDED sub-state to the EXECUTED payment before completing.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE", "props": { "preceding_sub_states": [ { "sub_state": "FORWARDED", "memo": "Forwarded to ACH", "info": { "id": "12345678" } } ] } } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "RECEIVER_SUB_STATES", "value": "FORWARDED" } ] }, { "test_case_id": "1.12", "test_case_description": "This test passes if the payment is RETURNED. Test Harness locks the ACCEPTED payment and waits for the sender to settle. Sender applies sub-state REQUEST_RETURN, triggering Test Harness to return payment with ISO code MD06.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "RETURN", "action_data": "MD06", "props": { "sub_state_trigger": { "triggering_sub_state": "REQUEST_RETURN", "trigger_timeout_seconds": 60 } } }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "SENDER_SUB_STATES", "value": "REQUEST_RETURN" }, { "criterion": "RETURN_REASON_CODES", "value": "MD06" } ] }, { "test_case_id": "1.13", "test_case_description": "This test passes if the payment is COMPLETED. Test Harness adds AWAITING_COLLECTION sub-state to EXECUTED payment, requests amendment 2x with REQUEST_INFO sub-state (and sender amends with AMENDED sub-state), then completes payment.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "REQUEST_AMENDMENT", "props": { "preceding_sub_states": [ { "sub_state": "AWAITING_COLLECTION", "memo": "Payment is available for cash pick-up.", "info": { "id": "12345" }, "delay_seconds": 30 } ], "info_request_sub_states": [ { "sub_state": "REQUEST_INFO", "memo": "BE01", "info": { "user_info.Cdtr.StrdNm.FirstNm": "Michael" } }, { "sub_state": "REQUEST_INFO", "memo": "CH11", "info": { "user_info.Cdtr.CtctDtls.MobNb": "08917453", "user_info.Cdtr.CtryOfRes": "PHL", "user_info.Cdtr.Id.PrvtId.Othr.SchmeNm.Cd": "CCPT", "user_info.Cdtr.StrdNm.FirstNm": "Michael", "user_info.Cdtr.StrdNm.LastNm": "Mouse" } } ], "amendment_trigger": { "triggering_sub_state": "AMENDED", "trigger_timeout_seconds": 120 }, "secondary_step": { "action": "COMPLETE" } } } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "SENDER_SUB_STATES", "value": "AMENDED" }, { "criterion": "RECEIVER_SUB_STATES", "value": "REQUEST_INFO,AWAITING_COLLECTION" } ] }, { "test_case_id": "1.14", "test_case_description": "This test passes if the payment is COMPLETED. Test Harness adds AWAITING_COLLECTION sub-state to EXECUTED payment, requests amendment 2x with REQUEST_INFO sub-state (and sender amends with AMENDED sub-state), then returns payment.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "REQUEST_AMENDMENT", "props": { "preceding_sub_states": [ { "sub_state": "AWAITING_COLLECTION", "memo": "Payment is available for cash pick-up.", "info": { "id": "12345" }, "delay_seconds": 30 } ], "info_request_sub_states": [ { "sub_state": "REQUEST_INFO", "memo": "BE01", "info": { "user_info.Cdtr.StrdNm.FirstNm": "Michael" } }, { "sub_state": "REQUEST_INFO", "memo": "CH11", "info": { "user_info.Cdtr.CtctDtls.MobNb": "08917453", "user_info.Cdtr.CtryOfRes": "PHL", "user_info.Cdtr.Id.PrvtId.Othr.SchmeNm.Cd": "CCPT", "user_info.Cdtr.StrdNm.FirstNm": "Michael", "user_info.Cdtr.StrdNm.LastNm": "Mouse" } } ], "amendment_trigger": { "triggering_sub_state": "AMENDED", "trigger_timeout_seconds": 120 }, "secondary_step": { "state": "EXECUTED", "action": "RETURN", "action_data": "BE01,BE05" } } }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RETURN_REASON_CODES", "value": "BE01,BE05" }, { "criterion": "SENDER_SUB_STATES", "value": "AMENDED" }, { "criterion": "RECEIVER_SUB_STATES", "value": "REQUEST_INFO,AWAITING_COLLECTION" } ] } ] } ``` br **COMPLETE** details summary Click to expand ```json { "profile_name": "Sample Sender Test Profile (COMPLETED)", "version": "1.7", "customer_name": "Sample SCP", "profile_type": "SENDING", "cases": [ { "test_case_id": "1.01", "test_case_description": "This test passes if the payment is COMPLETED within 35 minutes. Test Harness completes the payment regardless of the user_info.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE" } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" } ] }, { "test_case_id": "1.02", "test_case_description": "This test passes if the payment is COMPLETED within 35 minutes. Test Harness validates the ACCEPTED payment against the RPO schema, locks or rejects with the appropriate ISO code, then completes the EXECUTED payment.", "execution_steps": [ { "state": "ACCEPTED", "action": "VALIDATE" }, { "state": "EXECUTED", "action": "COMPLETE" } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" } ] }, { "test_case_id": "1.03", "test_case_description": "This test passes if the payment is COMPLETED within 35 minutes. Test Harness rejects the ACCEPTED payment twice with ISO codes RC04 and FF06 respectively, then locks the third time.", "execution_steps": [ { "state": "ACCEPTED", "action": "REJECT_LOCK", "action_data": "2;RC04,FF06" }, { "state": "EXECUTED", "action": "COMPLETE" } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RECEIVER_LOCK_DECLINED_CODES", "value": "RC04,FF06" } ] } ] } ``` br **FAIL** details summary Click to expand ```json { "profile_name": "Sample Sender Test Profile (FAILED)", "version": "1.7", "customer_name": "Sample SCP", "profile_type": "SENDING", "cases": [ { "test_case_id": "1.04", "test_case_description": "This test passes if the payment is FAILED within 35 minutes. Test Harness fails the ACCEPTED payment with ISO code AC08.", "execution_steps": [ { "state": "ACCEPTED", "action": "FAIL", "action_data": "AC08" } ], "expected_results": [ { "criterion": "STATE", "value": "FAILED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RECEIVER_FAILURE_CODES", "value": "AC08" } ] }, { "test_case_id": "1.05", "test_case_description": "This test passes if the payment is FAILED within 35 minutes. Test Harness locks the ACCEPTED payment. The sender must actively fail the LOCKED payment with ISO code CUST.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" } ], "expected_results": [ { "criterion": "STATE", "value": "FAILED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "SENDER_FAILURE_CODES", "value": "CUST" } ] }, { "test_case_id": "1.06", "test_case_description": "This test passes if the payment is FAILED within 35 minutes. Test Harness locks the ACCEPTED payment, then fails the EXECUTED payment with ISO code AC04.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "FAIL", "action_data": "AC04" } ], "expected_results": [ { "criterion": "STATE", "value": "FAILED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RECEIVER_FAILURE_CODES", "value": "AC04" } ] } ] } ``` br **RETURN** details summary Click to expand ```json { "profile_name": "Sample Sender Test Profile (RETURNED)", "version": "1.7", "customer_name": "Sample SCP", "profile_type": "SENDING", "cases": [ { "test_case_id": "1.07", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks/completes the payment, then returns the COMPLETED payment with ISO code MD06. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE" }, { "state": "COMPLETED", "action": "RETURN", "action_data": "MD06" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RETURN_REASON_CODES", "value": "MD06" } ] }, { "test_case_id": "1.08", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks the payment, then returns the EXECUTED payment with ISO code AC03. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "RETURN", "action_data": "AC03" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RETURN_REASON_CODES", "value": "AC03" } ] }, { "test_case_id": "1.09", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks/fails the payment with ISO code RR06, then returns the FAILED payment with ISO code RR06. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "FAIL_RETURN", "action_data": "RR06;RR06" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RECEIVER_FAILURE_CODES", "value": "RR06" }, { "criterion": "RETURN_REASON_CODES", "value": "RR06" } ] }, { "test_case_id": "1.10", "test_case_description": "This test passes if the payment is RETURNED within 35 minutes. Test Harness locks/completes the payment, then returns the COMPLETED payment with no reason code. The sender must complete the return payment and the original payment is RETURNED.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE" }, { "state": "COMPLETED", "action": "RETURN" }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "MAX_DURATION_MINS", "value": "35" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" } ] } ] } ``` br **SUB** details summary Click to expand ```json { "profile_name": "Sample Sender Test Profile (Sub-states)", "version": "1.7", "customer_name": "Sample SCP", "profile_type": "SENDING", "cases": [ { "test_case_id": "1.11", "test_case_description": "This test passes if the payment is COMPLETED. Test Harness locks the ACCEPTED payment, then adds the FORWARDED sub-state to the EXECUTED payment before completing.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "COMPLETE", "props": { "preceding_sub_states": [ { "sub_state": "FORWARDED", "memo": "Forwarded to ACH", "info": { "id": "12345678" } } ] } } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "RECEIVER_SUB_STATES", "value": "FORWARDED" } ] }, { "test_case_id": "1.12", "test_case_description": "This test passes if the payment is RETURNED. Test Harness locks the ACCEPTED payment and waits for the sender to settle. Sender applies sub-state REQUEST_RETURN, triggering Test Harness to return payment with ISO code MD06.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "RETURN", "action_data": "MD06", "props": { "sub_state_trigger": { "triggering_sub_state": "REQUEST_RETURN", "trigger_timeout_seconds": 60 } } }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "SENDER_SUB_STATES", "value": "REQUEST_RETURN" }, { "criterion": "RETURN_REASON_CODES", "value": "MD06" } ] }, { "test_case_id": "1.13", "test_case_description": "This test passes if the payment is COMPLETED. Test Harness adds AWAITING_COLLECTION sub-state to EXECUTED payment, requests amendment 2x with REQUEST_INFO sub-state (and sender amends with AMENDED sub-state), then completes payment.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "REQUEST_AMENDMENT", "props": { "preceding_sub_states": [ { "sub_state": "AWAITING_COLLECTION", "memo": "Payment is available for cash pick-up.", "info": { "id": "12345" }, "delay_seconds": 30 } ], "info_request_sub_states": [ { "sub_state": "REQUEST_INFO", "memo": "BE01", "info": { "user_info.Cdtr.StrdNm.FirstNm": "Michael" } }, { "sub_state": "REQUEST_INFO", "memo": "CH11", "info": { "user_info.Cdtr.CtctDtls.MobNb": "08917453", "user_info.Cdtr.CtryOfRes": "PHL", "user_info.Cdtr.Id.PrvtId.Othr.SchmeNm.Cd": "CCPT", "user_info.Cdtr.StrdNm.FirstNm": "Michael", "user_info.Cdtr.StrdNm.LastNm": "Mouse" } } ], "amendment_trigger": { "triggering_sub_state": "AMENDED", "trigger_timeout_seconds": 120 }, "secondary_step": { "action": "COMPLETE" } } } ], "expected_results": [ { "criterion": "STATE", "value": "COMPLETED" }, { "criterion": "SENDER_SUB_STATES", "value": "AMENDED" }, { "criterion": "RECEIVER_SUB_STATES", "value": "REQUEST_INFO,AWAITING_COLLECTION" } ] }, { "test_case_id": "1.14", "test_case_description": "This test passes if the payment is COMPLETED. Test Harness adds AWAITING_COLLECTION sub-state to EXECUTED payment, requests amendment 2x with REQUEST_INFO sub-state (and sender amends with AMENDED sub-state), then returns payment.", "execution_steps": [ { "state": "ACCEPTED", "action": "LOCK" }, { "state": "EXECUTED", "action": "REQUEST_AMENDMENT", "props": { "preceding_sub_states": [ { "sub_state": "AWAITING_COLLECTION", "memo": "Payment is available for cash pick-up.", "info": { "id": "12345" }, "delay_seconds": 30 } ], "info_request_sub_states": [ { "sub_state": "REQUEST_INFO", "memo": "BE01", "info": { "user_info.Cdtr.StrdNm.FirstNm": "Michael" } }, { "sub_state": "REQUEST_INFO", "memo": "CH11", "info": { "user_info.Cdtr.CtctDtls.MobNb": "08917453", "user_info.Cdtr.CtryOfRes": "PHL", "user_info.Cdtr.Id.PrvtId.Othr.SchmeNm.Cd": "CCPT", "user_info.Cdtr.StrdNm.FirstNm": "Michael", "user_info.Cdtr.StrdNm.LastNm": "Mouse" } } ], "amendment_trigger": { "triggering_sub_state": "AMENDED", "trigger_timeout_seconds": 120 }, "secondary_step": { "state": "EXECUTED", "action": "RETURN", "action_data": "BE01,BE05" } } }, { "applicable_to_return_payment": true, "state": "LOCKED", "action": "SETTLE" } ], "expected_results": [ { "criterion": "STATE", "value": "RETURNED" }, { "criterion": "RETURN_PAYMENT_STATE", "value": "COMPLETED" }, { "criterion": "RETURN_REASON_CODES", "value": "BE01,BE05" }, { "criterion": "SENDER_SUB_STATES", "value": "AMENDED" }, { "criterion": "RECEIVER_SUB_STATES", "value": "REQUEST_INFO,AWAITING_COLLECTION" } ] } ] } ``` #### Postman collection To save and import API requests into Postman: 1. Copy, paste, and save the postman collection as `RippleNet Test Harness (Sender Tests).postman_collection` 2. Import the Postman collection into Postman. **Postman Collection** details summary Click to expand ```json { "info": { "_postman_id": "24525e1c-292e-4075-8675-b312c0400848", "name": "RippleNet Test Harness (Sender Tests)", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [ { "name": "(SENDER) Get Auth Token", "event": [ { "listen": "test", "script": { "exec": [ "postman.clearEnvironmentVariable(\"SENDER_AUTH\")", "tests[\"Status code is 200\"] = responseCode.code === 200;", "var data = JSON.parse(responseBody);", "tests[\"Obtained Access Token\"] = data.access_token !== null;", "postman.setEnvironmentVariable(\"SENDER_AUTH\", data.access_token);", "", "pm.globals.set(\"SENDER_AUTH\", data.access_token);" ], "type": "text/javascript" } } ], "request": { "auth": { "type": "basic", "basic": [ { "key": "username", "value": "super_user_client", "type": "string" }, { "key": "password", "value": "secret", "type": "string" } ] }, "method": "POST", "header": [ { "key": "Content-Type", "value": "application/x-www-form-urlencoded" } ], "body": { "mode": "urlencoded", "urlencoded": [ { "key": "grant_type", "value": "client_credentials", "type": "text" } ], "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{SENDER_BASE}}/oauth/token", "host": [ "{{SENDER_BASE}}" ], "path": [ "oauth", "token" ] } }, "response": [] }, { "name": "(SENDER) 1.05 Fail Payment - CUST", "event": [ { "listen": "test", "script": { "exec": [ "var data = JSON.parse(responseBody);", "tests[\"Obtained Payment Object\"] = data.payment_id !== null;", "tests[\"Payment State is COMPLETED\"] = data.payment_state === \"FAILED\";" ], "type": "text/javascript" } } ], "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{SENDER_AUTH}}", "type": "string" } ] }, "method": "POST", "header": [ { "key": "Content-Type", "value": "application/json" } ], "body": { "mode": "raw", "raw": "{\n \"reasons\": [\n {\n \"type\": \"SENDER_RETURN\",\n \"code\": \"CUST\",\n \"reason\": \"RequestedByCustomer\"\n }\n ]\n}" }, "url": { "raw": "{{SENDER_BASE}}/v4/payments/3ea8b365-df58-48e5-9c9a-c35383820eeb/fail", "host": [ "{{SENDER_BASE}}" ], "path": [ "v4", "payments", "3ea8b365-df58-48e5-9c9a-c35383820eeb", "fail" ] } }, "response": [] }, { "name": "(SENDER) 1.12 Add Sub-state - REQUEST_RETURN", "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{SENDER_AUTH}}", "type": "string" } ] }, "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"sub_state\": \"REQUEST_RETURN\",\n \"memo\": \"Return requested by sender.\"\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{SENDER_BASE}}/v4/payments/42aa8494-7c90-41ef-bc77-1ffeacdd2d87/sub_state", "host": [ "{{SENDER_BASE}}" ], "path": [ "v4", "payments", "42aa8494-7c90-41ef-bc77-1ffeacdd2d87", "sub_state" ] } }, "response": [] }, { "name": "(SENDER) 1.13, 1.14 Add Sub-state - AMENDED 1", "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{SENDER_AUTH}}", "type": "string" } ] }, "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"sub_state\": \"AMENDED\",\n \"memo\": \"First name must be corrected\",\n \"info\": {\n \"first_name\": \"Michel\"\n }\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{SENDER_BASE}}/v4/payments/10b1a15c-4480-4ee9-8021-f0db7b7c573d/sub_state", "host": [ "{{SENDER_BASE}}" ], "path": [ "v4", "payments", "10b1a15c-4480-4ee9-8021-f0db7b7c573d", "sub_state" ] } }, "response": [] }, { "name": "(SENDER) 1.13, 1.14 Add Sub-state - AMENDED 2", "request": { "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{SENDER_AUTH}}", "type": "string" } ] }, "method": "POST", "header": [], "body": { "mode": "raw", "raw": "{\n \"sub_state\": \"AMENDED\",\n \"memo\": \"First name must be corrected\",\n \"info\": {\n \"first_name\": \"Michael\"\n }\n}", "options": { "raw": { "language": "json" } } }, "url": { "raw": "{{SENDER_BASE}}/v4/payments/10b1a15c-4480-4ee9-8021-f0db7b7c573d/sub_state", "host": [ "{{SENDER_BASE}}" ], "path": [ "v4", "payments", "10b1a15c-4480-4ee9-8021-f0db7b7c573d", "sub_state" ] } }, "response": [] } ] } ``` ### Open and close test In each section below ([Completed](#completed-payments), [Failed](#failed-payments), [Returned](#returned-payments), [Sub-states](#sub-state-payments)), start testing by creating a new "open" active mode test, and when done running the test cases, close the test to view the results. You can also open one test and use the combined Test Profile but you may need to increase the time allotted to complete the tests. 1. To run your sender tests, log on to the Test Harness that receives payments. 2. Click **Sender Tests** > **Active Mode**. 3. Click **New Test** to open a popup. 4. Select the **Test Profile** "Ripple Sample Sender Test Profile". 5. Select the **RPO Schema** "Ripple Sample RPO Schema". 6. Click **Create Test**. 7. In each section, run all test cases, and when done, click **Close Test** to view the results. ### Expected results For the sender tests included in this tutorial to pass, they must all pass and reach the following states with the defined failure codes within the defined amount of time. ```markdown | TCID | Final State | Sub-state(s) | ISO Codes | |:-----|:------------|:--------------------------------------------|:---------------| | 1.01 | COMPLETED | | | | 1.02 | COMPLETED | | | | 1.03 | COMPLETED | | RC04,FF06 | | 1.04 | FAILED | | AC08 | | 1.05 | FAILED | | CUST | | 1.06 | FAILED | | AC04 | | 1.07 | RETURNED | | MD06 | | 1.08 | RETURNED | | AC03 | | 1.09 | RETURNED | | RR06 | | 1.10 | RETURNED | | | | 1.11 | COMPLETED | FORWARDED | | | 1.12 | RETURNED | REQUEST_RETURN | MD06 | | 1.13 | COMPLETED | AWAITING_COLLECTION, REQUEST_INFO / AMENDED | BE01,CH11 | | 1.14 | RETURNED | AWAITING_COLLECTION, REQUEST_INFO / AMENDED | BE01,CH11,BE05 | ``` If you make a mistake during a test, for example you forgot to disable Auto Lock/Complete for a test that needs to fail, you can create a new payment and try again with the same test case ID.