Simulate a Payment Action

Overview

In Modern Treasury's Sandbox, you can test Payment Action workflows for Stop Payment actions on check payments. This applies to both Bring Your Own Bank accounts and PSP accounts.

When you create a Stop Payment Action in the Sandbox, the system simulates different outcomes based on the counterparty name on the original payment order. This allows you to test success and failure scenarios without interacting with a real bank.

For Bring Your Own Bank accounts, if the Payment Action is not associated with a Payment Order, you can set the details.payee_name field directly on the Payment Action with the same test values to trigger the simulation behavior.

Scenarios

Simulate a Successful Payment Action

Create a check payment order to any counterparty whose name does not contain one of the special test strings described below. Then create a Stop Payment Action on that payment order.

Result:

  • The Payment Action transitions to acknowledged.
  • The associated Payment Order transitions to stopped.

This simulates the standard flow where your bank successfully processes the stop payment request.

Simulate a Failed Payment Action

Create a check payment order to a counterparty whose name contains the string payment_action_failed (e.g., "Test payment_action_failed Co."). Then create a Stop Payment Action on that payment order.

Result:

  • The Payment Action transitions to failed.
  • The associated Payment Order is not affected.

This simulates a scenario where the bank rejects the stop payment request.

Simulate a Payment Action Stuck in Sent

Create a check payment order to a counterparty whose name contains the string payment_action_sent (e.g., "Test payment_action_sent Co."). Then create a Stop Payment Action on that payment order.

Result:

  • The Payment Action remains in sent status and does not progress further.
  • The associated Payment Order is not affected.

This simulates a scenario where the stop payment request has been sent to the bank but no response has been received yet.

Steps

1. Create a Counterparty

Create a counterparty with the appropriate name for the scenario you want to test. The name must contain the test string for failure or sent simulations. For the default success scenario, any name will work.

Because stop payment actions target check payments, the counterparty's external account must include a party_address. In the Sandbox, use one of the recognized test addresses (e.g., "7 Hogsmeade Ave.") to pass address validation.

curl --request POST \
  -u $ORGANIZATION_ID:$API_KEY \
  --url https://app.moderntreasury.com/api/counterparties \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Stop Payment Test Counterparty",
    "accounts": [
      {
        "account_type": "checking",
        "party_address": {
          "line1": "7 Hogsmeade Ave.",
          "locality": "San Francisco",
          "region": "California",
          "postal_code": "94108",
          "country": "US"
        },
        "routing_details": [
          {
            "routing_number_type": "aba",
            "routing_number": "121141822"
          }
        ],
        "account_details": [
          {
            "account_number": "123456789"
          }
        ]
      }
    ]
  }'
curl --request POST \
  -u $ORGANIZATION_ID:$API_KEY \
  --url https://app.moderntreasury.com/api/counterparties \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Test payment_action_failed Co.",
    "accounts": [
      {
        "account_type": "checking",
        "party_address": {
          "line1": "7 Hogsmeade Ave.",
          "locality": "San Francisco",
          "region": "California",
          "postal_code": "94108",
          "country": "US"
        },
        "routing_details": [
          {
            "routing_number_type": "aba",
            "routing_number": "121141822"
          }
        ],
        "account_details": [
          {
            "account_number": "123456789"
          }
        ]
      }
    ]
  }'
curl --request POST \
  -u $ORGANIZATION_ID:$API_KEY \
  --url https://app.moderntreasury.com/api/counterparties \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Test payment_action_sent Co.",
    "accounts": [
      {
        "account_type": "checking",
        "party_address": {
          "line1": "7 Hogsmeade Ave.",
          "locality": "San Francisco",
          "region": "California",
          "postal_code": "94108",
          "country": "US"
        },
        "routing_details": [
          {
            "routing_number_type": "aba",
            "routing_number": "121141822"
          }
        ],
        "account_details": [
          {
            "account_number": "123456789"
          }
        ]
      }
    ]
  }'

2. Create a Check Payment Order

Create a check payment order against the counterparty you just created. You will need the External Account ID from the counterparty creation response.

curl --request POST \
  -u $ORGANIZATION_ID:$API_KEY \
  --url https://app.moderntreasury.com/api/payment_orders \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "check",
    "amount": 10000,
    "direction": "credit",
    "currency": "USD",
    "originating_account_id": "YOUR_INTERNAL_ACCOUNT_ID",
    "receiving_account_id": "COUNTERPARTY_EXTERNAL_ACCOUNT_ID"
  }'

Wait for the Payment Order to reach sent status. In the Sandbox, this happens within seconds.

3. Create a Stop Payment Action

Once the payment order is in sent status, create a Stop Payment Action. You can do this via the API or from the Payment Order detail page in the Dashboard by selecting Stop Check Payment from the Actions dropdown.

curl --request POST \
  -u $ORGANIZATION_ID:$API_KEY \
  --url https://app.moderntreasury.com/api/payment_actions \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "stop",
    "actionable_id": "PAYMENT_ORDER_ID",
    "actionable_type": "payment_order"
  }'

Alternative: Create a Payment Action Without a Payment Order (Bring Your Own Bank Only)

For Bring Your Own Bank accounts, you can create a Stop Payment Action that is not associated with a Payment Order. In this case, provide your internal_account_id and set details.payee_name to the test string to control the sandbox behavior.

curl --request POST \
  -u $ORGANIZATION_ID:$API_KEY \
  --url https://app.moderntreasury.com/api/payment_actions \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "stop",
    "internal_account_id": "YOUR_INTERNAL_ACCOUNT_ID",
    "details": {
      "payee_name": "payment_action_failed",
      "amount": 10000,
      "currency": "USD",
      "check_number": "1234",
      "issue_date": "2026-01-15",
      "originating_account_number": "123456789"
    }
  }'

The same test values apply: use payment_action_failed to simulate a failure, or payment_action_sent to simulate a stuck-in-sent state. Any other value will follow the default success path.

4. Observe the Result

The sandbox will process the Payment Action within seconds. Check the status of the Payment Action and the associated Payment Order to verify the expected outcome for your scenario.

ScenarioTest ValuePayment Action StatusPayment Order Status
Success (default)(any name)acknowledgedstopped
Failurepayment_action_failedfailedunchanged
Stuck in sentpayment_action_sentsentunchanged

The test value can be set via the counterparty name on the original payment order, or via details.payee_name on the Payment Action itself when there is no associated Payment Order (Bring Your Own Bank only).