> ## Documentation Index
> Fetch the complete documentation index at: https://hifi-oa-push-to-cards.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Push to card

> Register a card, send a payout, and track settlement.

**Time to complete:** 10-15 minutes

<Note>
  This guide uses the v3 API (`https://sandbox.hifibridge.com/v3`). Sandbox
  transactions are simulated and do not move real funds.
</Note>

## Overview

With HIFI Push to card, you can convert stablecoins into fiat and deliver funds to an eligible recipient card.

The workflow has three steps:

<Steps>
  <Step title="Register card">
    Create a counterparty for the recipient, add their card, and save the
    returned `externalCardId`.
  </Step>

  <Step title="Send payout">
    Create a push-to-card offramp with `destination.externalCardId`, review the
    quote, and accept it before expiration.
  </Step>

  <Step title="Track payment">
    Use webhooks or the retrieve endpoint to follow the payment through card
    payout processing.
  </Step>
</Steps>

## Prerequisites

Before you start, make sure you have:

* API keys from the Dashboard
* A verified HIFI user with KYC or KYB approved
* A funded HIFI or external wallet with USDC
* The recipient's eligible card details

<Info>
  HIFI Push to card currently supports payouts to Visa cards globally through
  Visa Direct.
</Info>

For user onboarding, use a [KYC Link](/docs/features/kyc-links) or the API flow described in [Quickstart](/docs/guides/quickstart) and [Users](/docs/users/overview).

## Transaction Limits

The same limits apply to domestic and cross-border payouts, and are enforced separately per sender and per recipient.

| Frequency | Max transactions | Max total amount |
| :-------- | :--------------- | :--------------- |
| Daily     | 30               | \$50,000         |
| Weekly    | 50               | \$100,000        |
| Monthly   | 150              | \$200,000        |

Each individual push-to-card payout can be up to \$15,000.

## Register Card

Register the recipient card once, then reuse the returned `externalCardId` for future push-to-card payouts to that card.

### Create Counterparty

Create a counterparty for the recipient under the verified user. External card counterparties require `phoneNumber`, `email`, and `address`.

```bash theme={null}
curl -X POST "https://sandbox.hifibridge.com/v3/users/usr_abc123/counter-parties" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "individual",
    "firstName": "Jane",
    "lastName": "Doe",
    "phoneNumber": "+14155550101",
    "email": "jane@example.com",
    "address": {
      "addressLine1": "456 Market St",
      "city": "San Francisco",
      "stateProvinceRegion": "CA",
      "postalCode": "94105",
      "country": "USA"
    }
  }'
```

<Accordion title="Response">
  ```json theme={null}
  {
    "id": "cpty_abc123",
    "userId": "usr_abc123",
    "type": "INDIVIDUAL",
    "firstName": "Jane",
    "lastName": "Doe",
    "phoneNumber": "******0101",
    "email": "jane@example.com",
    "address": {
      "addressLine1": "456 Market St",
      "city": "San Francisco",
      "stateProvinceRegion": "CA",
      "postalCode": "94105",
      "country": "USA"
    },
    "status": "ACTIVE",
    "createdAt": "2026-07-14T19:00:00.000Z",
    "updatedAt": "2026-07-14T19:00:00.000Z"
  }
  ```
</Accordion>

Save the returned counterparty `id`. You will use it in the external card path.

### Create External Card

Create an external card for the counterparty. HIFI tokenizes the card with the provider and returns an external card ID.

```bash theme={null}
curl -X POST "https://sandbox.hifibridge.com/v3/users/usr_abc123/counter-parties/cpty_abc123/external-cards" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Jane",
    "lastName": "Doe",
    "cardNumber": "4111111111111111",
    "expiryMonth": "12",
    "expiryYear": "29",
    "cvv": "123"
  }'
```

<Accordion title="Response">
  ```json theme={null}
  {
    "id": "extcrd_abc123",
    "userId": "usr_abc123",
    "counterPartyId": "cpty_abc123",
    "firstName": "Jane",
    "lastName": "Doe",
    "cardNumber": "************1111",
    "expiryMonth": "12",
    "expiryYear": "29",
    "status": "ACTIVE",
    "createdAt": "2026-07-14T19:00:00.000Z",
    "updatedAt": "2026-07-14T19:00:00.000Z"
  }
  ```
</Accordion>

<ResponseField name="id" type="string">
  External card ID. Use this value as `destination.externalCardId` when sending the payout.
</ResponseField>

<ResponseField name="status" type="string">
  Card status. `ACTIVE` means the card can be used as an offramp destination.
</ResponseField>

<Warning>
  Card details are submitted once to create a provider token. Store the returned
  `id`, not the raw card number.
</Warning>

## Send Payout

Send a payout by creating an offramp quote to the registered card, then accepting the quote.

### Create Payout Quote

Create an offramp with `destination.externalCardId`. Provide exactly one source wallet identifier (`source.walletId` or `source.externalWalletId`) and exactly one amount (`source.amount` or `destination.amount`).

```bash theme={null}
curl -X POST "https://sandbox.hifibridge.com/v3/offramps" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "requestId": "b08e27be-c086-4b84-a321-307ed9f265e1",
    "source": {
      "walletId": "wlt_abc123",
      "currency": "USDC",
      "amount": 100
    },
    "destination": {
      "externalCardId": "extcrd_abc123",
      "currency": "USD"
    },
    "description": "Card payout for order 1001"
  }'
```

<Accordion title="Response">
  ```json theme={null}
  {
    "id": "offramp_abc123",
    "requestId": "b08e27be-c086-4b84-a321-307ed9f265e1",
    "status": "OPEN_QUOTE",
    "source": {
      "chain": "POLYGON",
      "amount": "100",
      "currency": "USDC",
      "userId": "usr_abc123",
      "walletId": "wlt_abc123",
      "walletAddress": "0x1234567890abcdef1234567890abcdef12345678"
    },
    "destination": {
      "amount": "100",
      "currency": "USD",
      "userId": "usr_abc123",
      "externalCardId": "extcrd_abc123"
    },
    "quote": {
      "sendGross": {
        "amount": "100",
        "currency": "USDC"
      },
      "receiveNet": {
        "amount": "100",
        "currency": "USD"
      },
      "rate": "1",
      "expiresAt": "2026-07-14T19:10:00.000Z"
    },
    "receipt": {
      "transactionHash": null,
      "paymentTracking": null
    },
    "depositInfo": []
  }
  ```
</Accordion>

<ResponseField name="id" type="string">
  Offramp ID. Use this value to accept the quote and track the payment.
</ResponseField>

<ResponseField name="status" type="string">
  `OPEN_QUOTE` means the quote is ready to review and accept.
</ResponseField>

<ResponseField name="destination.externalCardId" type="string">
  The registered card destination for the push-to-card payout.
</ResponseField>

<ResponseField name="quote.expiresAt" type="string">
  Quote expiration timestamp. Accept the quote before this time.
</ResponseField>

### Accept Quote

After reviewing the quote, accept it to execute the payout.

```bash theme={null}
curl -X POST "https://sandbox.hifibridge.com/v3/offramps/offramp_abc123/quote/accept" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

When the quote is accepted, HIFI starts the transfer flow.

<Accordion title="Response">
  ```json theme={null}
  {
    "id": "offramp_abc123",
    "requestId": "b08e27be-c086-4b84-a321-307ed9f265e1",
    "status": "IN_REVIEW",
    "source": {
      "amount": "100",
      "currency": "USDC",
      "walletId": "wlt_abc123"
    },
    "destination": {
      "amount": "100",
      "currency": "USD",
      "externalCardId": "extcrd_abc123"
    },
    "receipt": {
      "transactionHash": null,
      "paymentTracking": null
    }
  }
  ```
</Accordion>

## Track Payment

Track the payment with webhooks for real-time updates or poll the retrieve endpoint with the offramp ID.

### Listen for Webhooks

Subscribe to [Offramp events](/docs/webhooks/offramp-events) and handle `OFFRAMP.STATUS.*` events. Use `eventAction` or the transfer status in the event data to update the payment in your system.

### Retrieve Payment Status

Use the offramp ID returned when you created the payout quote.

```bash theme={null}
curl -X GET "https://sandbox.hifibridge.com/v3/offramps/offramp_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Common statuses include:

| Status           | Meaning                                                             |
| :--------------- | :------------------------------------------------------------------ |
| `OPEN_QUOTE`     | The quote was created and is waiting to be accepted.                |
| `AWAITING_FUNDS` | HIFI is waiting for funds from an external wallet source.           |
| `IN_REVIEW`      | Funds are in process and provider review or settlement is underway. |
| `FIAT_INITIATED` | The card payout has been initiated.                                 |
| `FIAT_PENDING`   | The card payout is processing.                                      |
| `COMPLETED`      | The push-to-card payout completed successfully.                     |
| `FIAT_FAILED`    | The card payout failed.                                             |

<ResponseField name="receipt.transactionHash" type="string">
  Stablecoin conversion transaction hash, when available.
</ResponseField>

<ResponseField name="receipt.paymentTracking" type="object">
  Fiat payout tracking details, when available from the card payout provider.
</ResponseField>

## Notes

* Use `destination.externalCardId` for push-to-card offramps. Do not include `destination.externalAccountId` in the same request.
* Push-to-card currently uses USD card payouts.
* External cards must be `ACTIVE`.
* The counterparty attached to the card must remain active.
* `requestId` is idempotent for creating offramps. Reusing the same `requestId` for a different transfer will return a conflict.
