Originating RTP Credit Transfers

In this tutorial we explore originating a credit transfer from a master account. We will also register relevant webhooks to receive status updates on our payment. Before starting this tutorial, please make sure you have the following:

  • API credentials
  • Partner ID
  • Master Account Number

This tutorial also assumes you have already opened a master account. If not, please complete the Opening an Account tutorial prior to completing this tutorial.

Get an Access Token

Before calling the COS API you must first request an access token. Once the access token has been obtained it is recommended that it is cached for the lifetime of the token. If the API starts to return a 401 response code, it is likely that your token has expired and you need to obtain a new one. More details can be found here.

Register Webhooks

Webhooks allow us to receive notifications when certain events occur within COS. After we originate our credit transfer, we will want to stay informed in order to track the payment through its lifecycle. For that you will need to call the webhook registration endpoint and indicate you wish to receive certain events. A few examples of RTP webhook registration calls are provided below.

The Rtp.Payment.Sent event will notify you in the event your payment has been sent over the RTP network and the funds are available in the creditor's (receiver's) bank account.

POST /webhooks/v1/registrations
{
  "partnerId": "00000000-0000-0000-0000-000000000000",
  "eventName": "Rtp.Payment.Sent",
  "registrationType": "Push", 
  "callbackUrl": "https://cos.yourcompanysite.com/rtp-events"
}

The Rtp.Payment.Received event will notify you in the event a credit transfer has been received by another institution and has posted to your COS account:

POST /webhooks/v1/registrations
{
  "partnerId": "00000000-0000-0000-0000-000000000000",
  "eventName": "Rtp.Payment.Received",
  "registrationType": "Push", 
  "callbackUrl": "https://cos.yourcompanysite.com/rtp-events"
}

The Rtp.Payment.Rejected event will notify you in the event your outbound payment is rejected:

POST /webhooks/v1/registrations
{
  "partnerId": "00000000-0000-0000-0000-000000000000",
  "eventName": "Rtp.Payment.Rejected",
  "registrationType": "Push", 
  "callbackUrl": "https://cos.yourcompanysite.com/rtp-events"

Payments can be rejected by either of the following:

  • By Cross River Bank for compliance reasons
  • By the RTP Network
  • By the receiving institution

To learn more about webhook registrations click here. For a full listing of available RTP webhook events click here.

Before We Begin...

A credit transfer is method of transferring money between banks in real time via the RTP Network. The party sending the funds is referred to as the debtor while the party receiving the funds is referred to as the creditor. The bank sending the credit transfer is referred to as the debtor FI while the bank receiving the credit transfer is referred to as the creditor FI.

The outbound credit transfer can result in one of the following:

  • The creditor FI rejects the transfer
  • The creditor FI accepts the transfer
  • The creditor FI does not respond

🚧

Accepted Without Posting

There may be instances where the creditor FI will provide a response indicating that the transfer was accepted but funds were not yet deposited into the creditor's account, known as "Accepted Without Posting" (ACWP). The creditor FI can then subsequently deposit the funds into the creditor's account or reject the transfer.

Originating a Credit Transfer

In this scenario, we'll be simulating a person-to-person (P2P) transaction where Peter Griffin (debtor) is sending $150 to Cleveland Brown (creditor).

POST /v1/payments

{
  "accountNumber": "2553179843",
  "amount": 15000,
  "creditor": {
    "routingNumber": "011000138",
    "accountNumber": "456789000",
    "name": "Cleveland Brown",
    "addressStreetName": "Spooner St",
    "addressBuildingNumber": "34",
    "addressCity": "Quahog",
    "addressState": "RI",
    "addressPostalCode": "00093",
    "addressCountry": "US"
  },
  "purpose": "gift money"
}

🚧

It is highly recommended that you include an idempotency key in your request header. This will provide duplicate protection in the event of a failure. Read more about idempotency keys here.

Here's a sample response body based on the above request:

{
    "id": "7b5f4bfb-8595-452b-914e-ad9400f7b8e3",
    "originalPaymentId": "7b5f4bfb-8595-452b-914e-ad9400f7b8e3",
    "referenceId": "R242O0354Y055",
    "accountNumber": "2553179843",
    "amount": 15000,
    "direction": "Outbound",
    "status": "Created",
    "paymentType": "CreditTransfer",
    "source": "Api",
    "transactionAccountContext": "NotSubmitted",
    "debtor": {
        "routingNumber": "021214891",
        "accountNumber": "2553179843",
        "name": "Peter M Griffin",
        "addressStreetName": "Spooner Street",
        "addressBuildingNumber": "31",
        "addressCity": "Quahog",
        "addressState": "RI",
        "addressPostalCode": "00093",
        "addressCountry": "US"
    },
    "creditor": {
        "routingNumber": "011000138",
        "accountNumber": "456789000",
        "name": "Cleveland Brown",
        "addressStreetName": "Spooner St",
        "addressBuildingNumber": "34",
        "addressCity": "Quahog",
        "addressState": "RI",
        "addressPostalCode": "00093",
        "addressCountry": "US"
    },
    "network": {
        "businessMessageId": "B20210830021214273T1BNSI93853549430",
        "messageId": "M20210830021214273T1BEML46024873029",
        "createdAt": "2021-08-30T11:01:55.7404545-04:00",
        "numberOfTransactions": 1,
        "interbankSettlementAmount": 15000,
        "currency": "USD",
        "interbankSettlementDate": "2021-08-30",
        "settlementMethod": "CLRG",
        "clearingSystemCode": "TCH",
        "instructionId": "20210830021214273T1B4S0534677157734",
        "endToEndId": "9a2638dc8cbe48f18d8cad9400f7b8e3",
        "transactionId": "20210830021214273T1B4S0534677157734",
        "fromParticipantId": "021214273T1",
        "toParticipantId": "990000001S1",
        "instructingRoutingNumber": "021214891",
        "instructedRoutingNumber": "011000138",
        "headerCreationDate": "2021-08-30T11:01:55.7404545-04:00",
        "messageCreationDateTime": "2021-08-30T11:01:55.7404545-04:00"
    },
    "serviceLevelCode": "SDVA",
    "localInstrumentProprietary": "STANDARD",
    "categoryPurpose": "CONSUMER",
    "currency": "USD",
    "chargeBearer": "SLEV",
    "purpose": "gift money",
    "wasRefunded": false,
    "wasPaid": false,
    "createdAt": "2021-08-30T11:01:55.7404545-04:00",
    "productId": "13362d99-f04e-455b-9363-abc10151c27c",
    "partnerId": "bd7a716f-6349-43ef-89cd-aa2200f15977",
    "lastModifiedAt": "2021-08-30T11:01:55.7414531-04:00",
    "sendAttemptCount": 0,
    "discounts": [],
    "awaitingResponse": false
}

Every request received by COS will contain a request-id value. This is a unique identifier for your request and is useful when troubleshooting issues with our support team. It is recommended you log this identifier.

{
  "access-control-allow-credentials": "true",
  "access-control-allow-origin": "https://sandbox.crbcos.com",
  "cache-control": "no-cache",
  "content-length": "1855",
  "content-type": "application/json; charset=utf-8",
  "date": "Mon, 30 Aug 2021 15:01:55 GMT",
  "expires": "-1",
  "pragma": "no-cache",
  "request-id": "5329cb29-ce2c-4586-8767-ad9400f7b8dc",
  "server": "Microsoft-IIS/8.5",
  "x-aspnet-version": "4.0.30319",
  "x-frame-options": "SAMEORIGIN",
  "x-powered-by": "ASP.NET"
}

Once the payment is released to the network, you'll receive a webhook event which will contain the payment ID within the resources section of the event body:

{
  "id": "7af80bc3-4f1c-4842-b60e-ad9400fb59db",
  "eventName": "Rtp.Payment.Sent",
  "status": "Pending",
  "partnerId": "bd7a716f-6349-43ef-89cd-aa2200f15977",
  "createdAt": "2021-08-30T11:15:08.623-04:00",
  "resources": [
    "rtp/v1/payments/7b5f4bfb-8595-452b-914e-ad9400f7b8e3"
  ],
  "details": []
}

Use that payment ID with the GET /v1/payments/{id} endpoint to query the details of the payment:

GET /v1/payments/{id}

{
    "id": "7b5f4bfb-8595-452b-914e-ad9400f7b8e3",
    "originalPaymentId": "7b5f4bfb-8595-452b-914e-ad9400f7b8e3",
    "referenceId": "R242O0354Y055",
    "accountNumber": "2553179843",
    "amount": 15000,
    "operatorCoreTransactionId": "2da7c99c-5804-4757-98c1-ad9400fa6c2c",
    "memoPostId": "7b5f4bfb-8595-452b-914e-ad9400f7b8e3",
    "memoPostRemovedAt": "2021-08-30T11:14:44.973-04:00",
    "direction": "Outbound",
    "status": "Completed",
    "paymentType": "CreditTransfer",
    "source": "Api",
    "transactionAccountContext": "Complete",
    "rtpTransactionStatus": "ACTC",
    "debtor": {
        "routingNumber": "021214891",
        "accountNumber": "2553179843",
        "name": "Peter M Griffin",
        "addressStreetName": "Spooner Street",
        "addressBuildingNumber": "31",
        "addressCity": "Quahog",
        "addressState": "RI",
        "addressPostalCode": "00093",
        "addressCountry": "US"
    },
    "creditor": {
        "routingNumber": "011000138",
        "accountNumber": "456789000",
        "name": "Cleveland Brown",
        "addressStreetName": "Spooner St",
        "addressBuildingNumber": "34",
        "addressCity": "Quahog",
        "addressState": "RI",
        "addressPostalCode": "00093",
        "addressCountry": "US"
    },
    "network": {
        "messageDefId": "pacs.008.001.08",
        "businessMessageId": "B20210830021214273T1BQPZ97287285414",
        "messageId": "M20210830021214273T1BEML46024873029",
        "createdAt": "2021-08-30T11:01:55.74-04:00",
        "numberOfTransactions": 1,
        "interbankSettlementAmount": 15000,
        "currency": "USD",
        "interbankSettlementDate": "2021-08-30",
        "settlementMethod": "CLRG",
        "clearingSystemCode": "TCH",
        "instructionId": "20210830021214273T1B4S0534677157734",
        "endToEndId": "9a2638dc8cbe48f18d8cad9400f7b8e3",
        "transactionId": "20210830021214273T1B4S0534677157734",
        "clearingSystemRef": "001",
        "fromParticipantId": "021214273T1",
        "toParticipantId": "990000001S1",
        "instructingRoutingNumber": "021214891",
        "instructedRoutingNumber": "011000138",
        "headerCreationDate": "2021-08-30T11:11:45.373-04:00",
        "messageCreationDateTime": "2021-08-30T11:01:55.74-04:00"
    },
    "confirmedStatus": {
        "messageStatusReportId": "2da7c99c-5804-4757-98c1-ad9400fa6c2c",
        "acceptedDateTime": "2021-08-30T11:11:45.4-04:00",
        "transactionStatus": "ACTC"
    },
    "serviceLevelCode": "SDVA",
    "localInstrumentProprietary": "STANDARD",
    "categoryPurpose": "CONSUMER",
    "currency": "USD",
    "chargeBearer": "SLEV",
    "purpose": "gift money",
    "wasRefunded": false,
    "wasPaid": false,
    "createdAt": "2021-08-30T11:01:55.74-04:00",
    "completedAt": "2021-08-30T11:14:45.05-04:00",
    "processingStartedAt": "2021-08-30T11:11:45.247-04:00",
    "postingCode": "OK",
    "productId": "13362d99-f04e-455b-9363-abc10151c27c",
    "partnerId": "bd7a716f-6349-43ef-89cd-aa2200f15977",
    "lastModifiedAt": "2021-08-30T11:14:45.0505825-04:00",
    "sentAt": "2021-08-30T11:11:45.3733333-04:00",
    "sendAttemptCount": 1,
    "result": {
        "code": "OK"
    },
    "discounts": [],
    "awaitingResponse": false
}

The response body above reflects a payment status of Completed and an rtpTransactionStatus of ACTC. Visit the RTP Reference page more information on RTP payment statuses.

Credit Transfer Using Ultimate Debtor

In this example, we'll be illustrating the use of the ultimate debtor fields within the payment transaction. Initech, a customer of Acme Co, wants to send $100 to their customer Globex Corp. Acme Co will be originating the $100 payment from their COS account. This means that Acme Co is the debtor, Initech is the ultimate debtor, and Globex Corp is the creditor. Here's what that request would look like:

{
  "accountNumber": "2342123458",
  "amount": 10000,
  "debtor": {
    "accountNumber": "2342123458",
    "name": "Acme Co",
    "addressStreetName": "Any St",
    "addressBuildingNumber": "123",
    "addressCity": "Anytown",
    "addressState": "NY",
    "addressPostalCode": "11101",
    "addressCountry": "US"
  },
  "ultimateDebtor": {
    "name": "Initech",
    "addressStreetName": "Office Way",
    "addressBuildingNumber": "555",
    "addressCity": "Sometown",
    "addressState": "MA",
    "addressPostalCode": "03741",
    "addressCountry": "US"
  },
  "creditor": {
    "routingNumber": "021000021",
    "accountNumber": "222354852",
    "name": "Globex Corp",
    "addressStreetName": "World Way",
    "addressBuildingNumber": "15",
    "addressCity": "New York",
    "addressState": "NY",
    "addressPostalCode": "10013",
    "addressCountry": "US"
  },
  "purpose": "Invoice T741"
  },
}

Did this page help you?