> ## Documentation Index
> Fetch the complete documentation index at: https://developers.dwolla.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Push to Card

> Learn about Push to Card, Dwolla's instant payout solution that enables real-time fund disbursements directly to debit cards.

## Overview

Push to Card enables instant payouts directly to your customers' debit cards, delivering funds in near real-time (often seconds or within 30 minutes) instead of days. Unlike traditional ACH transfers that require 1-4 business days to complete, Push to Card provides a faster, more convenient payout experience. Payouts are available 24/7 with near real-time confirmation of success or failure.

This capability operates on a fundamentally different model than ACH. Understanding these differences is essential for successful integration, particularly the **good funds model** and **synchronous processing** concepts covered in this guide.

> [!WARNING]
>
> Push to Card is a premium feature available for Dwolla customers. Enabling Push to Card requires additional Dwolla approvals before getting started. Please [contact Sales](https://www.dwolla.com/contact?b=apidocs) or your Relationship Manager for more information.

### Key Benefits

| Benefit | Description |
| - | - |
| **Speed** | Funds arrive in near real-time (often seconds or within 30 minutes) instead of days |
| **Real-time feedback** | Immediate success or failure confirmation |
| **Extended availability** | Payouts available 24/7/365 |
| **Broad coverage** | Works with Visa and Mastercard U.S. debit cards |

### How Push to Card Differs from ACH

The most significant difference between Push to Card and ACH is **speed**. ACH transfers are processed in batches and typically take 1-4 business days to complete, whereas Push to Card delivers funds to a recipient's card in real-time (often seconds or within 30 minutes).

Push to Card also operates on a **good funds model**, meaning funds must be available in your settlement account before initiating a payout. This differs from ACH, where transfers can be initiated while funds are still in transit. The tradeoff is certainty: Push to Card payouts are final and irrevocable once completed.

Finally, Push to Card is available **24/7/365**, while ACH processing is limited to banking business days. This makes Push to Card ideal for time-sensitive disbursements like gig economy payouts, insurance claims, or loan disbursements.

## The Good Funds Model

Push to Card operates on a **good funds model**, which represents a fundamental shift from how ACH transfers work. Understanding this model is critical for implementing Push to Card correctly.

### Core Concept

With ACH, you can initiate a transfer before funds have fully settled. The network processes transactions in batches, and returns may occur days later if there are insufficient funds or other issues.

Push to Card works differently. Because card payouts are **irrevocable** and cannot be recalled once sent, the system requires that funds be fully settled and available **before** a transfer can be initiated. There is no "float" period.

> [!NOTE]
>
> **The Rule:** Money must be settled and available in your settlement account before a Push to Card transfer can be initiated. You cannot initiate a payout with funds that are still pending.

### The Flow: Funding Before Disbursement

The good funds model enforces a strict sequence:

```mermaid theme={"dark"}
flowchart LR
    subgraph step1["Step 1: Funding"]
        A[Your Bank<br/>or Balance]
    end
    
    subgraph step2["Step 2: Hold"]
        B[Settlement Account<br/>Funds settle and<br/>become available]
    end
    
    subgraph step3["Step 3: Disbursement"]
        C[Customer's<br/>Debit Card]
    end
    
    A -->|"ACH, Same-Day ACH,<br/>or RTP*"| B
    B -->|"Push to Card"| C
```

| Step | Action | Description |
| - | - | - |
| 1 | **Funding (Inbound)** | Move funds into your settlement account via ACH, Same-Day ACH, or RTP (from a pre-funded Dwolla balance) |
| 2 | **Hold** | Funds settle and become available in the settlement account |
| 3 | **Disbursement (Outbound)** | Initiate the Push to Card transfer to the customer's debit card |

This model ensures that every Push to Card payout is backed by real, available funds, which removes the risk of overdrafts or failed transactions due to insufficient funds in transit.

## The Settlement Account

To support the good funds model, Push to Card requires a dedicated **settlement account**. This is a custodial bank account at a partner bank (Cross River Bank) used exclusively for card payouts.

### What Is a Settlement Account?

The settlement account serves as the funding source for all Push to Card transfers. Before you can send a payout to a debit card, funds must be present and available (settled) in this account. Think of it as a dedicated "wallet" for card payouts that you pre-fund as needed.

### Configuring Your Settlement Account

Setting up your settlement account is a one-time configuration performed in the Dwolla Dashboard that connects your Dwolla account to the card network infrastructure:

**1. Obtain Settlement Account Details from Checkout.com**

Retrieve the account number and routing number for your CRB settlement account from the Checkout.com Dashboard. These credentials are provided by Checkout.com as part of your Push to Card onboarding.

**2. Configure in the Dwolla Dashboard**

In the Dwolla Dashboard, create your settlement account funding source using the CRB account details from Checkout.com, and add your Checkout.com API credentials (public key and secret key) to establish the connection.

**3. Verify the Configuration**

Retrieve the funding source from the Dwolla API to confirm it includes the `bankUsageType: "card-network"` indicator, which confirms the account is properly configured for Push to Card.

### Identifying the Settlement Account

When you retrieve the settlement account funding source from the API, it includes a `bankUsageType` field that distinguishes it from standard bank accounts:

```bash Retrieve Settlement Account theme={"dark"}
GET https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer your_access_token
```

```json Response theme={"dark"}
{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591"
    },
    "balance": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591/balance"
    }
  },
  "id": "c6161158-5427-4a97-b92b-27532bf49591",
  "status": "unverified",
  "type": "bank",
  "bankAccountType": "checking",
  "name": "Card Network Settlement Account",
  "created": "2025-11-11T17:10:47.298Z",
  "removed": false,
  "channels": [
    "ach",
    "real-time-payments"
  ],
  "bankName": "SANDBOX TEST BANK",
  "bankUsageType": "card-network"
}
```

Use this field to programmatically identify your settlement account when listing funding sources or building account selection interfaces.

## Funding Your Settlement Account

Managing your settlement account requires an ongoing operational workflow to ensure funds are always available for payouts. We recommend establishing a regular **top-up cycle** that includes monitoring, replenishment, and threshold-based alerts.

### The Top-Up Cycle

The top-up cycle is a best practice for maintaining sufficient funds in your settlement account:

1. **Monitor**: Regularly check your settlement account balance via the Dwolla Dashboard or API
2. **Set thresholds**: Define minimum balance thresholds that trigger replenishment
3. **Replenish**: Transfer funds into the settlement account before the balance runs low
4. **Repeat**: Establish a regular cadence (daily, weekly) based on your payout volume

> [!TIP]
>
> For high-volume payout operations, consider automating the top-up cycle. Implement balance monitoring that triggers automatic transfers when the settlement account falls below a defined threshold.

### Checking the Balance

Before initiating a payout, check the available balance in your settlement account. You can do this via the Dwolla Dashboard or programmatically through the API.

```bash Check Settlement Balance theme={"dark"}
GET https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591/balance
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer your_access_token
```

```json Response theme={"dark"}
{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591/balance"
    },
    "funding-source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591"
    }
  },
  "balance": {
    "value": "10000.00",
    "currency": "USD"
  },
  "total": {
    "value": "10000.00",
    "currency": "USD"
  },
  "lastUpdated": "2025-12-10T14:28:12.679Z"
}
```

### Adding Funds (Top-Up)

When additional funds are needed, transfer money into the settlement account from your Master Balance or an external bank account. You can use standard ACH, Same-Day ACH, or RTP based on how quickly you need the funds available.

| Transfer Method | Settlement Time | Source | Use Case |
| - | - | - | - |
| Standard ACH | 3-4 business days | Bank account or Balance | Regular, planned top-ups |
| Same-Day ACH | Same business day | Bank account or Balance | Faster replenishment |
| RTP | Minutes | Pre-funded Balance only | Urgent, on-demand funding |

> [!NOTE]
>
> RTP transfers to the settlement account require a pre-funded [Dwolla Balance](https://developers.dwolla.com/docs/balance-funding-source.md) as the source. RTP cannot be initiated directly from an external bank account.

```bash Top-Up Settlement Account theme={"dark"}
POST https://api-sandbox.dwolla.com/transfers
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer your_access_token

{
  "_links": {
    "source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/your-balance-or-bank-id"
    },
    "destination": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591"
    }
  },
  "amount": {
    "currency": "USD",
    "value": "5000.00"
  }
}

HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/transfers/d76265cd-0951-e511-80da-0aa34a9b2388
```

## Initiating a Push to Card Payout

When you're ready to send funds to a customer's debit card, follow this workflow to ensure successful payouts.

### Recommended Payout Flow

Before creating a transfer, verify that sufficient funds are available in your settlement account:

```mermaid theme={"dark"}
flowchart TD
    A[Payout Request] --> B{Check Settlement<br/>Account Balance}
    B -->|Sufficient funds| C[Create Push to Card<br/>Transfer]
    B -->|Insufficient funds| D{Handle Shortage}
    D -->|Option 1| E[Return error to<br/>calling application]
    D -->|Option 2| F[Notify operations<br/>team]
    D -->|Option 3| G[Initiate top-up<br/>and queue payout]
    C --> H[Transfer Created<br/>with pending status]
    H --> I[Await webhook for<br/>final status]
```

This pre-flight balance check prevents failed transfers due to insufficient funds and allows you to handle shortages gracefully. You can return an error to the calling application, alert your operations team, or automatically initiate a top-up.

### Creating the Transfer

Once funds are available in the settlement account, initiate the Push to Card transfer. The settlement account serves as the source, and the Customer's card funding source serves as the destination.

```bash Push to Card Transfer theme={"dark"}
POST https://api-sandbox.dwolla.com/transfers
Content-Type: application/vnd.dwolla.v1.hal+json
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer your_access_token

{
  "_links": {
    "source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591"
    },
    "destination": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/12fb2f3c-39c7-40cf-99e2-b0311ba39261"
    }
  },
  "amount": {
    "currency": "USD",
    "value": "100.00"
  }
}

HTTP/1.1 201 Created
Location: https://api-sandbox.dwolla.com/transfers/e5b8223f-08f7-4a7e-b952-88a773c0df61
```

```ruby push_to_card_transfer.rb theme={"dark"}
# Settlement account (source) and card funding source (destination)
settlement_account = 'https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591'
card_funding_source = 'https://api-sandbox.dwolla.com/funding-sources/12fb2f3c-39c7-40cf-99e2-b0311ba39261'

request_body = {
  _links: {
    source: {
      href: settlement_account
    },
    destination: {
      href: card_funding_source
    }
  },
  amount: {
    currency: 'USD',
    value: '100.00'
  }
}

# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby
transfer = app_token.post 'transfers', request_body
transfer.response_headers[:location]
# => "https://api-sandbox.dwolla.com/transfers/e5b8223f-08f7-4a7e-b952-88a773c0df61"
```

```javascript pushToCardTransfer.js theme={"dark"}
// Settlement account (source) and card funding source (destination)
const settlementAccount =
  "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591";
const cardFundingSource =
  "https://api-sandbox.dwolla.com/funding-sources/12fb2f3c-39c7-40cf-99e2-b0311ba39261";

const requestBody = {
  _links: {
    source: {
      href: settlementAccount,
    },
    destination: {
      href: cardFundingSource,
    },
  },
  amount: {
    currency: "USD",
    value: "100.00",
  },
};

// Using dwolla-v2 - https://github.com/Dwolla/dwolla-v2-node
dwolla.post("transfers", requestBody).then((res) => res.headers.get("location"));
// => "https://api-sandbox.dwolla.com/transfers/e5b8223f-08f7-4a7e-b952-88a773c0df61"
```

```python push_to_card_transfer.py theme={"dark"}
# Settlement account (source) and card funding source (destination)
settlement_account = 'https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591'
card_funding_source = 'https://api-sandbox.dwolla.com/funding-sources/12fb2f3c-39c7-40cf-99e2-b0311ba39261'

request_body = {
    '_links': {
        'source': {
            'href': settlement_account
        },
        'destination': {
            'href': card_funding_source
        }
    },
    'amount': {
        'currency': 'USD',
        'value': '100.00'
    }
}

# Using dwollav2 - https://github.com/Dwolla/dwolla-v2-python
transfer = app_token.post('transfers', request_body)
transfer.headers['location']
# => 'https://api-sandbox.dwolla.com/transfers/e5b8223f-08f7-4a7e-b952-88a773c0df61'
```

When the transfer is created successfully, it enters a `pending` status. The final outcome (`processed` or `failed`) is delivered via webhook.

> [!WARNING]
>
> **Push to Card transfers cannot be cancelled.** Unlike ACH transfers, which can be cancelled while in `pending` status, Push to Card payouts are irrevocable once initiated. The transfer is submitted to the card network immediately upon creation, and there is no window to cancel or recall the funds. Ensure all payout details are correct before creating the transfer.

## API Behavior: Transfer Lifecycle

Understanding the Push to Card transfer lifecycle helps you build robust integrations that handle all possible outcomes.

### ACH Behavior (Comparison)

With ACH transfers, the API returns a `201 Created` response when the transfer is accepted for processing. The transfer enters a `pending` status, and actual success or failure is communicated **days later** via webhooks when the bank processes the transaction.

```
Request → 201 Created (pending) → [Days pass] → Webhook (processed/failed)
```

### Push to Card Behavior

Push to Card transfers are created synchronously with a `pending` status. The transfer is then submitted to the card network, and the final outcome (`processed` or `failed`) is delivered via webhook. This typically occurs within minutes rather than days.

```
Request → 201 Created (pending) → [Minutes pass] → Webhook (processed/failed)
```

While the initial transfer creation is synchronous, the final approval or decline from the card network is communicated asynchronously through webhooks. This means your application should:

1. Handle the `201 Created` response to confirm the transfer was accepted
2. Listen for `card_transfer_completed`/`customer_card_transfer_completed` or `card_transfer_failed`/`customer_card_transfer_failed` webhooks to determine the final outcome
3. Update your UI or notify users based on the webhook status

### Error Handling

Validation errors and some failure scenarios are returned immediately during transfer creation. Common errors include:

| HTTP Status | Scenario | Example Error |
| - | - | - |
| 400 | Card used as source | Cards cannot be used as a source for transfers |
| 400 | Invalid source | Source funding source does not support card payouts |
| 400 | Invalid destination | Destination funding source is removed or does not exist |

> [accordion] Card Used as Source
>
> Returned when attempting to use a card funding source as the source of a transfer. Cards can only receive funds via Push to Card; they cannot be debited.
>
> > [!NOTE]
> >
> > Card payouts require the source funding source to have `bankUsageType: "card-network"`. This indicates it is a properly configured settlement account. See [The Settlement Account](#the-settlement-account) for configuration details.
>
> ```json theme={"dark"}
> {
>   "code": "ValidationError",
>   "message": "Validation error(s) present. See embedded errors list for more details.",
>   "_embedded": {
>     "errors": [
>       {
>         "code": "NotAllowed",
>         "message": "Cards cannot be used as a source for transfers.",
>         "path": "/_links/source/href",
>         "_links": {}
>       }
>     ]
>   }
> }
> ```

> [accordion] Invalid Source
>
> Returned when the source funding source is not configured as a settlement account with `bankUsageType: "card-network"`.
>
> ```json theme={"dark"}
> {
>   "code": "ValidationError",
>   "message": "Validation error(s) present. See embedded errors list for more details.",
>   "_embedded": {
>     "errors": [
>       {
>         "code": "NotAllowed",
>         "message": "Source funding source does not support card payouts.",
>         "path": "/_links/source/href"
>       }
>     ]
>   }
> }
> ```

> [accordion] Invalid Destination
>
> Returned when the destination funding source has been removed or does not exist.
>
> ```json theme={"dark"}
> {
>   "code": "ValidationError",
>   "message": "Validation error(s) present. See embedded errors list for more details.",
>   "_embedded": {
>     "errors": [
>       {
>         "code": "Invalid",
>         "message": "Destination funding source is either removed or does not exist.",
>         "path": "/_links/destination/href"
>       }
>     ]
>   }
> }
> ```

> [!NOTE]
>
> Card network declines (e.g., card closed, not eligible for credits) are communicated via the `card_transfer_failed` webhook rather than as immediate HTTP errors. Always implement webhook handling to capture these outcomes.

### Retrieving Transfer Failure Details

When a Push to Card transfer fails after creation, the transfer response includes a `failure` link. Follow this link to [retrieve the transfer failure reason](https://developers.dwolla.com/docs/api-reference/transfers/retrieve-a-transfer-failure-reason.md) and get detailed information about why the payout failed.

#### Failed Transfer Response

When you retrieve a failed transfer, the response includes a `failure` link in the `_links` object:

```bash Retrieve Failed Transfer theme={"dark"}
GET https://api-sandbox.dwolla.com/transfers/a5fc2522-3414-4cce-a965-de142b7e89c9
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer your_access_token
```

```json Response theme={"dark"}
{
  "_links": {
    "failure": {
      "href": "https://api-sandbox.dwolla.com/transfers/a5fc2522-3414-4cce-a965-de142b7e89c9/failure",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "failure"
    },
    "source": {
      "href": "https://api-sandbox.dwolla.com/accounts/d3517b45-7152-4714-8e24-d13dab5d10ac",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "account"
    },
    "destination-funding-source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/5154b24b-4278-4784-aac2-e431f0f8824f",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    },
    "self": {
      "href": "https://api-sandbox.dwolla.com/transfers/a5fc2522-3414-4cce-a965-de142b7e89c9",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "transfer"
    },
    "source-funding-source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/c6161158-5427-4a97-b92b-27532bf49591",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    },
    "destination": {
      "href": "https://api-sandbox.dwolla.com/customers/568cb344-6232-4bd4-b669-ebb1bd4ecb78",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "customer"
    }
  },
  "id": "a5fc2522-3414-4cce-a965-de142b7e89c9",
  "status": "failed",
  "amount": {
    "value": "5000.01",
    "currency": "USD"
  },
  "created": "2025-12-23T20:15:10.687Z",
  "metadata": {
    "key": "master",
    "orderId": "12345"
  },
  "correlationId": "8a2cdc8d-629d-4a24-98ac-40b735229fe2"
}
```

#### Retrieve the Failure Reason

Use the `failure` link from the transfer response to get the specific failure code and description:

```bash Retrieve Failure Reason theme={"dark"}
GET https://api-sandbox.dwolla.com/transfers/a5fc2522-3414-4cce-a965-de142b7e89c9/failure
Accept: application/vnd.dwolla.v1.hal+json
Authorization: Bearer your_access_token
```

```json Response theme={"dark"}
{
  "_links": {
    "self": {
      "href": "https://api-sandbox.dwolla.com/transfers/a5fc2522-3414-4cce-a965-de142b7e89c9/failure",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "failure"
    },
    "failed-funding-source": {
      "href": "https://api-sandbox.dwolla.com/funding-sources/5154b24b-4278-4784-aac2-e431f0f8824f",
      "type": "application/vnd.dwolla.v1.hal+json",
      "resource-type": "funding-source"
    }
  },
  "code": "50003",
  "description": "Balance reservation insufficient funds",
  "created": "2025-12-23T20:15:27.392Z"
}
```

#### Push to Card Failure Codes

The following failure codes are specific to Push to Card transfers:

| Code | Description | Explanation |
| - | - | - |
| 50001 | Compliance error | The transfer failed due to a compliance-related issue |
| 50002 | Sanction screening failure | The transfer was blocked due to sanction screening. You can reduce how often cards are flagged for screening by supplying the optional [cardholder identity fields](https://developers.dwolla.com/docs/adding-a-debit-card.md#cardholder-identity-fields) when you create or update a card funding source. |
| 50003 | Balance reservation insufficient | The settlement account does not have sufficient available balance to cover the payout amount |

> [!TIP]
>
> To avoid `50003` errors, always check your settlement account balance before initiating a payout. See [Checking the Balance](#checking-the-balance) for details.

## Webhook Events

Push to Card introduces new webhook events specifically for card funding sources and card transfers. Subscribe to these events to track the lifecycle of cards and payouts in your application.

### Card Funding Source Events

| Event Topic | Description |
| - | - |
| `customer_card_funding_source_added` | Sent when a card funding source is created for a Customer |
| `customer_card_funding_source_removed` | Sent when a card funding source is removed from a Customer |

### Card Transfer Events

Card transfers emit events at the account level and the customer level, depending on the parties involved in the transfer.

| Event Topic | Description |
| - | - |
| `card_transfer_created` | Sent when a Push to Card transfer is created |
| `card_transfer_completed` | Sent when the transfer completes successfully (`processed` status) |
| `card_transfer_failed` | Sent when the transfer fails (`failed` status) |
| `customer_card_transfer_created` | Sent when a Push to Card transfer is created for a Customer |
| `customer_card_transfer_completed` | Sent when a Customer's card transfer completes successfully |
| `customer_card_transfer_failed` | Sent when a Customer's card transfer fails |

> [!NOTE]
>
> The `card_transfer_completed` and `card_transfer_failed` webhooks are essential for determining the final outcome of a payout. Always implement handlers for these events to update your application state and notify users.

## Next Steps

Now that you understand how Push to Card works, you're ready to start building your integration.

> [!TIP]
>
> Check out our [Push to Card sample application](https://github.com/Dwolla/integration-examples/tree/main/packages/push-to-card/checkout) for a complete working example of the add debit card and payout flow.

> [card] [Adding a Debit Card](https://developers.dwolla.com/docs/adding-a-debit-card.md)
>
> Learn how to add debit cards as funding sources for Push to Card payouts

> [card] [Transfer Processing Times](https://developers.dwolla.com/docs/transfer-processing-times.md)
>
> Compare processing times across all payment methods


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.