Card issuing tutorial
Moov enables you to instantly issue virtual cards on the Visa network, empowering a broad range of embedded spending and expense management solutions such as:
- Replacing traditional checks for bill payments
- Providing rapid access to funds from merchant processing
- Facilitating immediate payments to vendors
Use case
For the purposes of this guide, we’ll assume you are a developer building a platform for the following use case:
- Your Moov account: A platform that enables customers to accept payments and use those funds for business-related purchases
- Customer: A business that will use the virtual card to make payments with funds from its Moov wallet
Prerequisites
This guide assumes that you have onboarded business customers with the card-issuing capabilities. To learn more about onboarding, read our hosted onboarding guide. We also assume that your customer's Moov wallet has already been funded with a balance.
Read our wallet and source guides for more information on funding a wallet.
Your customer's card-issuing wallet will be used as the funds source for the issued card. Card-issuing wallets are automatically created when the card-issuing capability is enabled. Card-issuing wallets can be loaded with funds from another source, typically with a wallet-to-wallet transfer from the default wallet. Only funds in the card-issuing wallet can be used with issued cards.
Request a virtual spending card
After successfully onboarding and verifying your customer's business, you can proceed to request a virtual card through the Moov API.
To issue a virtual card, you have the option of submitting the following parameters:
| Parameter | Description |
|---|---|
authorizedUserAccountID |
The unique identifier for the Moov wallet associated with the authorized user |
billingAddress |
Billing address of the issued card's authorized user |
controls |
Choose controls such as velocity limits, merchant restrictions, schedules, expiry, and whether or not the card is single use |
expiration |
The expiration date of the card or token |
metadata |
Free-form key-value pair list. Useful for storing information that is not captured elsewhere |
nickname |
Descriptive name for the issued spending card |
curl -X POST "https://api.moov.io/issuing/{accountID}/cards" \
-H "Authorization: Bearer {token}" \
-H "x-moov-version: v2024.01.00" \
--data-raw '{
"authorizedUserAccountID": "string",
"billingAddress": {
"addressLine1": "123 Main Street",
"city": "Denver",
"stateOrProvince": "CO",
"postalCode": "80301",
"country": "US"
},
"controls": {
"singleUse": false,
"velocityLimits" : [
{
"amount": 1000,
"interval": "per-transaction"
}
]
},
"expiration": {
"month": "01",
"year": "27"
},
"nickname": "supplies purchase"
}'\
Once the virtual card has been issued, the customer can then use the card to make purchases within the amount of their wallet balance.
Optional card controls
You can limit the usage of an issued card by setting controls in the card creation request. The following controls are currently supported:
allowedSchedule: Limits card usage to specific days and times. Set tonullto remove all schedule restrictions.expiresOn: When a cutoff date and time are set, all authorizations after this datetime are declined regardless of other controls. Set tonullfor no cutoff.merchantCategoryRestrictions: Restricts card usage by merchant category. If none are set, some categories might be blocked by card networks by default.merchantRestrictions: Restricts card usage to specific merchants, or blocks specific merchants.singleUse: Iftrue, the card closes after the first successful authorization.velocityLimits: Sets spending limits per time interval.
Most controls can be updated with the PATCH update spending card endpoint. The singleUse control cannot be updated after card creation.
The following example demonstrates a card configured to close after the first successful authorization (singleUse) and enforces a per-transaction spending limit of $50.00.
{
"controls": {
"singleUse": true,
"velocityLimits": [
{
"amount": 5000, // $50.00
"interval": "per-transaction"
}
]
}
}
Issued card Drop
Once an issued card is in an active state, your customer can securely access the full PCI-compliant card details for making transactions through the Issued card Drop, a secure interface for displaying sensitive card information.
// Card issuing Moov Drop
const issuedCard = document.querySelector("moov-issued-card");
// After generating a token, set it on the issued card element
issuedCard.oauthToken = "some-generated-token";
// Include the accountID of the Moov account to which the card was issued and the ID of the issued card to display
issuedCard.accountID = "account-id";
issuedCard.issuedCardID = "card-id";
View issued card authorizations
Each time a card is used to make a purchase from a merchant, Moov processes the authorization request in real time. The outcomes of these requests can be tracked through the card authorization API.
Below is an example of the card authorization response:
[
{
"authorizationID": "string",
"issuedCardID": "string",
"fundingWalletID": "string",
"network": "visa",
"authorizedAmount": "-14.89",
"status": "pending",
"merchantData": {
"networkID": "string",
"name": "Whole Body Fitness",
"city": "San Francisco",
"country": "US",
"postalCode": "94107",
"state": "CA",
"mcc": "7298"
},
"createdOn": "2026-08-24T14:15:22Z",
"cardTransactions": [
"string"
]
}
]
View completed card transactions
When a pending authorization is successfully captured and funds have settled, a card transaction resource is created. This indicates that the funds related to that transaction have been moved. We retain details from the original authorization for reconciliation and tracking purposes.
You can list all card transactions associated with a particular Moov account by using the list card transactions GET endpoint. Below is an example of the card transaction response:
[
{
"cardTransactionID": "string",
"issuedCardID": "string",
"fundingWalletID": "string",
"amount": "-14.89",
"authorizationID": "string",
"authorizedOn": "2019-08-24T14:15:22Z",
"merchantData": {
"networkID": "string",
"name": "Whole Body Fitness",
"city": "San Francisco",
"country": "US",
"postalCode": "94107",
"state": "CA",
"mcc": "7298"
},
"createdOn": "2019-08-24T14:15:22Z"
}
]