Skip to main content

Consumer Prepaid Template

Overview

Consumer prepaid card products allow consumers to manage personal expenses, shop both in-store and online, and withdraw cash from ATMs. Consumer prepaid card products have the following features:

  • Debit card capabilities
  • A predefined amount of funds
  • Funded from a designated bank account

Prepaid cards require funding through a bank account. When the account holder needs to increase the balance in their financial account, a transfer is initiated from an external bank account.

The following graphic shows how a consumer prepaid card is created and funded:

Consumer Prepaid Card

This guide provides an overview of creating and setting up a consumer prepaid card product in the Test environment.

Create a card product

Use the following mutation to create a consumer prepaid card product. Use CONSUMER_PREPAID as the vertical input variable:

CreateCardProduct
Query
mutation CreateCardProduct($input: CreateCardProductInput!) {
createCardProduct(input: $input) {
__typename
... on CardProduct {
id
name
usage
}
... on UserError {
errors {
errorPath
code
description
}
}
}
}
Variables
{
  "input": {
    "cardProduct": {
      "name": "Consumer Prepaid",
      "usage": "MULTI_USE",
      "vertical": "CONSUMER_PREPAID"
    }
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"createCardProduct": {
"__typename": "CardProduct",
"id": "G8FyZHByb2R1Y3RfcGRfNjI3YjEzYjAyMDI5NDJlN9FkOTBjZGJjNmQzYmY0TYU=",
"name": "Consumer Prepaid",
"usage": "MULTI_USE"
}
},
"extensions": {
"requestId": "b85fc1ec-e770-9d06-922f-16b7486a677i"
}
}

Fund your card program

Some card products use a product funding account to transfer funds to financial accounts. In the Test environment, you can simulate depositing funds into your product funding account. Simulating deposits doesn't require connecting a verified external bank account.

Funding your product funding account requires the following steps:

  1. Retrieve the product funding account ID.
  2. Initiate a wire transfer to the product funding account.

Find product funding account ID

Use the following query to find your product funding account ID:

GetCardProductwithAccounts
Query
query GetCardProductwithAccounts($id: ID!) {
node(id: $id) {
... on CardProduct {
__typename
id
name
usage
accounts {
edges {
node {
id
name
features {
__typename
enabled
}
accountStatus
owner {
__typename
}
}
}
}
}
}
}
Variables
{
"id": "'CARD_PRODUCT_ID"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"id": "CARD_PRODUCT_ID",
"accounts": {
"edges": [
{
"node": {
"id": "FINANCIAL_ACCOUNT_ID",
"features": [
{
"enabled": true,
"__typename": "ProductFundingFinancialAccountFeature"
}
]
}
}
]
}
}
},
"extensions": {
"requestId": "REQUEST_ID",
"rateLimit": {
"cost": 13,
"limit": 60060,
"remaining": 60041
}
}
}

Initiate a wire transfer

Using the following mutation, simulate a wire transfer in the Test environment using the product funding account ID as the toFinancialAccountId input variable:

SimulateDeposit
Query
mutation SimulateDeposit($input: SimulateDepositInput!) {
simulateDeposit(input: $input) {
__typename
... on Transfer {
id
status
statusReason
amount {
value
currencyCode
}
createdAt
updatedAt
ledgers {
name
}
}
... on UserError {
errors {
code
}
}
... on AccessDeniedError {
message
}
}
}
Variables
{
  "input": {
    "amount": {
      "value": 10000000,
      "currencyCode": "USD"
    },
    "source": "WIRE",
    "toFinancialAccountId": "PRODUCT_FUNDING_ACCOUNT_ID",
    "memo": "Consumer Credit product funding wire deposit"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"simulateDeposit": {
"__typename": "Transfer",
"id": "WIRE_TRANSFER_ID",
"status": "PENDING",
"statusReason": null,
"amount": {
"value": 10000000,
"currencyCode": "USD"
},
"createdAt": "2023-09-01T22:26:43.629Z",
"updatedAt": "2023-09-01T22:26:43.629Z",
"ledgers": null
}
},
"extensions": {
"requestId": "REQUEST_ID",
"rateLimit": {
"cost": 12,
"limit": 60060,
"remaining": 60040
}
}
}

Create an account holder

Consumer cards are used by US person account holders. Use the following mutation to create a US person account holder:

createUSPersonAccountHolder
Query
mutation createUSPersonAccountHolder(
$input: CreateUSPersonAccountHolderInput!
) {
createUSPersonAccountHolder(input: $input) {
__typename
... on UserError {
errors {
errorPath
code
description
}
}
... on USPersonAccountHolder {
id
email
dateOfBirth
externalId
updatedAt
createdAt
name {
givenName
familyName
title
suffix
middleName
}
billingAddress {
streetAddress
extendedAddress
postalCode
region
locality
countryCodeAlpha3
}
phoneNumbers {
countryCode
number
label
}
identificationDocument {
socialSecurityNumber {
numberHash
countryCodeAlpha3
}
}
personCreditRiskAttributes {
totalAnnualIncome {
value
currencyCode
}
currentDebtObligations {
value
currencyCode
}
employmentStatus
}
}
}
}
Variables
{
  "input": {
    "personAccountHolder": {
      "email": "gerrytest1@abc.com",
      "name": {
        "givenName": "Gerry",
        "familyName": "Wolfe"
      },
      "billingAddress": {
        "streetAddress": "123 Main Street",
        "postalCode": "60654",
        "locality": "Chicago",
        "region": "IL",
        "countryCodeAlpha3": "USA"
      },
      "phoneNumber": {
        "countryCode": "1",
        "number": "5555555555",
        "label": "MOBILE",
        "extension": "312"
      },
      "identificationDocument": {
        "socialSecurityNumber": {
          "number": "111-11-1111",
          "countryCodeAlpha3": "USA"
        }
      },
      "personCreditRiskAttributes": {
        "totalAnnualIncome": {
          "value": "1000",
          "currencyCode": "USD"
        },
        "currentDebtObligations": {
          "value": "1000",
          "currencyCode": "USD"
        },
        "employmentStatus": "EMPLOYED"
      },
      "dateOfBirth": "1980-09-01",
      "externalId": "EXTERNAL_ID"
    }
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"createUSPersonAccountHolder": {
"__typename": "USPersonAccountHolder",
"id": "ACCOUNT_HOLDER_ID",
"email": "gerrytest1@abc.com",
"dateOfBirth": "1980-09-01",
"externalId": "EXTERNAL_ID",
"updatedAt": "2023-05-03T05:12:01.703Z",
"createdAt": "2023-05-03T05:12:01.703Z",
"name": {
"givenName": "Gerry",
"familyName": "Wolfe",
"title": "",
"suffix": "",
"middleName": ""
},
"billingAddress": {
"streetAddress": "123 Main Street",
"extendedAddress": "",
"postalCode": "60654",
"region": "IL",
"locality": "Chicago",
"countryCodeAlpha3": "USA"
},
"phoneNumbers": [
{
"countryCode": "1",
"number": "5555555555",
"label": "MOBILE"
}
],
"identificationDocument": {
"socialSecurityNumber": {
"numberHash": "AQAAAAOsQ644SC1GNYnzkU0evWaL290gayp0lfmx-sEyxxdQnA",
"countryCodeAlpha3": "USA"
}
},
"personCreditRiskAttributes": {
"totalAnnualIncome": [
{
"value": 1000,
"currencyCode": "USD"
}
],
"currentDebtObligations": [
{
"value": 1000,
"currencyCode": "USD"
}
],
"employmentStatus": "EMPLOYED"
}
}
},
"extensions": {
"requestId": "REQUEST_ID"
}
}

Open an application

After creating an account holder, you can open an application to onboard them to your card product. Opening an application triggers identity verification processes. You can participate in the application decisioning process using Collaborative Application Decisioning.

In some cases, additional documents may be required to approve an application. For more information on collecting additional documents, see Request Documents for Application Review.

Use the following mutation to open an application for an account holder:

createAccountHolderCardProductApplication
Query
mutation createAccountHolderCardProductApplication(
$input: CreateAccountHolderCardProductApplicationInput!
) {
createAccountHolderCardProductApplication(input: $input) {
__typename
... on AccountHolderCardProductApplication {
id
applicationState {
status
}
updatedAt
createdAt
}
... on UserError {
errors {
errorPath
code
description
}
}
}
}
Variables
{
  "input": {
    "accountHolderId": "ACCOUNT_HOLDER_ID",
    "cardProductId": "CARD_PRODUCT_ID",
    "cardHolderAgreementConsent": {
      "primaryAuthorizedPersonId": "PRIMARY_AUTHORIZED_PERSON_ID",
      "consentTimestamp": "2021-12-22T17:10:55.662Z"
    }
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"createAccountHolderCardProductApplication": {
"__typename": "AccountHolderCardProductApplication",
"id": "APPLICATION_ID",
"applicationState": {
"status": "PENDING"
},
"createdAt": "2021-07-07T23:22:30.475Z",
"updatedAt": "2021-07-07T23:22:30.475Z"
}
},
"extensions": {
"requestId": "REQUEST_ID"
}
}

Issue a financial account

Financial accounts hold the balance for payment cards. To create a financial account, pass the id of the account holder's approved application.

Financial accounts have an externalId variable field that allows you to tie the account to an entity in your system. If you do not pass in an externalId, Highnote will generate one.

Use the following mutation to issue a financial account for an application:

IssueFinancialAccountForApplication
Query
mutation IssueFinancialAccountForApplication(
$input: IssueFinancialAccountForApplicationInput!
) {
issueFinancialAccountForApplication(input: $input) {
... on FinancialAccount {
id
externalId
name
createdAt
updatedAt
application {
id
createdAt
}
cardProduct {
id
vertical
}
features {
__typename
enabled
createdAt
updatedAt
}
directDepositDetails {
id
restrictedDetails {
__typename
... on DirectDepositDetailRestrictedDetails {
number
routingNumber
bank {
name
}
}
}
}
owner {
__typename
... on USPersonAccountHolder {
id
}
}
}
}
}
Variables
{
  "input": {
    "applicationId": "APPLICATION_ID",
    "name": "Financial Account",
    "externalId": "YOUR_EXTERNAL_ID"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"issueFinancialAccountForApplication": {
"id": "FINANCIAL_ACCOUNT_ID",
"externalId": "ABC123456",
"name": "John Doe - Account",
"createdAt": "2021-12-28T18:20:49.932Z",
"updatedAt": "2021-12-28T18:20:49.960Z",
"application": {
"id": "APPLICATION_ID",
"createdAt": "2021-12-20T17:59:33.570Z"
},
"cardProduct": {
"id": "CARD_PRODUCT_ID",
"vertical": "GENERAL_PURPOSE_RELOADABLE"
},
"features": [
{
"__typename": "DirectDepositFinancialAccountFeature",
"enabled": true,
"createdAt": "2021-12-28T18:20:49.933Z",
"updatedAt": "2021-12-28T18:20:49.933Z"
},
{
"__typename": "DebitPaymentCardFinancialAccountFeature",
"enabled": true,
"createdAt": "2021-12-28T18:20:49.933Z",
"updatedAt": "2021-12-28T18:20:49.933Z"
}
],
"directDepositDetails": {
"id": "FINANCIAL_ACCOUNT_ID",
"restrictedDetails": {
"__typename": "AccessDeniedError"
}
},
"owner": {
"__typename": "USPersonAccountHolder",
"id": "ACCOUNT_HOLDER_ID"
}
}
}
}

Issue a payment card

Once you have created a financial account, you can issue a payment card. By default, all payment cards start as virtual cards. After you issue a virtual card, you can create a physical card order if needed.

Use the following mutation to issue a virtual card:

IssuePaymentCardForFinancialAccount
Query
mutation IssuePaymentCardForFinancialAccount(
$input: IssuePaymentCardForFinancialAccountInput!
) {
issuePaymentCardForFinancialAccount(input: $input) {
... on PaymentCard {
id
bin
last4
expirationDate
network
status
financialAccounts {
id
name
}
restrictedDetails {
... on PaymentCardRestrictedDetails {
cvv
number
}
... on AccessDeniedError {
message
}
}
}
... on UserError {
errors {
errorPath
code
description
}
}
}
}
Variables
{
  "input": {
    "financialAccountId": "FINANCIAL_ACCOUNT_ID",
    "options": {
      "activateOnCreate": true,
      "expirationDate": "2023-01-01T23:59:59Z"
    }
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"issuePaymentCardForFinancialAccount": {
"id": "PAYMENT_CARD_ID",
"bin": "489661",
"last4": "9602",
"expirationDate": "2025-01-01T23:59:59Z",
"network": "MASTERCARD",
"status": "ACTIVE",
"financialAccounts": [
{
"id": "FINANCIAL_ACCOUNT_ID",
"name": "Test Consumer Credit Account"
}
],
"restrictedDetails": {
"message": "Access is denied"
}
}
},
"extensions": {
"requestId": "REQUEST_ID"
}
}

Physical cards

By default, all payment cards start as virtual cards. Highnote also supports issuing personalized payment cards to account holders. For more information on issuing physical cards, see Print Physical Cards.

Digital wallets

Highnote supports issuing tokenized cards. Account holders can add tokenized cards to digital wallets like Apple and Google Pay. For more information, see Add Cards to Digital Wallets.

Non-originated ACH

test with dummy data

Do not enter production data in the Highnote Test environment, which is for exploring features and training. Use only dummy or test data.

In the Live environment, non-originated ACH transfers are initiated by account holders. In the Test environment, you can simulate a non-originated ACH transfer to fund a financial account using the following mutation:

simulateNonOriginatedAchTransfer
Query
mutation simulateNonOriginatedAchTransfer(
$input: SimulateNonOriginatedAchTransferInput!
) {
simulateNonOriginatedAchTransfer(input: $input) {
__typename
... on NonOriginatedAchTransfer {
id
amount {
currencyCode
value
}
createdAt
updatedAt
ledgers {
id
name
normalBalance
asOf
debitBalance {
value
currencyCode
}
creditBalance {
value
currencyCode
}
}
type
purpose
sign
traceNumber
status
statusFailureReason
settlementDate
processedAt
failedAt
returnSentToBankAt
}
}
}
Variables
{
  "input": {
    "idempotencyKey": "12345",
    "financialAccountId": "id",
    "amount": {
      "currencyCode": "USD",
      "value": "200.00"
    },
    "purpose": "DEPOSIT",
    "settlementDate": "2024-12-23",
    "companyIdentifier": "123",
    "companyName": "My Company",
    "companyDiscretionaryData": "data",
    "companyEntryDescription": "description",
    "individualIdentificationNumber": "123",
    "individualName": "Joe",
    "paymentRelatedInformation": "RMR*IV*0123456789**999.99"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"simulateNonOriginatedAchTransfer": {
"__typename": "NonOriginatedAchTransfer",
"id": "TRANSFER_ID",
"amount": {
"currencyCode": "USD",
"value": "200.00"
},
"createdAt": "2024-09-13T10:15:30Z",
"updatedAt": "2024-09-13T10:15:30Z",
"ledgers": [
{
"id": "ledger_001",
"name": "Primary Ledger",
"normalBalance": "DEBIT",
"asOf": "2024-09-13T10:15:30Z",
"debitBalance": {
"value": "200.00",
"currencyCode": "USD"
},
"creditBalance": {
"value": "0.00",
"currencyCode": "USD"
}
}
],
"type": "DEPOSIT",
"purpose": "DEPOSIT",
"sign": "+",
"traceNumber": "123456789",
"status": "PROCESSED",
"statusFailureReason": null,
"settlementDate": "2024-12-23",
"processedAt": "2024-09-13T10:16:30Z",
"failedAt": null,
"returnSentToBankAt": null
}
}
}

Transfer from product funding account

Some prepaid card products may require using your product funding account to fund an account holder's financial account. Use the following input variables to ensure money is moving in the correct direction:

  • toFinancialAccountId: Account holder's financial account ID
  • fromFinancialAccountId: Product funding account ID

Use the following mutation to initiate a transfer from your product funding account:

initiateTransferFromFundingFinancialAccountToPaymentCardFinancialAccount
Query
mutation initiateTransferFromFundingFinancialAccountToPaymentCardFinancialAccount(
$input: InitiateTransferFromFundingFinancialAccountToPaymentCardFinancialAccountInput!
) {
initiateTransferFromFundingFinancialAccountToPaymentCardFinancialAccount(
input: $input
) {
__typename
... on InterFinancialAccountTransfer {
id
status
statusReason
createdAt
updatedAt
memo
amount {
value
currencyCode
}
}
... on UserError {
errors {
code
errorPath
description
}
}
... on AccessDeniedError {
message
}
}
}
Variables
{
  "input": {
    "toFinancialAccountId": "ACCOUNT_HOLDER_FINANCIAL_ACCOUNT_ID",
    "fromFinancialAccountId": "PRODUCT_FUNDING_ACCOUNT_ID",
    "memo": "Fund Financial Account #1",
    "amount": {
      "value": 10000,
      "currencyCode": "USD"
    }
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"initiateTransferFromFundingFinancialAccountToPaymentCardFinancialAccount": {
"__typename": "InterFinancialAccountTransfer",
"id": "TRANSFER_ID",
"status": "PENDING",
"memo": "Fund Financial Account #1",
"statusReason": null,
"createdAt": "2021-12-27T22:26:55.102Z",
"updatedAt": "2021-12-27T22:26:55.127Z",
"amount": {
"value": 10000,
"currencyCode": "USD"
}
}
}
}

Transfer funds from a financial account

Use the following mutation to transfer funds from a Highnote financial account to your product funding account. For input variables, use the following IDs:

  • toFinancialAccountId: Product funding account ID
  • fromFinancialAccountId: Account holder's payment card financial account ID
initiateTransferFromPaymentCardFinancialAccountToFundingFinancialAccount
Query
mutation initiateTransferFromPaymentCardFinancialAccountToFundingFinancialAccount(
$input: InitiateTransferFromPaymentCardFinancialAccountToFundingFinancialAccountInput!
) {
initiateTransferFromPaymentCardFinancialAccountToFundingFinancialAccount(
input: $input
) {
__typename
... on InterFinancialAccountTransfer {
id
status
statusReason
createdAt
updatedAt
memo
amount {
value
currencyCode
}
}
... on UserError {
errors {
code
errorPath
description
}
}
... on AccessDeniedError {
message
}
}
}
Variables
{
  "input": {
    "toFinancialAccountId": "PRODUCT_FUNDING_ACCOUNT_ID",
    "fromFinancialAccountId": "FINANCIAL_ACCOUNT_ID",
    "memo": "unload card",
    "amount": {
      "value": 5000,
      "currencyCode": "USD"
    }
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"initiateTransferFromPaymentCardFinancialAccountToFundingFinancialAccount": {
"__typename": "InterFinancialAccountTransfer",
"id": "TRANSFER_ID",
"status": "COMPLETED",
"memo": "unload card",
"statusReason": null,
"createdAt": "2022-2-27T22:26:55.102Z",
"updatedAt": "2022-2-27T22:26:55.127Z",
"amount": {
"value": 5000,
"currencyCode": "USD"
}
}
}
}

Display account and routing number

Prepaid cards have the DIRECT_DEPOSIT feature enabled by default. Financial accounts with the DIRECT_DEPOSIT feature have an associated account and routing number that can be used to transfer funds into the account from outside Highnote.

To display the account and routing number in your website or application, you can fetch them from the API by generating a Client Token and using that token to view the restricted details.

The following graphic shows an example of what fetching an account and routing number looks like:

Display Virtual Card Account and Routing Numbers

Use the following query to view direct deposit information:

ViewDirectDepositDetails
Query
query ViewDirectDepositDetails($id: ID!) {
node(id: $id) {
... on FinancialAccount {
directDepositDetails {
id
restrictedDetails {
__typename
... on DirectDepositDetailRestrictedDetails {
number
routingNumber
}
}
}
}
}
}
Variables
{
"id": "FINANCIAL_ACCOUNT_ID"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"__typename": "ExternalBankAccountDetail",
"id": "FINANCIAL_ACCOUNT_ID",
"last4": "2730",
"type": "CHECKING",
"restrictedDetails": {
"number": "0493712730",
"routingNumber": "89703965"
}
}
},
"extensions": {
"requestId": "REQUEST_ID"
}
}

Display payment card data

tip

Highnote recommends using the Card Viewer SDK to securely display payment card data and and reduce PCI non-compliance.

There are two methods for displaying payment card data on your website or application:

  • Fetching the data from the Highnote API
  • Use the Card Viewer SDK to ensure PCI compliance

To fetch payment card data from the API, use the following query:

FindPaymentCard
Query
query FindPaymentCard($id: ID!) {
node(id: $id) {
... on PaymentCard {
bin
last4
expirationDate
restrictedDetails {
... on PaymentCardRestrictedDetails {
cvv
number
}
}
}
}
}
Variables
{
"id": "PAYMENT_CARD_ID"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
Result
{
"data": {
"node": {
"bin": "BIN",
"last4": "LAST_4",
"expirationDate": "EXPIRATION_DATE",
"restrictedDetails": {
"cvv": "CVV",
"number": "NUMBER"
}
}
}
}

Simulate transactions

After configuring your card product, we recommend simulating transactions. Simulating transactions is useful for testing your card program's configuration and settings.

For more information on simulating transactions, see Simulate Transactions.

Expand your integration

After configuring your card product and simulating transactions, you can use the following features to further expand your integration: