# TxPUSH
source: https://developer.mastercard.com/open-finance-us/documentation/products/manage/tx-push/index.md

## Overview {#overview}

TxPUSH is an alternative to pulling aggregated account and transaction data daily in order to stay up to date. TxPUSH automatically sends update notifications to an event listener, so a client can be PUSHed the most up to date information when it is available, and skip PULLing when there are no changes.
Note: The TxPUSH service is not compatible with [Data Access Tiers](https://developer.mastercard.com/open-finance-us/documentation/products/manage/data-access-tiers/index.md) (ASD, AFD, and ATD).

## How it Works {#how-it-works}

TxPUSH services allow an app to register a TxPUSH Listener service to receive notifications whenever there are updates to account or transaction data for a specific customer's account.

#### Subscribe to TxPUSH Notifications {#subscribe-to-txpush-notifications}


API Reference: `POST /aggregation/v1/customers/{customerId}/accounts/{accountId}/txpush`

#### Disable TxPUSH Notification {#disable-txpush-notification}


API Reference: `DELETE /aggregation/v1/customers/{customerId}/accounts/{accountId}/txpush`

#### Delete TxPUSH Subscription {#delete-txpush-subscription}


API Reference: `DELETE /aggregation/v1/customers/{customerId}/subscriptions/{subscriptionId}`

#### Create TxPUSH Test Transaction {#create-txpush-test-transaction}


API Reference: `POST /aggregation/v1/customers/{customerId}/accounts/{accountId}/transactions`

### Subscription Record {#subscription-record}

TxPUSH subscription details:

|          Name          |                        Description                        |
|------------------------|-----------------------------------------------------------|
| id (Required)          | (Long) Unique subscription identifier.                    |
| accountId (Required)   | (Long) The Finicity account ID for the subscription.      |
| type (Required)        | (String) Event subscription type. account or transaction. |
| callbackUrl (Required) | (String) The url for the events.                          |
| signingKey (Required)  | (String) Signing key for events.                          |

## Setting Up the TxPUSH Listener Service {#setting-up-the-txpush-listener-service}

An account must already be added to the Mastercard platform via [Mastercard Data Connect](https://developer.mastercard.com/open-finance-us/documentation/connect/index.md) before a TxPUSH subscription can be set up.

To begin receiving TxPUSH notifications, the TxPUSH Listener needs to be set up. You will need to define a public RESTful web service that is accessible from the Mastercard platform. Using the Subscribe to TxPUSH Notifications endpoint, enter a URL that will be used as the TxPUSH Listener URL, where notifications will be sent. The URL can use the standard HTTP protocol (port 80) for test accounts, but must use the secure HTTPS protocol (port 443) for any real-world accounts. This arrangement is to facilitate testing, by requiring SSL configuration only when moving into Production. The use of other ports will result in the call failing.

Notifications can be sent in either JSON or XML format. To set up notifications in JSON, list application/json in the Accept field of the header; to set up notifications in XML, list application/xml in the Accept field of the header.

After the subscription request has been sent, Mastercard will respond with a GET call to the listener with a URL parameter that includes a txpush_verification_code. Respond with an HTTP 200, header Content-Type: text/plain, and a response body containing the txpush_verification_code in plain text in the body of the response. Finally, Mastercard will respond again with an HTTP 200 and an ID, which can be treated as a confirmation code, and a signingKey, which can be used as a key to validate the txpush-signature of future notifications. This is a one-time event to verify an active TxPUSH Listener URL. The txpush_verification_code and ID are not needed in any subsequent requests.

For example, if the callback URL `https://callback.example.com/txpush` is used, Mastercard will respond: `GET https://callback.example.com/txpush?txpush_verification_code=CODE`. The TxPUSH Listener should respond with an HTTP code 200, header Content-Type: text/plain, and a response body containing the verification code value (copied from the request parameter) in plain text.

If a txpush_verification_code is not sent in the first HTTP 200 response, or the txpush_verification_code is incorrect, Mastercard will respond with a 60000 code indicating the txpush_verification_code is invalid, and the subscription request will be rejected.

To validate a successful set up, the Create TxPush Test Transaction endpoint can be used to set up a test transaction on a test account to trigger a TxPUSH notification.

## TxPUSH Webhook Notification {#txpush-webhook-notification}

Partners must create a listener endpoint to receive the TxPUSH Webhook Notification. You can download the specification for the notification events:
[txpush-webhooks-us.yaml](https://static.developer.mastercard.com/content/open-finance-us/swagger/txpush-webhooks-us.yaml) (12KB)

When an event is received, the listener must return HTTP 200 (OK) to acknowledge the message. If an event is not acknowledged promptly, Mastercard will resend the notice every 30 minutes for up to six hours. If the notification is not acknowledged within six hours, the notification service on that event will be canceled. Instead, the event can be retrieved through an account aggregation or transaction aggregation API call.

TxPUSH notifications can be cancelled by using the [Disable TxPUSH Notifications endpoint](https://developer.mastercard.com/open-finance-us/documentation/products/manage/tx-push/index.md#disable-txpush-notification). This will stop all future account data or transaction events from being sent to the TxPUSH Listener URL for the specified account. TxPUSH notifications may be set-up again for the specified account by following the Setting Up the TxPUSH Listener Service steps above.
Note: TxPUSH notifications are sent from the IP address 68.142.128.67. To ensure the arrival of notifications, add this address to your allow-list for inbound traffic. Allow-listing is an alternative option to verifying the txpush-signature by blocking all other traffic.

When setting up more than one TxPUSH subscription, different URLs are not needed for each account. They can be the same, different, or a combination; however, subscription set-up must be completed for each account.

TxPUSH varies from Webhook technology as webhooks will have an expected response, such as a report that has been requested. TxPUSH works on aggregation, where there may or may not be an update, depending on financial institution and customer actions.

One use of TxPUSH is to determine when the first aggregation has been completed on an account. Clients may consider the following flow to enable this solution:

* Customer adds an account in Connect
* Call **Get Customer Account**
* Subscribe to TxPUSH Notifications
* Call **Refresh Customer Accounts**

<br />

TxPUSH will send both an account and transaction event with the data, so clients can skip additional calls to the Account Aggregation and Transaction Aggregation endpoints on the first aggregation. In addition, TxPUSH reduces your development time by allowing you to keep your data up to-date without the development work required with a traditional batch process.

## Understanding TxPUSH Notifications {#understanding-txpush-notifications}

TxPUSH runs constantly, and a notification will automatically be sent out to the TxPUSH Listener URL when there is an update (called event) to either account or transaction data for a specific customer's account. These updates are batched, so there may be a slight delay between Mastercard receiving the update, and a TxPUSH notification being sent out. Notifications are sent as HTTP POST requests to the TxPUSH Listener URL in the format determined during setup.
Warning: If you are caching transaction data, we recommend that you use the `uniqueTransactionId` instead of the simple transaction ID when querying the cached data. This avoids any potential problems caused by the same transaction ID being used with more than one customer.

If you are not able to use the unique ID (for example if you have data cached from before the unique ID was introduced in Q1 2026), ensure you use the transaction ID along with an `accountId` or `customerId` when querying the cached data. This avoids any potential problems caused by the same transaction ID being used with more than one customer.

There are two classes of events the Listener can receive, account data events and transaction events. The account data events and transaction events include the following event types: MODIFIED, DELETED, and CREATED.

### Event Classes {#event-classes}

This table describes each event type and their significance for both event categories.

| Types of Event |                             Account Data                             |                                                                                                                                  Transaction Data                                                                                                                                   |
|----------------|----------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| MODIFIED       | This event indicates one of the 6 monitored fields has been updated. | This event indicates a [transaction status](https://developer.mastercard.com/open-finance-us/documentation/products/manage/transaction-data/understanding-transaction-data/index.md#transaction-status) has changed. Refer to the Transaction Events table for status combinations. |
| DELETED        | This event indicates an account has been deleted.                    | This type of event will **never be sent** for this category.                                                                                                                                                                                                                        |
| CREATED        | This type of event will **never be sent** for this category.         | This event indicates there is a new pending or active transaction record.                                                                                                                                                                                                           |

#### Transaction Events {#transaction-events}

This table describes how the transaction status changes based on transaction events.

| Event Type |                                                   Condition/Trigger                                                    |  Status   |
|------------|------------------------------------------------------------------------------------------------------------------------|-----------|
| Created    | New active transaction is created                                                                                      | `active`  |
| Created    | New pending transaction is created                                                                                     | `pending` |
| Modified   | Transaction is updated from pending/shadow to active                                                                   | `active`  |
| Modified   | Transaction is updated from active to shadow (when it is not found on a subsequent refresh for the same date range)    | `shadow`  |
| Modified   | Transaction is updated from pending to inactive (when it is not found on a subsequent refresh for the same date range) | `deleted` |

## Sample Notifications {#sample-notifications}

### Account Modified {#account-modified}

The following example shows how a typical message body might look for an account modified event:
* JSON
* XML

```JSON
{
   "event": {
      "class": "account",
      "type": "modified",
      "source": "Connect Fix",
      "records": [
         {
            "id": "2055",
            "number": ">XXXX-XXXXXX-32765",
            "name": "Checking",
            "balance": 964.23,
            "type": "checking",
            "aggregationStatusCode": 0,
            "status": "active",
            "customerId": "41442",
            "institutionId": "101732",
            "balanceDate": 1444768982,
            "aggregationSuccessDate": 1444768982,
            "aggregationAttemptDate": 1444768982,
            "createdDate": 1422395818,
            "lastUpdatedDate": 1444768982
         }
      ]
   }
}
```

```XML
<event>
  <class>account</class>
  <type>modified</type>
  <source>Connect Fix</source>
  <records>
    <id>2055</id>
    <number>>XXXX-XXXXXX-32765</number>
    <name>Checking</name>
    <balance>964.23</balance>
    <type>checking</type>
    <aggregationStatusCode>0</aggregationStatusCode>
    <status>active</status>
    <customerId>41442</customerId>
    <institutionId>101732</institutionId>
    <balanceDate>1444768982</balanceDate>
    <aggregationSuccessDate>1444768982</aggregationSuccessDate>
    <aggregationAttemptDate>1444768982</aggregationAttemptDate>
    <createdDate>1422395818</createdDate>
    <lastUpdatedDate>1444768982</lastUpdatedDate>
  </records>
</event>
```

### Account Deleted {#account-deleted}

The following example shows how a typical message body might look for an account delete event:
* JSON
* XML

```JSON
{
   "event": {
      "class": "account",
      "type": "deleted",
      "source": "Connect Fix",
      "records": [
         {
            "id": "2055",
            "number": ">XXXX-XXXXXX-32765",
            "name": "Checking",
            "balance": 964.23,
            "type": "checking",
            "aggregationStatusCode": 0,
            "status": "deleted",
            "customerId": "41442",
            "institutionId": "101732",
            "balanceDate": 1444768982,
            "aggregationSuccessDate": 1444768982,
            "aggregationAttemptDate": 1444768982,
            "createdDate": 1422395818,
            "lastUpdatedDate": 1444768982
         }
      ]
   }
}
```

```XML
<event>
  <class>account</class>
  <type>deleted</type>
  <source>Connect Fix</source>
  <records>
    <id>2055</id>
    <number>>XXXX-XXXXXX-32765</number>
    <name>Checking</name>
    <balance>964.23</balance>
    <type>checking</type>
    <aggregationStatusCode>0</aggregationStatusCode>
    <status>deleted</status>
    <customerId>41442</customerId>
    <institutionId>101732</institutionId>
    <balanceDate>1444768982</balanceDate>
    <aggregationSuccessDate>1444768982</aggregationSuccessDate>
    <aggregationAttemptDate>1444768982</aggregationAttemptDate>
    <createdDate>1422395818</createdDate>
    <lastUpdatedDate>1444768982</lastUpdatedDate>
  </records>
</event>
```

### Transaction Created {#transaction-created}

The following example shows how a typical message body might look for a new pending transaction record:
* JSON
* XML

```JSON
{
  "event": {
    "class": "transaction",
    "type": "modified",
    "records": [
      {
        "id": 7158760954,
        "amount": -42.18,
        "accountId": 7001630128,
        "customerId": 7000224872,
        "status": "created",
        "description": "WALMART SUPERCENTER #2153 MEW YORK NY",
        "uniqueTransactionId": "7158760954-7001630128",
        "memo": "Debit",
        "interestAmount": 0,
        "principalAmount": 0,
        "escrowAmount": 0,
        "postedDate": 1738411200,
        "transactionDate": 1738411200,
        "createdDate": 1738440763,
        "lastUpdatedDate": 1738558241,
        "categorization": {
          "normalizedPayeeName": "Walmart",
          "category": "Shopping",
          "score": 1,
          "bestRepresentation": "WALMART SUPERCENTER MEW YORK NY DEBIT",
          "country": "USA",
          "entityStandardizationConfidenceScore": 96.7
        }
      }
    ]
  }
}
```

```XML
<event>
	<class>transaction</class>
	<type>modified</type>
	<records>
		<id>7158760954</id>
		<amount>-42.18</amount>
		<accountId>7001630128</accountId>
		<customerId>7000224872</customerId>
		<status>created</status>
		<description>WALMART SUPERCENTER #2153 MEW YORK NY</description>
		<uniqueTransactionId>7158760954-7001630128</uniqueTransactionId>
		<memo>Debit</memo>
		<interestAmount>0</interestAmount>
		<principalAmount>0</principalAmount>
		<escrowAmount>0</escrowAmount>
		<postedDate>1738411200</postedDate>
		<transactionDate>1738411200</transactionDate>
		<createdDate>1738440763</createdDate>
		<lastUpdatedDate>1738558241</lastUpdatedDate>
		<categorization>
			<normalizedPayeeName>Walmart</normalizedPayeeName>
			<category>Shopping</category>
			<score>1</score>
			<bestRepresentation>WALMART SUPERCENTER MEW YORK NY DEBIT</bestRepresentation>
			<country>USA</country>
			<entityStandardizationConfidenceScore>96.7</entityStandardizationConfidenceScore>
		</categorization>
	</records>
</event>
```

### Transaction Modified {#transaction-modified}

The following example shows how a typical message body might look for a transaction status change event:
* JSON
* XML

```JSON
{
  "event": {
    "class": "transaction",
    "type": "modified",
    "records": [
      {
        "id": 7158760954,
        "amount": -27.43,
        "accountId": 7001630128,
        "customerId": 7000224872,
        "status": "modified",
        "description": "STARBUCKS STORE 01452 OGDEN UT",
        "uniqueTransactionId": "7158760954-7001630128",
        "memo": "DEBIT",
        "interestAmount": 0,
        "principalAmount": 0,
        "escrowAmount": 0,
        "postedDate": 1738411200,
        "transactionDate": 1738411200,
        "createdDate": 1738440763,
        "lastUpdatedDate": 1738558241,
        "categorization": {
          "normalizedPayeeName": "Starbucks",
          "category": "Coffee Shops",
          "score": 1,
          "bestRepresentation": "STARBUCKS OGDEN UT DEBIT",
          "country": "USA",
          "entityStandardizationConfidenceScore": 97.8
        }
      }
    ]
  }
}
```

```XML
<event>
	<class>transaction</class>
	<type>modified</type>
	<records>
		<id>7158760954</id>
		<amount>-27.43</amount>
		<accountId>7001630128</accountId>
		<customerId>7000224872</customerId>
		<status>modified</status>
		<description>STARBUCKS STORE 01452 OGDEN UT</description>
		<uniqueTransactionId>7158760954-7001630128</uniqueTransactionId>
		<memo>DEBIT</memo>
		<interestAmount>0</interestAmount>
		<principalAmount>0</principalAmount>
		<escrowAmount>0</escrowAmount>
		<postedDate>1738411200</postedDate>
		<transactionDate>1738411200</transactionDate>
		<createdDate>1738440763</createdDate>
		<lastUpdatedDate>1738558241</lastUpdatedDate>
		<categorization>
			<normalizedPayeeName>Starbucks</normalizedPayeeName>
			<category>Coffee Shops</category>
			<score>1</score>
			<bestRepresentation>STARBUCKS OGDEN UT DEBIT</bestRepresentation>
			<country>USA</country>
			<entityStandardizationConfidenceScore>97.8</entityStandardizationConfidenceScore>
		</categorization>
	</records>
</event>
```

### Transaction Deleted {#transaction-deleted}

The following example shows how a typical message body might look when a transaction status has changed to shadow:
* JSON
* XML

```JSON
{
  "event": {
    "class": "transaction",
    "type": "modified",
    "records": [
      {
        "id": 7158760954,
        "amount": -54.27,
        "accountId": 7001630128,
        "customerId": 7000224872,
        "status": "deleted",
        "description": "TRADER JOE'S #0123 HARTFORD CT",
        "uniqueTransactionId": "7158760954-7001630128",
        "memo": "DEBIT",
        "interestAmount": 0,
        "principalAmount": 0,
        "escrowAmount": 0,
        "postedDate": 1771934700,
        "transactionDate": 1771877880,
        "createdDate": 1771877910,
        "lastUpdatedDate": 1771934700,
        "categorization": {
          "normalizedPayeeName": "Trader Joe's",
          "category": "Groceries",
          "score": 1,
          "bestRepresentation": "TRADER JOES HARTFORD CT DEBIT",
          "country": "USA",
          "entityStandardizationConfidenceScore": 93.2
        }
      }
    ]
  }
}
```

```XML
<event>
	<class>transaction</class>
	<type>modified</type>
	<records>
		<id>7158760954</id>
		<amount>-54.27</amount>
		<accountId>7001630128</accountId>
		<customerId>7000224872</customerId>
		<status>deleted</status>
		<description>TRADER JOE'S #0123 HARTFORD CT</description>
		<uniqueTransactionId>7158760954-7001630128</uniqueTransactionId>
		<memo>DEBIT</memo>
		<interestAmount>0</interestAmount>
		<principalAmount>0</principalAmount>
		<escrowAmount>0</escrowAmount>
		<postedDate>1771934700</postedDate>
		<transactionDate>1771877880</transactionDate>
		<createdDate>1771877910</createdDate>
		<lastUpdatedDate>1771934700</lastUpdatedDate>
		<categorization>
			<normalizedPayeeName>Trader Joe's</normalizedPayeeName>
			<category>Groceries</category>
			<score>1</score>
			<bestRepresentation>TRADER JOES HARTFORD CT DEBIT</bestRepresentation>
			<country>USA</country>
			<entityStandardizationConfidenceScore>93.2</entityStandardizationConfidenceScore>
		</categorization>
	</records>
</event> 
```

There are specific fields monitored for TxPUSH notifications. If data in one of these fields changes, a notification will be sent. Data can change in a non-monitored field during refresh, and a TxPUSH notification will not be sent. Due to this, Mastercard recommends a bi-weekly reconciliation of account and transaction data to ensure uniformity between Mastercard's data and a Client's data. If there ever is an instance of a missing TxPUSH event, please submit a [support ticket](https://developer.mastercard.com/open-finance-us/documentation/support/index.md#create-a-support-case-in-scm) for troubleshooting.

|     Data     |               Fields Monitored for TxPUSH Notifications                |
|--------------|------------------------------------------------------------------------|
| Account data | accountNumber, nickname, aggrNickname, balance, status, aggrStatusCode |
| Transactions | status                                                                 |

Clients may opt-in to receiving TxPUSH notifications whenever the `aggregationSuccessDate` is updated, indicating a successful refresh and new data may be available outside of the monitored fields. Reach out to your Client Success Manager if you wish to opt-in.

## Validating a txpush-signature {#validating-a-txpush-signature}

All events contain a txpush-signature to validate the authenticity of the update. If the txpush-signature does not match the expected result, submit a [support ticket](https://developer.mastercard.com/open-finance-us/documentation/support/index.md#create-a-support-case-in-scm) for assistance.

Use the following steps to validate the txpush-signature:

1. Base64 encode the event message's Body (request body).

2. Create a new empty string, known here as the signing string.

3. Append the text "content-type".

4. Append the value of the Content-Type header for the HTTP request (all lower-case). This will depend on the output format that you are using (JSON or XML). For example: `content-typeapplication/json` or `content-typeapplication/xml`.

5. Append the text "host".

6. Append the value of the host from the Header from the HTTP request (all lower-case).

7. Append the Base64-encoded string from step 1 to the end of the signing string.

8. Using HMAC SHA256, create a signature in Base64 format. For this algorithm, the "secret key" is the signingKey from the [Subscribe to TxPush Notifications](https://developer.mastercard.com/open-finance-us/documentation/products/manage/tx-push/index.md#subscribe-to-txpush-notifications) API, and the "value" is the signing string.

9. UrlEncode the resulting Base64 value.

10. Compare the result to the txpush-signature. If the values are the same, the notification is authentic. If the values are not the same, submit a [support ticket](https://developer.mastercard.com/open-finance-us/documentation/support/index.md#create-a-support-case-in-scm).

### Example {#example}

This example shows how to perform these verification steps with the following event message and signing key.

The following shows the header of an event sent to your call back / listener service as XML:

```curl
POST https://domain.example.com/txpush/listener
Content-Type: application/xml
Host: domain.example.com
x-txpush-signature:
Mtbdwo1ZCsmDrcvBkVa8K5LzY9KBPYQ7S44TQdcDLIw%3D
```

The Event Message Body (request body) for this might look similar to the following (this is an XML message for an Account event):

```XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<event>
  <type>modified</type>
  <class>account</class>
  <records>
    <account>
      <id>2055</id>
      ...
    </account>
  </records>
</event>
```

signingKey (given during set-up): `1234567890`

#### Verification Steps {#verification-steps}

* **Step 1:** Base64 encode the event message body (request body):

  `PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8ZXZlbnQ+CiAgPHR5cGU+bW9kaWZpZWQ8L3R5cGU+CiAgPGNsYXNzPmFjY291bnQ8L2NsYXNzPgogIDxyZWNvcmRzPgogICAgPGFjY291bnQ+CiAgICAgIDxpZD4yMDU1PC9pZD4KICAgICAgLi4uCiAgICA8L2FjY291bnQ+CiAgPC9yZWNvcmRzPgo8L2V2ZW50Pg==`
* **Steps 2 to 6**: Create the signing string:

  `content-typeapplication/xmlhostdomain.example.com`
* **Step 7**: Combine the signing string and the Base64 encoded event message body:

  `content-typeapplication/xmlhostdomain.example.comPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8ZXZlbnQ+CiAgPHR5cGU+bW9kaWZpZWQ8L3R5cGU+CiAgPGNsYXNzPmFjY291bnQ8L2NsYXNzPgogIDxyZWNvcmRzPgogICAgPGFjY291bnQ+CiAgICAgIDxpZD4yMDU1PC9pZD4KICAgICAgLi4uCiAgICA8L2FjY291bnQ+CiAgPC9yZWNvcmRzPgo8L2V2ZW50Pg==`
* **Step 8**: Create a signature in Base64 format using HMAC SHA256:

  `Mtbdwo1ZCsmDrcvBkVa8K5LzY9KBPYQ7S44TQdcDLIw=`
* **Step 9**: URL encode the Base64 signature:

  `Mtbdwo1ZCsmDrcvBkVa8K5LzY9KBPYQ7S44TQdcDLIw%3D`
* **Step 10**: Compare the Base64 encoded signature to the txpush-signature:

  The signatures match, so the notification is authentic.
