# Use Treasury and Issuing to set up financial accounts and cards Follow a sample Treasury and Issuing integration that sets up a financial account and creates cards. Homebox is a fictitious vertical SaaS that builds software for home-services companies like HVAC technicians, cleaners, and plumbers. Homebox begins its *Treasury* integration by setting up a Treasury financial account and creating payment cards. To see how Homebox moves money to and from external bank accounts, see the [Using Treasury to move money](https://docs.stripe.com/treasury/examples/moving-money.md) example integration. ## Platform onboarding Homebox is already a Stripe platform with [Payments](https://docs.stripe.com/payments.md) and [Connect](https://docs.stripe.com/connect.md) enabled. Homebox uses [Custom connected accounts](https://docs.stripe.com/connect/accounts.md), and those connected accounts already have the `card_payments` capability enabled. ## Add capabilities To use Treasury and Issuing services, Homebox needs to request the additional `treasury` and `card_issuing` capabilities for the platform’s connected accounts. Each connected account must then onboard before Stripe can create a Treasury financial account for it. To use ACH transfers with Treasury, Homebox also needs to request the `us_bank_account_ach_payments` capability. To request the `treasury`, `card_issuing`, and `us_bank_account_ach_payments` capabilities, Homebox makes a request to the [Accounts API](https://docs.stripe.com/api/accounts.md). To use Hosted Onboarding, Homebox makes a call to [Account Links](https://docs.stripe.com/api/account_links.md) to retrieve a URL that their connected account can use to submit onboarding information for the Treasury financial account. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new AccountLinkCreateOptions { Account = "<>", RefreshUrl = "https://example.com/reauth", ReturnUrl = "https://example.com/return", Type = "account_onboarding", }; var service = new AccountLinkService(); AccountLink accountLink = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.AccountLinkParams{ Account: stripe.String("<>"), RefreshURL: stripe.String("https://example.com/reauth"), ReturnURL: stripe.String("https://example.com/return"), Type: stripe.String("account_onboarding"), }; result, err := accountlink.New(params); ``` ```java Stripe.apiKey = "<>"; AccountLinkCreateParams params = AccountLinkCreateParams.builder() .setAccount("<>") .setRefreshUrl("https://example.com/reauth") .setReturnUrl("https://example.com/return") .setType(AccountLinkCreateParams.Type.ACCOUNT_ONBOARDING) .build(); AccountLink accountLink = AccountLink.create(params); ``` ```node const stripe = require('stripe')('<>'); const accountLink = await stripe.accountLinks.create({ account: '<>', refresh_url: 'https://example.com/reauth', return_url: 'https://example.com/return', type: 'account_onboarding', }); ``` ```python import stripe stripe.api_key = "<>" account_link = stripe.AccountLink.create( account="<>", refresh_url="https://example.com/reauth", return_url="https://example.com/return", type="account_onboarding", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $accountLink = $stripe->accountLinks->create([ 'account' => '<>', 'refresh_url' => 'https://example.com/reauth', 'return_url' => 'https://example.com/return', 'type' => 'account_onboarding', ]); ``` ```ruby Stripe.api_key = '<>' account_link = Stripe::AccountLink.create({ account: '<>', refresh_url: 'https://example.com/reauth', return_url: 'https://example.com/return', type: 'account_onboarding', }) ``` The response includes a URL the connected account uses to access the application, which must be done before the link expires. ```json { "object": "account_link", "created": 1612927106, "expires_at": 1612927406, "url": "https://connect.stripe.com/setup/s/iCtLfmYb2tEU" } ``` Homebox listens for the `account.updated` webhook to confirm the following fields and capabilities on the connected account: ```json { "object": { "id": "{{CONNECTED_ACCOUNT_ID}}", "object": "account", "capabilities": { "card_payments": "active", "treasury": "active", "card_issuing": "active", // Only appears if requesting the `card_issuing` capability. "us_bank_account_ach_payments": "active", // Only appears if requesting the `us_bank_account_ach_payments` capability. }, ... } } ``` ## Create a FinancialAccount After Stripe adds the `treasury` capability to an account, Homebox can create the `FinancialAccount` object for the account. To do so, Homebox calls `FinancialAccounts` and requests the `Features` the company wants to provide. The response confirms the account is processing. After processing completes and all relevant features are active, Homebox gets a confirmation from their `treasury.financial_account.features_status_updated` webhook listener. ```json { "object": "treasury.financial_account", "created": 1612927106, "id": "{{FINANCIAL_ACCOUNT_ID}}", "country": "US", "supported_currencies": ["usd"], "financial_addresses": [ // This field is empty until the "financial_addresses.aba" feature becomes active { "type": "aba", "supported_networks": ["ach", "us_domestic_wire"], "aba": { "account_number_last4": "7890", // Use the expand[] parameter to view the `account_number` field hidden by default "account_number": "1234567890", "routing_number": "000000001", "bank_name": "Bank of Earth" } } ], "livemode": true, // State machine: // open - the account is ready to be used // closed - the account is closed "status": "open", "status_details": { // `closed` is null if financial account is not closed "closed": { // List of one or more reasons why the FinancialAccount was closed: // - account_rejected // - closed_by_platform // - other "reasons": [], } }, active_features: ["card_issuing"], pending_features: ["deposit_insurance", "financial_addresses.aba", "outbound_payments.ach", "us_domestic_wire", "inbound_transfers.ach", "outbound_transfers.ach", "outbound_transfers.us_domestic_wire"], restricted_features: [], "features": { "object": "treasury.financial_account_features", "card_issuing": { "status": "active", "status_details": [], "access": "active", }, "deposit_insurance": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, "financial_addresses": { "aba": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, }, "outbound_payments": { "ach": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, }, "us_domestic_wire": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, "inbound_transfers": { "ach": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, }, "outbound_transfers": { "ach": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, }, "outbound_payments": { "ach": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, }, "outbound_transfers": { "us_domestic_wire": { "requested": true, "status": "pending", // Becomes "active" once the Treasury financial account is set up "status_details": [{"code": "activating", "resolution": nil}], }, }, "platform_restrictions": { "inbound_flows": "unrestricted", "outbound_flows": "unrestricted" }, "metadata": {}, ... } ``` ## Create a payment cardholder Before Homebox can create cards for Treasury financial accounts, it needs to create cardholders. The cardholders in this example are plumbers who use Homebox services and own the connected accounts on the platform. # Dashboard > This is a Dashboard for when testing-method is without-code. View the original doc at https://docs.stripe.com/treasury/examples/financial-accounts?testing-method=without-code. 1. Visit the [Connected accounts](https://dashboard.stripe.com/test/issuing/cards) page in the Dashboard. 1. Select the connected account you want to create a cardholder on to expand its details. 1. Select the **Card issuing** tab. ![Connected account details view 'Card issuing' tab](images/issuing/connected-account-card-issuing-tab.png) 1. Click the **+** button next to **Cardholders**. 1. Fill in the cardholder’s details and click **Create cardholder**. ![Create Issuing cardholder form](images/issuing/connected-account-cardholder-create.png) # API > This is a API for when testing-method is with-code. View the original doc at https://docs.stripe.com/treasury/examples/financial-accounts?testing-method=with-code. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Issuing.CardholderCreateOptions { Name = "Jenny Bath Remodeling", Type = "company", Email = "jenny@example.com", PhoneNumber = "+18008675309", Status = "active", Billing = new Stripe.Issuing.CardholderBillingOptions { Address = new AddressOptions { Line1 = "1234 Main Street", City = "San Francisco", State = "CA", PostalCode = "94111", Country = "US", }, }, }; var service = new Stripe.Issuing.CardholderService(); Stripe.Issuing.Cardholder cardholder = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.IssuingCardholderParams{ Name: stripe.String("Jenny Bath Remodeling"), Type: stripe.String(string(stripe.IssuingCardholderTypeCompany)), Email: stripe.String("jenny@example.com"), PhoneNumber: stripe.String("+18008675309"), Status: stripe.String(string(stripe.IssuingCardholderStatusActive)), Billing: &stripe.IssuingCardholderBillingParams{ Address: &stripe.AddressParams{ Line1: stripe.String("1234 Main Street"), City: stripe.String("San Francisco"), State: stripe.String("CA"), PostalCode: stripe.String("94111"), Country: stripe.String("US"), }, }, }; result, err := cardholder.New(params); ``` ```java Stripe.apiKey = "<>"; CardholderCreateParams params = CardholderCreateParams.builder() .setName("Jenny Bath Remodeling") .setType(CardholderCreateParams.Type.COMPANY) .setEmail("jenny@example.com") .setPhoneNumber("+18008675309") .setStatus(CardholderCreateParams.Status.ACTIVE) .setBilling( CardholderCreateParams.Billing.builder() .setAddress( CardholderCreateParams.Billing.Address.builder() .setLine1("1234 Main Street") .setCity("San Francisco") .setState("CA") .setPostalCode("94111") .setCountry("US") .build() ) .build() ) .build(); Cardholder cardholder = Cardholder.create(params); ``` ```node const stripe = require('stripe')('<>'); const cardholder = await stripe.issuing.cardholders.create({ name: 'Jenny Bath Remodeling', type: 'company', email: 'jenny@example.com', phone_number: '+18008675309', status: 'active', billing: { address: { line1: '1234 Main Street', city: 'San Francisco', state: 'CA', postal_code: '94111', country: 'US', }, }, }); ``` ```python import stripe stripe.api_key = "<>" cardholder = stripe.issuing.Cardholder.create( name="Jenny Bath Remodeling", type="company", email="jenny@example.com", phone_number="+18008675309", status="active", billing={ "address": { "line1": "1234 Main Street", "city": "San Francisco", "state": "CA", "postal_code": "94111", "country": "US", }, }, ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $cardholder = $stripe->issuing->cardholders->create([ 'name' => 'Jenny Bath Remodeling', 'type' => 'company', 'email' => 'jenny@example.com', 'phone_number' => '+18008675309', 'status' => 'active', 'billing' => [ 'address' => [ 'line1' => '1234 Main Street', 'city' => 'San Francisco', 'state' => 'CA', 'postal_code' => '94111', 'country' => 'US', ], ], ]); ``` ```ruby Stripe.api_key = '<>' cardholder = Stripe::Issuing::Cardholder.create({ name: 'Jenny Bath Remodeling', type: 'company', email: 'jenny@example.com', phone_number: '+18008675309', status: 'active', billing: { address: { line1: '1234 Main Street', city: 'San Francisco', state: 'CA', postal_code: '94111', country: 'US', }, }, }) ``` The response confirms the cardholder is created. ```json { "id": "{{CARDHOLDER_ID}}", "object": "issuing.cardholder", "billing": { "address": { "city": "\"San Francisco\"", "country": "US", "line1": "\"1234 Main Street\"", "postal_code": "94111", "state": "CA" } }, "created": 1623803705, "email": "jenny@example.com", "livemode": false, "metadata": {}, "name": "Jenny Bath Remodeling", "phone_number": "+18008675309", "requirements": { "disabled_reason": "under_review", "past_due": [] }, "spending_controls": { "allowed_categories": [], "blocked_categories": [], "spending_limits": [], }, "status": "active", "type": "company" } ``` ## Create payment cards Now that the connected account has a `FinancialAccount` object associated with it and an available cardholder, Homebox can create a payment card using the `FinancialAccount` balance as the card’s available balance. # Dashboard > This is a Dashboard for when testing-method is without-code. View the original doc at https://docs.stripe.com/treasury/examples/financial-accounts?testing-method=without-code. You can’t create [Financial accounts](https://docs.stripe.com/treasury/account-management/financial-accounts.md) in the Dashboard. You must use the API to create them. 1. Visit the [Connected accounts](https://dashboard.stripe.com/test/issuing/cards) page in the Dashboard. 1. Select the connected account you want to create a cardholder on to expand its details. 1. Select the **Card issuing** tab. ![Connected account details view 'Card issuing' tab](images/issuing/connected-account-card-issuing-tab.png) 1. Click the **+** button next to **Cards**. 1. Select the card type and the financial account that you want to fund the card with and click **Create**. ![Create Issuing card form](images/issuing/connected-account-card-create.png) # API > This is a API for when testing-method is with-code. View the original doc at https://docs.stripe.com/treasury/examples/financial-accounts?testing-method=with-code. ```dotnet StripeConfiguration.ApiKey = "<>"; var options = new Stripe.Issuing.CardCreateOptions { Currency = "usd", Type = "virtual", Cardholder = "<>", FinancialAccount = "<>", }; var service = new Stripe.Issuing.CardService(); Stripe.Issuing.Card card = service.Create(options); ``` ```go stripe.Key = "<>" params := &stripe.IssuingCardParams{ Currency: stripe.String(string(stripe.CurrencyUSD)), Type: stripe.String(string(stripe.IssuingCardTypeVirtual)), Cardholder: stripe.String("<>"), FinancialAccount: stripe.String("<>"), }; result, err := card.New(params); ``` ```java Stripe.apiKey = "<>"; CardCreateParams params = CardCreateParams.builder() .setCurrency("usd") .setType(CardCreateParams.Type.VIRTUAL) .setCardholder("<>") .setFinancialAccount("<>") .build(); Card card = Card.create(params); ``` ```node const stripe = require('stripe')('<>'); const card = await stripe.issuing.cards.create({ currency: 'usd', type: 'virtual', cardholder: '<>', financial_account: '<>', }); ``` ```python import stripe stripe.api_key = "<>" card = stripe.issuing.Card.create( currency="usd", type="virtual", cardholder="<>", financial_account="<>", ) ``` ```php $stripe = new \Stripe\StripeClient('<>'); $card = $stripe->issuing->cards->create([ 'currency' => 'usd', 'type' => 'virtual', 'cardholder' => '<>', 'financial_account' => '<>', ]); ``` ```ruby Stripe.api_key = '<>' card = Stripe::Issuing::Card.create({ currency: 'usd', type: 'virtual', cardholder: '<>', financial_account: '<>', }) ``` The response confirms the card is issued. ```json { "id": "{{CARD_ID}}", "object": "issuing.card", "cardholder": { "id": "{{CARDHOLDER_ID}}", "object": "issuing.cardholder", "billing": { "address": { "city": "San Francisco", "country": "US", "line1": "123 Main Street", "line2": null, "postal_code": "94111", "state": "CA" } }, ... }, "created": 1643293629, "currency": "usd", "exp_month": 12, "exp_year": 2024, "last4": "0930", "livemode": false, ... } ``` ## See Also * [Using Treasury to move money](https://docs.stripe.com/treasury/examples/moving-money.md) * [API reference](https://docs.stripe.com/api/treasury/financial_accounts.md)