How to deposit a check

In this tutorial, you'll learn how to

Register the relevant webhooks

Deposit a check

Handle rejected checks

Note

If you are new to check management we recommend you read the check management overview before starting this tutorial.

The tutorial assumes you have a knowledge of APIs and how they work. For more information on sending API calls, see the API overview page.

The tutorial uses these API endpoints

API

Description

POST /Checks/v1/payments

Provides the necessary information and images to deposit a check

The tutorial uses these webhooks.

Webhook

Description

Check.Payment.Sent

A check deposit was sent to the Federal Reserve for clearing

Check.Payment.Rejected

An outbound check wasn't processed due to compliance reasons or rejection by the Federal Reserve

Check.Payment.Returned

Receiving bank returned a check to the sender

Before you begin

Make sure you have:

  • API credentials

  • Cross River bank account number

  • Images of the front and back of the check in Base64 (C9 check) format

Register the relevant webhook events

To receive the webhook events for this tutorial both partner accounts need to register each specific webhook event type. Once you are registered, the event objects are sent to the registered URLs.

The event object contains a list of resource identifiers used to download details on each event.

Deposit a check

In this tutorial you're a Banking-as-a-Service (BaaS) partner that offers a deposit account product to consumers. Your app allows your customers to perform mobile deposits. One of your customers just made a $1 check deposit into their account using your app, which is calling the CR system to pass the deposit details.

To deposit a check

  1. Call POST /Checks/v1/payments. For this call, you must supply the number of the account where the check is being deposited and images of both the front and back of the check as Base64-encoded values. A full list of attributes is found here.

    Copy
    Sample request POST /Checks/v1/payments
    POST /v1/payments
    {
      "accountNumber": "2193590144",
      "amount": 100,
      "frontImage": "image/jpg;base64,/9j/4REyRXhpZgAATU0AKgA...",
      "backImage": "image/jpg;base64,/9j/4QuqRXhpZgAATU0AKg...",
      "isRedeposit": false
    }
  2. A successful API call returns a JSON response with the details of the check. The status attribute in the response only tells you that the payment was created. It's not an indicator of a successful payment. The id attribute provides you with the payment ID. In this case, it's 9a44fdbf-89e2-4300-8f05-ad9501439bb1. The schedule attribute shows the schedule for paying the deposit into the account.

  3. Copy
    Sample response POST /checks/v1/payments
    {
      "id": "9a44fdbf-89e2-4300-8f05-ad9501439bb1",
      "accountNumber": "2193590144",
      "referenceId": "C2436F698K0D",
      "paymentType": "Forward",
      "checkType": "Standard",
      "direction": "Outbound",
      "status": "Created",
      "source": "OpsPortal",
      "posting": "Pending",
      "postingCode": "OK",
      "coreTransactionId": "21ba5fb0-e609-4560-a36f-ad9501439bb1",
      "memoPostId": "dc20e619-c5f7-4890-b3c8-ad9501439bb1",
      "originalPaymentId": "9a44fdbf-89e2-4300-8f05-ad9501439bb1",
      "customerId": "700f0d35-9940-4132-8608-ad89013927a9",
      "payerRoutingNumber": "",
      "payerAccountNumber": "",
      "payeeName": "",
      "checkNumber": "",
      "bofdRoutingNumber": "021214891",
      "sequenceNumber": "1353885824",
      "amount": 100,
      "currency": "usd",
      "recognizedAmount": 0,
      "iqaPassed": false,
      "hasFrontImage": true,
      "hasBackImage": true,
      "isRedeposit": false,
      "policy": "NewAccount",
      "schedule": [
        0,
        0,
        100
      ],
      "createdAt": "2021-08-31T15:38:13.2795042-04:00",
      "wasReturned": false,
      "purpose": "ENTERED BY #60C367E26DD36A0068580230#",
      "depositBusinessDate": "210831",
      "productId": "d5dc52bb-df80-4a5d-a5a8-ad89013844bd",
      "partnerId": "ede1a60d-3d51-47e8-9a9b-ad8901381f9e",
      "lastModifiedAt": "2021-08-31T15:38:13.2951299-04:00"
  4. The CR system executes its OCR process to convert the check images into a format that complies with Federal Reserve Standards. CR sends the check deposit to the Federal Reserve for clearing, which triggers the Check.Payment.Sent webhook event. Note that the payment ID appears in the resources array.

    Note
    If you are registered for the Core.Transaction.Completed webhook event, you also receive that webhook at this point. When the check payment is released to the Federal Reserve, the CR system executes the core transaction related to the payment. This does not mean the funds are available. The schedule attribute in the response indicates the availability schedules of the deposited funds.
    Copy
    Sample Check.Payment.Set event
    {
      "id": "160e52d2-4355-4fa3-a421-ad8800f886a2",
      "eventName": "Check.Payment.Sent",
      "status": "Pending",
      "partnerId": "4c5b488d-711d-428a-bdae-ad800131970d",
      "createdAt": "2021-08-31T15:39:51.3-04:00",
      "resources": [
        "checks/v1/payments/9a44fdbf-89e2-4300-8f05-ad9501439bb1"
      ],
      "details": [
        {
          "paymentId": "9a44fdbf-89e2-4300-8f05-ad9501439bb1",
          "paymentType": "Forward",
          "coreTransactionId": "21ba5fb0-e609-4560-a36f-ad9501439bb1",
          "memoPostId": "dc20e619-c5f7-4890-b3c8-ad9501439bb1",
          "accountNumber": "2193590144",
          "depositBusinessDate": "230808",
          "postingCode": "OK",
          "amount": "10000",
          "recognizedAmount": "100",
          "payerRoutingNumber": "314074269",
          "payerAccountNumber": "28293886",
          "checkNumber": "1237",
          "checkType": "Standard",
          "sequenceNumber": "1353885824",
          "micr": "1237",
          "purpose": "SKIP_IQA",
          "clientIdentifier": null,
          "schedule": "0,0,10000",
          "policy": "Standard",
          "rejectionReason": null,
          "isRedeposit": "False",
          "originalPaymentId": "9a44fdbf-89e2-4300-8f05-ad9501439bb1"
        }
      ]
    }

Check validation

A check is systemically validated for compliance when you deposit it, for example the system verifies that the check has a valid MICR number. Results of this validation appear in the body of the response to the deposit request. Non-compliant checks are rejected and the rejection reason appears in the rejectionReason field.

Rejected checks

Check rejection triggers the webhook event. In this case the payment ID is b9e53e1c-683e-469c-8f79-ad8800f1ccc.

Copy
Sample Check.Payment.Rejected event
{
  "id": "96595e06-508f-4d5f-ba80-ad8800f1e69d",
  "eventName": "Check.Payment.Rejected",
  "status": "Pending",
  "partnerId": "4c5b488d-711d-428a-bdae-ad800131970d",
  "createdAt": "2021-08-18T10:40:44.033-04:00",
  "resources": [
    "checks/v1/payments/b9e53e1c-683e-469c-8f79-ad8800f1ccc3"
  ],
  "details": [
    {
      "paymentId": "b9e53e1c-683e-469c-8f79-ad8800f1ccc3",
      "paymentType": "Forward",
      "coreTransactionId": "2c9292b0-cf01-44c5-b416-b05800de64c7",
      "memoPostId": "ef1aee23-1546-438a-a2bd-b05800de64c7",
      "accountNumber": "2151546989",
      "depositBusinessDate": "230808",
      "postingCode": "OK",
      "amount": "70000",
      "recognizedAmount": "100",
      "payerRoutingNumber": "314074269",
      "payerAccountNumber": "28293886",
      "checkNumber": "1237",
      "checkType": "Standard",
      "sequenceNumber": "0283216503",
      "micr": "1237",
      "purpose": "SKIP_IQA",
      "clientIdentifier": null,
      "schedule": "0,0,70000",
      "policy": "Standard",
      "rejectionReason": "Duplicate",
      "isRedeposit": "False",
      "originalPaymentId": "b9e53e1c-683e-469c-8f79-ad8800f1ccc3"
    }
  ]
}

As already described, the rejection reason appears in the rejectionReason field of the event. In the example above, the check payment is rejected because of Duplicate. Address any check issues with the customer prior to resubmitting the check deposit to avoid subsequent rejections.