Instinctively access money from your customers by pulling funds from their cards.

With pull from card transfers, Moov supports instant account funding and account-to-account transfers using supported Visa and Mastercard debit cards, available 24/7/365. Pull from card is available for customers that are chartered financial institutions.

## Use cases

Pull transfers, or account funding transactions, facilitate the movement of funds from a supported debit or prepaid card to an external account owned by the cardholder. To use pull transfers, merchants are required to be U.S. regulated financial institutions. These transactions are ideal for:

- **Initial account funding**: Quickly deposit funds to newly opened accounts.
- **External transfers**: Move money from accounts held at other financial institutions.

Currently, pull from card transactions cannot be used for peer-to-peer (P2P) transfers.

Within the Moov platform, this payment type is modeled as a transfer from an individual's linked debit or prepaid card to the Moov wallet of the financial institution external account. When initiating a transaction, the following needs to be set:

- **Source:** Individual’s debit or prepaid card (Visa and Mastercard only).
- **Destination:** Financial institution’s Moov wallet.

The destination account requires the `wallet` and `collect-funds` [capabilities](https://docs.moov.io/guides/accounts/capabilities/).

## Determine support for pull from card

Ensure you have linked a card on the account. The simplest way to securely link a card is by using the [card link Drop](https://docs.moov.io/moovjs/drops/card-link/), a prebuilt UI component for embedding card-based payments. If you've provided proof of PCI compliance, you also have the option to link a card using the `POST` link a card [endpoint](https://docs.moov.io/api/sources/cards/create/).

When linking a card, ensure that the Moov account is created with **the same name as the cardholder’s name** on the linked card. You will receive a `400` response during transfer creation if the names do not match.

Moov strongly recommends using the `X-Wait-For` header in the request to receive a synchronous response. This includes the rail response and newly created payment methods. If you omit the `X-Wait-For` header, you'll get an asynchronous response and need to call the list payment methods `GET` [endpoint](https://docs.moov.io/api/sources/payment-methods/list/). You can also subscribe to [webhooks](https://docs.moov.io/guides/webhooks/webhook-events/#payment-methods) and wait for the new payment methods to be available for use.

Once you’ve linked a card, use the `GET` [endpoint](https://docs.moov.io/api/sources/cards/get/) and check the `domesticPullfromCard` field in the response to see if `pull-from-card` is supported. The `domesticPullfromCard` field will show one of the following:

| Eligibility | Description |
| --- | --- |
| `supported` | Funds will be available to the destination upon authorization |
| `not-supported` | This card is ineligible for `pull-from-card` payments. Contact your issuer for more details |
| `unknown` | Eligibility has not been checked or is unknown |

### Ask

```zsh
curl -X GET "https://api.moov.io/accounts/{accountID}/cards" \
  -H 'Authorization: Bearer {token}' \
```

### Ask

```go
mc, _ := moov.NewClient()

var accountID string
var cardID string

mc.GetCard(ctx, accountID, cardID)
```

To bolster fraud prevention controls, Moov has taken steps to verify the card’s account ownership. The card verification process will match the existing `cardVerification` object's `addressLine1`, `postalCode`, and `cvv` between the Moov account and the card network in the response:

### Ask

```json
{
  "cardVerification": {
    "addressLine1": "match",
    "postalCode": "match",
    "cvv": "match"
  }
}
```

Additionally, Moov supports Visa’s [Account Name Inquiry (ANI)](https://usa.visa.com/content/dam/VCOM/regional/na/us/support-legal/documents/account-name-inquiry-onesheet-merchant-version.pdf). ANI provides a way to check that names provided on the linked card match the names held on file with the issuer. This optional tool serves to enhance cardholder verification.

To submit a name to Visa's ANI, supply the `holderName` and set `verifyName` to **true** when making a call to the card link `POST` [endpoint](https://docs.moov.io/api/sources/cards/create/) or `PATCH` [endpoint](https://docs.moov.io/api/sources/cards/update/). The response will show a match status for each of the names on file with the issuer:

### Ask

```json
{
  "cardVerification": {
    "fullName": "match", // noMatch, match, partialMatch, notChecked
    "firstName": "match", // noMatch, match, partialMatch, notChecked
    "middleName": "noMatch", // noMatch, match, partialMatch, notChecked
    "lastName": "match" // noMatch, match, partialMatch, notChecked
  }
}
```

**The verification process is crucial in reducing the risk of fraudulent activities and ensuring cards are linked to the rightful owner. If these requirements are not met, the card will be ineligible for pull from card transactions.** You can find example name verification scenarios in our [test mode data](https://docs.moov.io/guides/developer-tools/test-data/#name-verification) reference.

## Implement pull from card

You can simulate pull from card transfers in test mode using [specific test cards](https://docs.moov.io/guides/developer-tools/test-data/#push-pull-from-card).

The `pull-from-card` payment method becomes available when the following criteria are met:

- The linked card is `supported`.
- The linked card meets verification requirements.
- Moov has approved the account for pull from card transfers.

Moov has a platform limit of $10,000 per pull from card transaction. Additionally, the merchant must pay for the pull from card transaction. The merchant **cannot** surcharge the end user.

### Initiate the transfer

A pull transfer can be created when the source is a sender with a linked card with the transfers capability and the `destination` is a Moov wallet with `collect-funds` capability.

In the response, check the `domesticPullFromCard` field to determine if the card supports pull from card transactions. Possible values are `supported`, `not-supported`, or `unknown`.

### Ask

```zsh
curl -X GET "https://api.moov.io/transfers" \
  -H 'Authorization: Bearer {token}' \
  -H "Origin: https://api.moov.io" \
  -H "X-Wait-For: rail-response" \
  --data-raw '{
  "source": {
    # Pull from card
    "paymentMethodID": "string"
  },
  "destination": {
    # Moov wallet
    "paymentMethodID": "string"
  },
  "amount": {
    "value": 10000,
    "currency": "USD"
  },
  "description": "Account funding example"
}'\
```

### Ask

```go
mc, _ := moov.NewClient()

var accountID string

mc.CreateTransfer(ctx, accountID, moov.CreateTransfer{
  Amount: moov.Amount{
    Currency: "USD",
    Value:    97, // $0.97
  },
  Source: moov.CreateTransfer_Source{
    // Pull from card
    PaymentMethodID: "string",
    CardDetails: &moov.CreateTransfer_CardDetailsSource{
      DynamicDescriptor: "Pull transfer",
    },
  },
  Destination: moov.CreateTransfer_Destination{
    // Moov wallet
    PaymentMethodID: "string",
  },
  FacilitatorFee: moov.CreateTransfer_FacilitatorFee{
    Total: moov.PtrOf(int64(2)), // $0.02
  },
  Description: "Account funding example",
})
```

### Track transfer status

To track the transfer status, view `destination.cardDetails` using the transfers `GET` [endpoint](https://docs.moov.io/api/money-movement/transfers/get/):

| Status | Description |
| --- | --- |
| `initiated` | Transaction is created and awaiting authorization |
| `failed` | Issuer declined or there was error with processing |
| `completed` | Authorization request was successful and Issuer approved the transaction |

### Refund status

In the event of an error, pull from card transfers can be refunded. The table below lists the possible refund statuses.

| Status | Description |
| --- | --- |
| `confirmed` | Authorization request was successful and the issuer has approved the transaction |
| `pending` | The refund is in progress but not yet completed |
| `completed` | The card network has settled the transaction and the funds should be available in the customer’s account |
| `failed` | Issuer declined, or there was an error with processing |

## Set up recurring transfers

Using the `transactionSource` parameter in `source.cardDetails` to set up recurring payments. Mark the initial transaction as `first-recurring` and subsequent transactions as `recurring`.

### Ask

```json
{
  "source": {
    "cardDetails": {
      "dynamicDescriptor": "WhlBdy Monthly",
      "transactionSource": "first-recurring"
    },
  }
}
```

### Ask

```json
{
  "source": {
    "cardDetails": {
      "dynamicDescriptor": "WhlBdy Monthly",
      "transactionSource": "recurring"
    },
  }
}
```

For more details, see our [recurring payments](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/recurring-payments/) guide.

## Transfer & velocity limits

There are limits on the amount a card `fingerprint` can send within a specified time. The following limits are for Visa and Mastercard.

| Limit type | Maximum limit |
| --- | --- |
| Amount | $10,000 |
| 1-day velocity | $10,000 |
| 7-day velocity | $25,000 |
| 30-day velocity | $50,000 |

### Error responses

**Amount limit:** If you have exceeded the amount limit, you'll receive a `400` error response. You can retry the transfer with a lower amount.

**Velocity limits**: If you have exceeded the velocity limits, pull from card transfers will fail. The transfer status will be `failed` and the failure reason will be `rejected-high-risk`.

**Issuer limits:** If you have exceeded issuer limits, the transfer status will be `failed` and the failure reason will be `source-payment-error`. American Express transactions less than $1 will also result in a payment error. Contact the issuer if you require guidance on specific issuer limits.

The specific transaction decline code can be found in `cardDetails.failureCode` using the retrieve a transfer [endpoint](https://docs.moov.io/api/money-movement/transfers/) or the list transfers [endpoint](https://docs.moov.io/api/money-movement/transfers/get/).

## Disputes

You can receive notifications on disputes by subscribing to the `dispute.created` and `dispute.updated` [webhook events](https://docs.moov.io/guides/webhooks/webhook-events/#disputes). Alternatively, you can use the disputes list `GET` [endpoint](https://docs.moov.io/api/money-movement/disputes/list/) to pull a list of disputes on a recurring schedule.

For more details on the disputes lifecycle, see our [disputes guide](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/disputes/).  
Pull from card disputes can be tested in [test mode](https://docs.moov.io/guides/developer-tools/test-data/#disputes).
