# Stablecoin-backed cards for Bridge, Privy, or third-party wallets

Integrate Stripe Issuing with Bridge to build a stablecoin-backed consumer or commercial card program.

The Stripe Issuing integration with the Bridge stablecoin infrastructure lets you build a card program funded by any non-custodial, Bridge, or Privy wallet. This guide shows you how to connect your Stripe account to Bridge to issue debit cards that spend just-in-time from a stablecoin balance.

## Onboard

When launching a card program with Bridge and Stripe Issuing, Stripe outlines the end-to-end requirements and create an individualized onboarding approach to the program design of your business. We’ll match you with a dedicated implementation expert who manages our requirements across our BIN sponsor, networks, and other partners to help you go live.

| Onboarding step          | Number of users                | Timeline                              |
| ------------------------ | ------------------------------ | ------------------------------------- |
| First onboarding meeting | 0 (sandbox only)               | After signing addendum                |
| Production testing       | 10 (internal employees)        | About 2 weeks after onboarding starts |
| Live launch              | Unlimited (external customers) | 6-8 weeks after the onboarding starts |

Onboarding typically takes 6-8 weeks from the start of onboarding to the actual onboarding of external customers. After an initial call to get onboarding started, Stripe shares an Asana board outlining each of the required documents with required deadlines for your desired launch date. Upload the required documents to your Asana board so Stripe can review and provision the full launch approval.

In parallel, you’ll work through the technical integration across supported chains and funds flows outlined below.

## Technical integration APIs

This integration requires interaction with both the Bridge APIs and the Stripe APIs. The table below shows where to use each API. The integration guide below provides each step of the integration.

| Integration step                     | API              |
| ------------------------------------ | ---------------- |
| Create customer                      | Bridge API       |
| Create and manage cards              | Stripe API       |
| Card spend APIs and webhooks         | Stripe API       |
| Additional card features             | Stripe API       |
| Statements                           | Bridge API       |
| KYC and cards endorsement management | Bridge Dashboard |
| Cards management                     | Stripe Dashboard |

## Set up Bridge developer account and Stripe account

Work with Bridge to get a developer account set up on Bridge. Separately, set up a new Stripe account on the [Stripe Dashboard](https://dashboard.stripe.com).

Bridge sends you a URL (Stripe App Install Link) to associate the Bridge Developer to the Stripe account, and activate Stripe Issuing on this account. This flow connects Bridge to your Stripe account.

## Create customer

#### Consumer

On the Bridge side, the consumer cardholder maps to an [individual-typed Customer](https://apidocs.bridge.xyz/api-reference/customers/create-a-customer#individual-customer) and on the Stripe side as a [Cardholder](https://docs.stripe.com/api/issuing/cardholders.md). Bridge manages creating the Stripe `Cardholder` object, so you only need to create the customer object on the Bridge API.

Create a customer using the Bridge Customer API or dashboard, and [request the cards endorsement](https://apidocs.bridge.xyz/platform/cards/overview/kyc#managing-customer-eligibility-for-cards) on Bridge. After approving the cards endorsement, Bridge returns the Stripe Cardholder ID in the `Customer` object.

```json
{
    "id": "1e210e5b-700e-41e6-a62a-0eb0b6ac1967",
    "first_name": "Jenny",
    "last_name": "Rosen",
    "email": "jenny.rosen@example.com",
    "status": "active",
    "type": "individual",
    "persona_inquiry_type": "gov_id_db",
    "stripe_cardholder_id": "ich_1SVf3CG6FooBAru7mB2MSrDY",
    "created_at": "2026-01-08T19:24:48.448Z",
    "updated_at": "2026-01-08T19:25:50.758Z",
    "rejection_reasons": [],
    "has_accepted_terms_of_service": true,
    "endorsements": [
        ...,
        {
            "name": "cards",
            "status": "approved",
            "requirements": {
                "complete": [
                    "terms_of_service_v1",
                    "first_name",
                    "last_name",
                    "tax_identification_number",
                    "email_address",
                    "address_of_residence",
                    "date_of_birth",
                    "proof_of_address",
                    "sanctions_screen",
                    "pep_screen",
                    "blocklist_lookup",
                    "min_age_18",
                    "valid_date_of_birth",
                    "selfie_verification",
                    "government_id_rejection_checks_passed",
                    "government_id_review_checks_passed",
                    "pre_onboarding_check",
                    "has_base",
                    "database_lookup",
                    "customer_region_supports_cards",
                    "customer_address_is_valid_for_cards"
                ],
                "pending": [],
                "missing": null,
                "issues": []
            }
        }
    ],
    "future_requirements_due": [],
    "requirements_due": [
        "external_account"
    ],
    "capabilities": {
        "payin_crypto": "active",
        "payout_crypto": "active",
        "payin_fiat": "pending",
        "payout_fiat": "pending"
    },
    "state": "WA",
    "country": "USA"
}
```

This `stripe_cardholder_id` represents a cardholder that has already been created in Stripe. You can use it to directly create cards.

The Stripe Cardholder API is read-only for Bridge-managed cardholders, but you can use the cardholder ID to create a card. Bridge automatically manages the status of the cardholder.

Per existing bank partner rules, the cards endorsement requires the customer to have gone through the KYC process or confirmed their information within the past 24 hours, and is automatically revoked after 24 hours has passed if no card is created. When the cards endorsement gets revoked, the cardholder is automatically transitioned to an `inactive` status in Stripe. You can re-request the endorsement for the customer to refresh the customer’s KYC status, which automatically reactivates the cardholder in Stripe.

#### Commercial

The commercial cardholder’s business is represented on the Bridge side as a [business-typed Customer](https://apidocs.bridge.xyz/api-reference/customers/create-a-customer#business-customer) and on the Stripe side as a [Connect Account](https://docs.stripe.com/api/accounts.md). Bridge manages creating the Stripe `Account` object, so you only need to create the business customer object on the Bridge API.

Create a business customer using the Bridge Customer API and request the `cards` endorsement. For commercial cards, the customer type must be `business`.

After approval of the `cards` endorsement, a Stripe account is created for the business customer within your Stripe Connect platform. You can think of this as a subaccount created under your main Stripe account. The `stripe_account_id` is returned in the `Customer` object.

```json
{
    "id": "fc7c8079-1c66-4b42-b470-fb49ee502f19",
    "first_name": "John",
    "last_name": null,
    "email": "business@example.com",
    "status": "active",
    "type": "business",
    "persona_inquiry_type": "business",
    "created_at": "2026-04-10T16:04:26.982Z",
    "updated_at": "2026-04-10T16:04:27.047Z",
    "rejection_reasons": [],
    "has_accepted_terms_of_service": true,
    "endorsements": [
        ...,
        {
            "name": "cards",
            "status": "approved",
            "requirements": {
                "complete": [
                    "terms_of_service_v1",
                    "business_name",
                    "business_type",
                    "business_description",
                    "is_dao",
                    "email_address",
                    "address_of_incorporation",
                    "address_of_operation",
                    "tax_identification_number",
                    "control_person_ownership_attestation",
                    "minimal_source_of_funds_data",
                    "source_of_funds_questionnaire",
                    "proof_of_address",
                    "adverse_media_screen",
                    "sanctions_screen",
                    "business_ein_verification",
                    "business_registry_verification",
                    "business_website",
                    "business_website_verification",
                    "aiprise_nature_of_business_verification",
                    "aiprise_business_registry_verification",
                    "address_of_incorporation_completeness",
                    "kyb_review",
                    "customer_region_supports_cards",
                    "customer_address_is_valid_for_cards"
                ],
                "pending": [],
                "missing": null,
                "issues": []
            }
        }
    ],
    "future_requirements_due": [],
    "requirements_due": [
        "external_account"
    ],
    "capabilities": {
        "payin_crypto": "active",
        "payout_crypto": "active",
        "payin_fiat": "pending",
        "payout_fiat": "pending"
    },
    "state": "California",
    "country": "USA",
    "associated_persons": [
        {
            "id": "436d8fef-6c9c-4c47-ab48-3ddf5158be6b",
            "email": "person@example.com"
        }
    ],
    "stripe_account_id": "acct_1THowoRnOOaEdKcg"
}
```

This `stripe_account_id` represents a Stripe Connect subaccount tied to the business customer. You use this account ID to create cardholders and cards for the business.

## Create a card

#### Consumer

Use the created cardholder ID to create a card in the Stripe API. In addition to the [standard parameters](https://docs.stripe.com/api/issuing/cards/create.md) for creating the card, you can specify the wallet and balance to associate the card by specifying the `crypto_wallet` parameter of the request. Unlike the Bridge API, the Stripe API uses x-www-form-urlencoded requests.

For example, to create a card to spend USDC from a non-custodial wallet on Solana, make the following request:

```curl
curl -X POST https://api.stripe.com/v1/issuing/cards \
  -u sk_live_…: \
  -d cardholder=ich_1234 \
  -d currency=usd \
  -d type=virtual \
  -d status=active \
  -d "crypto_wallet[chain]=solana" \
  -d "crypto_wallet[currency]=usdc" \
  -d "crypto_wallet[type]=standard" \
  -d "crypto_wallet[address]=6rXzF4UzvU9qxkRxUP3sTrPJ3YudA8eutFHVz7zcmV6q"
```

This table describes the `crypto_wallet` parameters:

| Parameter  | Description                                                                                                                                                                                                                                                                                                                                                                     |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`    | The chain that the wallet is on.                                                                                                                                                                                                                                                                                                                                                |
| `currency` | The stablecoin balance to spend from. Contact Bridge to confirm your stablecoin is supported.                                                                                                                                                                                                                                                                                   |
| `type`     | The type of the funds flow to use. Specify a value of `standard` for non-custodial wallets. The following values are available:
  - `standard`: Non-custodial wallet with an approval to the Bridge smart contract.
  - `bridge_wallet`: The associated wallet is a Bridge Wallet custodied by Bridge.                                                                          |
| `address`  | The address of the crypto wallet. For Solana, don’t specify the associated token account address in this request. Bridge automatically derives it from the specified address and currency. In the previous example, the account’s owner address is `6rXzF4UzvU9qxkRxUP3sTrPJ3YudA8eutFHVz7zcmV6q` but the USDC token account is `G95sWJoUTazecyaUz992djQoMzhiqoFz3CgRXxiuScAp`. |

All Stripe Issuing features are available. For example, to issue a physical card, you can specify a [type](https://docs.stripe.com/api/issuing/cards/create.md#create_issuing_card-type) value of `physical` and supply a shipping address using the [shipping](https://docs.stripe.com/api/issuing/cards/create.md#create_issuing_card-shipping) parameter.

#### Commercial

For commercial cards, creating a card is a two-step process: first create a cardholder for an authorized user of the business, then create a card for that cardholder.

### Create a cardholder

After approval of the business customer’s `cards` endorsement and the creation of a Stripe Account, you can create authorized cardholders under that account using the Stripe [Cardholders API](https://docs.stripe.com/api/issuing/cardholders.md). Use your main Stripe API key and set the `Stripe-Account` header to the business customer’s `stripe_account_id`.

You must pass the Lead Bank terms to the cardholder and record the IP address and date of acceptance.

```curl
curl -X POST https://api.stripe.com/v1/issuing/cardholders \
  -u sk_live_…: \
  -H "Stripe-Account: acct_1THowoRnOOaEdKcg" \
  -d "name=Jenny Rosen" \
  -d "email=jenny.rosen@example.com" \
  -d "phone_number=+18008675309" \
  -d "status=active" \
  -d "type=individual" \
  -d "individual[first_name]=Jenny" \
  -d "individual[last_name]=Rosen" \
  -d "individual[dob][day]=1" \
  -d "individual[dob][month]=11" \
  -d "individual[dob][year]=1981" \
  -d "individual[user_terms_acceptance][lead][ip]=..." \
  -d "individual[user_terms_acceptance][lead][date]=..." \
  -d "billing[address][line1]=510 Townsend Street" \
  -d "billing[address][city]=San Francisco" \
  -d "billing[address][state]=CA" \
  -d "billing[address][postal_code]=94111" \
  -d "billing[address][country]=US"
```

### Create a card for the cardholder

After creating the cardholder, create a card using the Stripe Issuing [Cards API](https://docs.stripe.com/api/issuing/cards/create.md). Include the `Stripe-Account` header and specify the Bridge Wallet to use in the `crypto_wallet` parameter. Unlike the Bridge API, the Stripe API uses x-www-form-urlencoded requests.

```curl
curl -X POST https://api.stripe.com/v1/issuing/cards \
  -u sk_live_…: \
  -H "Stripe-Account: acct_1THowoRnOOaEdKcg" \
  -d cardholder=ich_1TECAmQ6cuy2YivTrox18sOM \
  -d currency=usd \
  -d type=virtual \
  -d status=active \
  -d "crypto_wallet[chain]=solana" \
  -d "crypto_wallet[currency]=usdc" \
  -d "crypto_wallet[type]=bridge_wallet" \
  -d "crypto_wallet[address]=0xc04e299636ba313e1610cbd2d83af23dba01e583"
```

Multiple cards and cardholders can share the same Bridge Wallet, as long as they belong to the same Stripe Account tied to the same business customer on Bridge.

This table describes the `crypto_wallet` parameters:

| Parameter  | Description                                                                                                                                                                                                                                                                                          |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chain`    | The chain that the wallet is on.                                                                                                                                                                                                                                                                     |
| `currency` | The stablecoin balance to spend from. Contact Bridge to confirm your stablecoin is supported.                                                                                                                                                                                                        |
| `type`     | The type of the funds flow to use. Specify a value of `standard` for non-custodial wallets. The following values are available:
  - `standard`: Non-custodial wallet with an approval to Bridge’s smart contract.
  - `bridge_wallet`: The associated wallet is a Bridge Wallet custodied by Bridge. |
| `address`  | The address of the crypto wallet. For Solana, don’t specify the associated token account address in this request. Bridge automatically derives it from the specified address and currency.                                                                                                           |

All Stripe Issuing features are available. For example, to issue a physical card, you can specify a [type](https://docs.stripe.com/api/issuing/cards/create.md#create_issuing_card-type) value of `physical` and supply a shipping address using the [shipping](https://docs.stripe.com/api/issuing/cards/create.md#create_issuing_card-shipping) parameter.

## Bridge custodial wallet

The Stripe Issuing API supports issuing a card that spends from a Bridge-custodied Bridge Wallet. To create a card that spends out of a Bridge Wallet, specify the crypto wallet type as `bridge_wallet`, and pass in the address of the Bridge Wallet:

```curl
curl -X POST https://api.stripe.com/v1/issuing/cards \
  -u sk_live_…: \
  -d cardholder=ich_1234 \
  -d currency=usd \
  -d type=virtual \
  -d status=active \
  -d "crypto_wallet[chain]=solana" \
  -d "crypto_wallet[currency]=usdc" \
  -d "crypto_wallet[type]=bridge_wallet" \
  -d "crypto_wallet[address]=8gN8ioFOObaraWxRcb5p9QHxBSQG8fgHhE95LoAGZXCK"
```

After the card is activated, you can directly use the specified currency balance from the Bridge Wallet for card transactions.

## Non-custodial wallets

The Stripe Issuing API enables issuing a card that spends from your own non-custodial wallet such as a Privy wallet. For the card to be able to spend out of your wallet balance, you must also set up an approval for the Bridge smart contract. The following sections describe the required steps for various chains that Bridge supports.

### Solana

Bridge has a program deployed on Solana mainnet at [cardWArqhdV5jeRXXjUti7cHAa4mj41Nj3Apc6RPZH2](https://solscan.io/account/cardWArqhdV5jeRXXjUti7cHAa4mj41Nj3Apc6RPZH2). To enable spending from your Solana non-custodial wallet, you can set up an approval against the program derived address.

You can adapt a sample delegate approval logic within [this GitHub Gist](https://gist.github.com/lvn/dd41a7233f63f1c45b4ec25c220ecff6) for your own use case. Modify the following lines as needed:

- `MERCHANT_ID` is an ID assigned by Bridge onchain to represent a card issuer on the smart contract. Bridge assigns you a `MERCHANT_ID` for you to derive the delegate address to use. The onchain approval that the user wallet submits is tied to a specific merchant ID and delegate address.
- You can modify the `MINT_PUBKEY` and `TOKEN_PROGRAM_ID` to set the approval to your specific token.

### EVM

On EVM chains with the Bridge smart contract deployed, Bridge assigns an issuer address specific to your developer. You can [submit an ERC-20 approval](https://apidocs.bridge.xyz/platform/cards/overview/noncustodial#evm-2) for Bridge to spend from your non-custodial wallet.

[Contact Stripe](https://support.stripe.com/) to learn about support for other chains.

## Test your card

When your card is activated, you can immediately begin testing card spend. To view the card’s details, you can use the [Stripe Dashboard](https://dashboard.stripe.com/issuing/overview) or embed an Issuing Element into your UI.

At the time of authorization, Bridge pulls funds from the card’s linked non-custodial wallet on a just-in-time basis, relying on the prior onchain approval from the linked non-custodial wallet. In addition to standard authorization checks, Bridge rejects the authorization if the approval isn’t active, insufficient for the purchase amount, or there are insufficient funds in the wallet. See an [example](https://solscan.io/tx/56rPiueBoovToXxLRsC9ztRYteg7b6tmTFcFZNsr9gbJ9VBkB5QNywQGsQNbYWiCzBNZb3NAAovkSpZUAYU4ePkK) of a successful debit transaction onchain.

You can view your card authorizations by using [Issuing authorization endpoints and webhooks](https://docs.stripe.com/issuing/purchases/authorizations.md).

> Stripe doesn’t automatically give control of the `issuing_authorization.request` webhook because of transaction submission latency requirements. If you need this webhook, contact your account manager.

When a card is authorized at a business, Bridge validates that the linked non-custodial wallet has an active onchain approval and sufficient funds for the authorization, and submits an onchain transaction to pull the funds just-in-time.

## Webhooks

Stripe Issuing webhooks notify you of any new card authorizations and changes to existing card authorizations.

When an issuing authorization is requested, a transaction is submitted onchain against your non-custodial wallet. We send an [issuing_authorization.created](https://docs.stripe.com/api/events/types.md?api-version=2025-12-15.preview&rds=1) event to notify you of the authorization. Each incremental authorization (represented by an item in the [request_history](https://docs.stripe.com/api/issuing/authorizations/object.md?api-version=2025-12-15.preview&rds=1#issuing_authorization_object-request_history)) has a corresponding onchain pull against your non-custodial wallet.

An issuing authorization can be partially or fully refunded. The [issuing_authorization.updated](https://docs.stripe.com/api/issuing/authorizations/object.md?api-version=2025-12-15.preview&rds=1) event contains the new amount. For refunds, Bridge asynchronously submits an onchain transaction for the amount to be returned to the external wallet. Bridge can batch multiple refunds into the same onchain transaction.

When a business captures an authorization, we send an [issuing_transaction.created](https://docs.stripe.com/api/events/types.md?api-version=2026-01-28.preview&rds=1#event_types-issuing_transaction.created) webhook. If the captured amount is higher than the previously-authorized amount, another crypto transaction is submitted to pull the additional funds from the linked non-custodial wallet onchain. Bridge might also proactively pull an additional amount at the time of authorization based on the MCC and the overcapture upper bound, and refunds any difference when they know the final amount at capture time.

If the business doesn’t capture the transaction, the authorization also expires after a period of time. When the Issuing Authorization expires, we send an [issuing_authorization.updated](https://docs.stripe.com/api/issuing/authorizations/object.md?api-version=2025-12-15.preview&rds=1) event to transition the authorization to a status of `closed`. Any remaining authorized funds are pushed back to the non-custodial wallet.

## Stripe Issuing features

All Stripe Issuing features are available for your integration. Below are key features:

### Physical cards

Stripe Issuing lets you [issue physical cards](https://docs.stripe.com/issuing/cards/physical.md#get-support-physical-cards) to your customers. You can design custom cards, or issue standard cards to customers in 2 days. Contact your account manager if you’re interested.

When your designs are complete and approved, you can issue physical cards by specifying a [type](https://docs.stripe.com/api/issuing/cards/create.md#create_issuing_card-type) value of `physical` and supplying a shipping address using the [shipping](https://docs.stripe.com/api/issuing/cards/create.md#create_issuing_card-shipping) parameter when creating the card.

### Mobile wallets

Stripe Issuing has support for push provisioning card details to [mobile wallets](https://docs.stripe.com/issuing/cards/digital-wallets.md), which lets cardholders add their card directly to Apple Pay and Google Pay without manually inputting details. To enable push provisioning for your mobile app, work with Stripe to make sure you have the necessary entitlements (in the case of Apple Pay) or API access (in the case of Google Pay).

### Spending limits

In addition to the limits specified on the ERC-20 approval, you can control how much a cardholder can spend on the card by specifying [spending controls](https://docs.stripe.com/issuing/controls/spending-controls.md) on the card or cardholder. At the time of authorization, the Stripe-configured spending limit is checked first, then the onchain limit. When submitting the onchain approval, we recommend that you set a high general limit, then set more specific spending limits by setting the `spending_controls` parameter of a card or cardholder.

### Disputes

Stripe Issuing lets you [submit disputes](https://docs.stripe.com/issuing/purchases/disputes.md) using either the Stripe Dashboard, or through the Disputes API for a more custom UI. We push provisional credits and other refunds associated with the dispute directly to your non-custodial wallet.

### Cardholder support

Card network rules require you to provide phone support to cardholders. Stripe support agents can handle this on your behalf under a generic greeting or one customized to match your specific branding and voice.

Support options range from dispute intake to more complex queries about statements or rewards. For more information, contact your account manager.

### Manage fraud

As a payments product, card issuing inherently incurs potential fraud risks and liabilities for both businesses and issuers. Stripe Issuing provides tools and controls to [manage fraud](https://docs.stripe.com/issuing/manage-fraud.md) in your card program, including [3DS](https://docs.stripe.com/issuing/3d-secure.md), [advanced fraud models](https://docs.stripe.com/issuing/controls/advanced-fraud-tools.md), and [enriched transaction data](https://docs.stripe.com/issuing/purchases/enriched-merchant-data.md).

## Statements

To offer a card program to your customers, you need to generate statements that you make available at least monthly.

For statement generation, you must use the Bridge API. Bridge provides a single API for [automatically generating statements in PDF form](https://apidocs.bridge.xyz/platform/cards/additional/statements#generating-card-statements). We also support generating statements with custom templates.

## Dashboards

You can manage different parts of your card program from the Bridge Dashboard and the Stripe Dashboard.

### Bridge Dashboard

To manage cards endorsement or KYC issues, you can use the Customers section of the Bridge Dashboard. When a customer is missing required steps for their KYC, the customer page indicates that additional customer information is required.

If a customer has previously performed KYC but is missing a fresh KYC for their cards endorsement, the customer page indicates that cards access is `Pending`.

After the customer has fulfilled all the requirements for their cards endorsement, the customer page indicates that they’ve been granted all features.

### Stripe Dashboard

To manage cardholders, cards, disputes and any other features related to cards, use the Stripe Dashboard. The Stripe Dashboard lets you look at all of your issued cards, and the complete history of card authorizations and transactions. You can also initiate a dispute and manage its status from the Dashboard.

## Developer support

For support inquiries related to your card issuing program, use the Slack channel dedicated to your Bridge Slack cards that Bridge sets up at kickoff. A Bridge representative can help you resolve issues related to both the Stripe and Bridge Card Issuing APIs.
