Simulate an Incoming Payment Detail

Simulate an Incoming Payment Detail in the sandbox

Overview

In the sandbox, you may want to simulate workflows where you have received a payment in your bank account from an external party. This guide walks you through how to simulate these workflows so you can build the end-to-end experience in your application.

1. Create an Incoming Payment Detail

  • The first step is to create an Incoming Payment Detail (IPD). To successfully simulate IPDs they should only be created from internal accounts linked to Gringotts Wizarding Bank. You will use an endpoint that creates the IPD asynchronously and notifies you via webhook if it was successfully created. Just as in production, you will receive a webhook from Modern Treasury when an IPD is created.

Here are two examples for how to create the IPD. The first one demonstrates the base case of an IPD in an internal account. The second demonstrates how to create an IPD associated to a virtual account.

curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/simulations/incoming_payment_details/create_async \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "wire",
    "direction": "credit",
    "amount": 2000,
    "internal_account_id": "0f8e3719-3dfd-4613-9bbf-c0333781b59f"
  }'
curl --request POST \
  -u ORGANIZATION_ID:API_KEY \
  --url https://app.moderntreasury.com/api/simulations/incoming_payment_details/create_async \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "wire",
    "direction": "credit",
    "amount": 2000,
    "internal_account_id": "0f8e3719-3dfd-4613-9bbf-c0333781b59f",
    "virtual_account_id": "4844bda1-eb57-4129-afb4-fc663a395ca0"
  }'

You will receive the following successful API response from this endpoint, unless you pass in an invalid internal_account_id or virtual_account_id.

{
  "object": "incoming_payment_detail",
  "id": "c5f4009c-bdd6-4cc1-84b2-17974ac9e77a"
}

2. Monitor for IPD created webhook

After enqueuing the IPD for creation in step 1, you must now monitor for the webhook to see if it was created successfully or not. There is a 1 minute delay before you receive the created webhook event.

If created successfully, you will receive the IPD in a webhook. This webhook will resemble what you see in production. The initial state of the IPD will be pending until it is reconciled to a transaction, which happens in step 3.

Please note that the exact schema within the data object may change depending on your bank. The sandbox simulates the data object from one of our partners, Increase.

{
  "event": "created",
  "data": {
    "id": "4844bda1-eb57-4129-afb4-fc663a395ca0",
    "object": "incoming_payment_detail",
    "internal_account_id": "c5f4009c-bdd6-4cc1-84b2-17974ac9e77a",
    "virtual_account_id": null,
    "transaction_line_item_id": null,
    "transaction_id": null,
    "type": "wire",
    "data": { // This field may contain PII and is not included in webhook event bodies by default
      "id": "sandbox_transaction_686898458",
      "date": "2021-05-07",
      "path": "/transactions/sandbox_transaction_686898458",
      "amount": 3100,
      "source": {
        "amount": 3100,
        "class_name": "inbound_wire_transfer",
        "description": "Doloremque ducimus blanditiis incidunt.",
        "originator_name": "Prof. Summer Lesch",
        "beneficiary_name": "Rachele Bergnaum DVM",
        "beneficiary_reference": "84624313903339570000",
        "originator_address_line1": "7953 Kessler Union",
        "originator_address_line2": "Suite 964",
        "originator_address_line3": "Richelleside",
        "beneficiary_address_line1": "713 Ivey Ports",
        "beneficiary_address_line2": "Suite 686",
        "beneficiary_address_line3": "Baileyborough",
        "input_message_accountability_data": "66872621214100990000",
        "originator_to_beneficiary_information_line1": "Alias earum fuga culpa.",
        "originator_to_beneficiary_information_line2": "null",
        "originator_to_beneficiary_information_line3": "null",
        "originator_to_beneficiary_information_line4": "null"
      },
      "route_id": "sandbox_account_route_1",
      "account_id": "sandbox_account_1296c413b83b",
      "description": "Doloremque ducimus blanditiis incidunt."
    },
    "amount": 10000,
    "currency": "USD",
    "direction": "credit",
    "status": "pending",
    "metadata": {},
    "as_of_date": "2020-10-17",
    "live_mode": true,
    "created_at": "2020-10-15T04:23:11Z",
    "updated_at": "2020-10-15T04:23:11Z"
  }
}

If the data provided in the original API call is invalid, you will receive a webhook to indicate it was not created.

{
  "event": "failed",
  "id": "4844bda1-eb57-4129-afb4-fc663a395ca0",
  "errors": {
    "code": "parameter_missing",
    "message": "Amount is required",
    "parameter": "amount"
  }
}

3. Monitor for reconciliation webhooks

In step 2, we showed how to simulate creating an IPD. Typically, you will receive an IPD a few hours to a day prior to a Transaction posting in your bank account. Once a transaction posts in your bank account, Modern Treasury automatically reconciles the IPD to the bank transaction. In the sandbox, we simulate the transaction creation and subsequent reconciliation.

There are four webhooks you'll see delivered on two different objects: the IPD and the transaction.

The first and second webhooks will be for the completed and reconciled events on the IPD. They will indicate that the IPD has been reconciled to a posted transaction. For the details behind why there are two webhooks, you should refer to the IPD webhook guide. In short, however, it is safe to just use the completed webhook, which is detailed below.

{
  "event": "completed",
  "data": {
    "id": "4844bda1-eb57-4129-afb4-fc663a395ca0",
    "object": "incoming_payment_detail",
    "internal_account_id": "c5f4009c-bdd6-4cc1-84b2-17974ac9e77a",
    "virtual_account_id": null,
    "transaction_line_item_id": null,
    "transaction_id": null,
    "type": "wire",
    "data": { // This field may contain PII and is not included in webhook event bodies by default
      "id": "sandbox_transaction_686898458",
      "date": "2021-05-07",
      "path": "/transactions/sandbox_transaction_686898458",
      "amount": 3100,
      "source": {
        "amount": 3100,
        "class_name": "inbound_wire_transfer",
        "description": "Doloremque ducimus blanditiis incidunt.",
        "originator_name": "Prof. Summer Lesch",
        "beneficiary_name": "Rachele Bergnaum DVM",
        "beneficiary_reference": "84624313903339570000",
        "originator_address_line1": "7953 Kessler Union",
        "originator_address_line2": "Suite 964",
        "originator_address_line3": "Richelleside",
        "beneficiary_address_line1": "713 Ivey Ports",
        "beneficiary_address_line2": "Suite 686",
        "beneficiary_address_line3": "Baileyborough",
        "input_message_accountability_data": "66872621214100990000",
        "originator_to_beneficiary_information_line1": "Alias earum fuga culpa.",
        "originator_to_beneficiary_information_line2": "null",
        "originator_to_beneficiary_information_line3": "null",
        "originator_to_beneficiary_information_line4": "null"
      },
      "route_id": "sandbox_account_route_1",
      "account_id": "sandbox_account_1296c413b83b",
      "description": "Doloremque ducimus blanditiis incidunt."
    },
    "amount": 10000,
    "currency": "USD",
    "direction": "credit",
    "status": "completed",
    "metadata": {},
    "as_of_date": "2020-10-17",
    "live_mode": true,
    "created_at": "2020-10-15T04:23:11Z",
    "updated_at": "2020-10-15T04:23:11Z"
  }
}

The third and fourth webhooks you will receive will be the created and reconciled webhooks on the transaction object. You will get these in rapid succession, since our system automatically creates the transaction and reconciles it immediately. This will mirror the events you'd see in production.

📘

Using the webhooks

In many cases, our customers simply rely on the IPD webhooks. If you want to ignore the transaction webhooks, that is safe to do and you may customize your event delivery options in the dashboard to exclude them.