Cards

Learn how to create, update, manage, and reissue cards. Both virtual cards and physical cards [beta] are supported.

Card Schema

{
  "created": String,
  "cvv": String,
  "funding": FundingAccount,
  "exp_month": String,
  "exp_year": String,
  "hostname": String,
  "last_four": String,
  "memo": String,
  "pan": String,
  "spend_limit": Integer,
  "spend_limit_duration": String,
  "state": String,
  "token": String,
  "type": String
}
createdAn ISO 8601 timestamp for when the card was created
cvv (Enterprise) Three digit CVV printed on the back of the card
fundingSee Funding Schema
exp_month (Enterprise) Two digit (MM) expiry month
exp_year (Enterprise) Four digit (yyyy) expiry year
hostnameHostname of card’s locked merchant (will be empty if not applicable)
last_fourLast four digits of the card number
memoFriendly name to identify the card
pan (Enterprise) Sixteen digit card number (only available for customers who have verified PCI compliance)
spend_limitAmount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined
spend_limit_durationTRANSACTION, MONTHLY, ANNUALLY, FOREVER
stateOPEN, PAUSED, CLOSED, PENDING_FULFILLMENT, PENDING_ACTIVATION
tokenGlobally unique identifier
typeSINGLE_USE, MERCHANT_LOCKED, UNLOCKED, PHYSICAL

Create Card

API reference: Create card

Creates either a virtual or physical card [beta]. Parameters pin, shipping_address, and product_id only apply to physical cards.

🚧

Before physical cards can be issued, there are a few onboarding steps with external party dependencies that must be completed. Reach out to [email protected] or your account rep for more information. Steps required include:

  1. Establish and validate new BINs with the network and card manufacturer; this ensures that BINs are set up correctly and are ready for use, that transactional data will be sent securely, and that physical cards can be issued by the manufacturer
  2. Set up requirements for card manufacturing (e.g., card art)
  3. Test and confirm card configurations (e.g., spend testing, shipping) for final approval
POST https://api.lithic.com/v1/card

Sample Request

curl https://api.lithic.com/v1/card \
  -X POST \
  -H "Authorization: api-key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"memo":"New Card","spend_limit":100,"spend_limit_duration":"TRANSACTION","state":"OPEN","type":"SINGLE_USE"}'

Sample Response

{
  "created": "2021-06-28T22:53:15Z",
  "cvv": "776",
  "exp_month": "06",
  "exp_year": "2027",
  "funding": {
    "account_name": "Sandbox",
    "created": "2020-07-08 17:57:36",
    "last_four": "5263",
    "nickname": "",
    "state": "ENABLED",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING"
  },
  "hostname": "",
  "last_four": "4142",
  "memo": "New Card",
  "pan": "4111111289144142",
  "spend_limit": 100,
  "spend_limit_duration": "TRANSACTION",
  "state": "OPEN",
  "token": "7ef7d65c-9023-4da3-b113-3b8583fd7951",
  "type": "SINGLE_USE"
}
memo (optional)Friendly name to identify the card
typeSINGLE_USE, MERCHANT_LOCKED, DIGITAL_WALLET, UNLOCKED, PHYSICAL (Unlocked & physical cards require additional privileges. All physical cards have digital wallet functionality and are unlocked)
funding_token (optional)The token for the desired FundingAccount to use when making transactions with this card
spend_limit (optional)Amount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined
spend_limit_duration (optional)TRANSACTION, MONTHLY, ANNUALLY, FOREVER
state (optional)OPEN, PAUSED
card_program_token (optional)Identifies the card program under which to create the card. Different card programs may have their own configurations (e.g., digital wallet card art, BIN type). This must be configured with Lithic before use
exp_month (optional)Two digit (MM) expiry month. If neither exp_month nor exp_year is provided, an expiration date will be generated
exp_year (optional)Four digit (yyyy) expiry year. If neither exp_month nor exp_year is provided, an expiration date will be generated
account_token (multi-account users only)Token identifying the account the card will be associated with. Only applicable if using account enrollment. See Managing Identities for more information
pin (optional)Encrypted PIN block (in base64). Only applies to cards of type PHYSICAL [beta]. See Encrypted PIN Block
product_id (optional)Specifies the configuration (e.g., physical card art) that the card should be manufactured with, and only applies to cards of type PHYSICAL [beta]. This must be configured with Lithic before use
shipping_address (optional)Shipping Address. Only applies to cards of type PHYSICAL [beta]

Update Card

API reference: Update card

Update the specified properties of the card. Unsupplied properties will remain unchanged. pin parameter only applies to physical cards [beta].

🚧

Setting a card to a CLOSED state is a final action that cannot be undone.

PUT https://api.lithic.com/v1/card

API reference: Update card

Sample Request

curl https://api.lithic.com/v1/card \
  -X PUT \
  -H "Authorization: api-key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"memo":"Sample Name","spend_limit":100,"spend_limit_duration":"FOREVER","state":"OPEN","card_token":"f5f905f5-8a8e-49bf-a9b4-c0adaa401456"}'

Sample Response

{
  "created": "2021-05-07T17:27:46Z",
  "cvv": "742",
  "exp_month": "05",
  "exp_year": "2027",
  "funding": {
    "account_name": "Sandbox",
    "created": "2020-07-08 17:57:36",
    "last_four": "5263",
    "nickname": "",
    "state": "ENABLED",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING"
  },
  "hostname": "",
  "last_four": "4938",
  "memo": "Sample Name",
  "pan": "4111111222794938",
  "spend_limit": 100,
  "spend_limit_duration": "FOREVER",
  "state": "OPEN",
  "token": "f5f905f5-8a8e-49bf-a9b4-c0adaa401456",
  "type": "SINGLE_USE"
}
card_tokenThe unique token of the card to update
state (optional)OPEN, PAUSED, CLOSED
funding_token (optional)The token for the desired FundingAccount to use when making transactions with this card
memo (optional)Friendly name to identify the card
spend_limit (optional)Amount (in cents) to limit approved authorizations. Transaction requests above the spend limit will be declined
spend_limit_duration (optional)TRANSACTION, MONTHLY, ANNUALLY, FOREVER
account_token (multi-account users only)Token identifying the account which owns the card. Only applicable if using account enrollment. See Managing Identities for more information
pin (optional)Encrypted PIN block (in base64). Only applies to cards of type PHYSICAL [beta]. See Encrypted PIN Block

List Cards

API reference: Get cards

GET https://api.lithic.com/v1/card

Sample Request

curl https://api.lithic.com/v1/card \
  -H "Authorization: api-key YOUR_API_KEY"

Sample Response

{
  "data": [
    {
      "created": "2021-05-07T17:27:46Z",
      "cvv": "742",
      "exp_month": "05",
      "exp_year": "2027",
      "funding": {
          "account_name": "Sandbox",
          "created": "2020-07-08 17:57:36",
          "last_four": "5263",
          "nickname": "",
          "state": "ENABLED",
          "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
          "type": "DEPOSITORY_CHECKING"
      },
      "hostname": "",
      "last_four": "4938",
      "memo": "Samplejka",
      "pan": "4111111222794938",
      "spend_limit": 100,
      "spend_limit_duration": "FOREVER",
      "state": "OPEN",
      "token": "f5f905f5-8a8e-49bf-a9b4-c0adaa401456",
      "type": "SINGLE_USE"
    },
  ],
  "page": 1,
  "total_entries": 1,
  "total_pages": 1
}
pageFor pagination. The default is 1
page_sizeFor pagination. The default value page size is 50 and the maximum is 1,000
beginDate string in the form YYYY-MM-DD, only cards created after the specified date will be included
endDate string in the form YYYY-MM-DD, only cards created before the specified date will be included
card_tokenReturns a specific card
account_token (multi-account users only)Returns cards associated with this account. Only applicable if using account enrollment. See Managing Identities for more information

Any combination of the queries may be used together in the form:

[url]?[query field]=[query value]&[query field]=[query value]

Encrypted PIN Block (Enterprise)

Physical cards [beta] can be provisioned for ATM/PIN debit access which requires a cardholder PIN. The Create card and Update card endpoints can set and update the cardholder PIN.

🚧

Due to the sensitive nature, PINs must be encrypted on the frontend immediately after user input.

An Encrypted PIN block is a JSON blob, encrypted with the Lithic API public key, base64 digest.

api.lithic.com.pub.pem

{
  "nonce": Integer,
  "pin": String
}
nonceA cryptographic nonce to create additional entropy and prevent replay attacks. This should be unique per request. Integer should be at least 8 digits in length
pinCardholder PIN (between 4 and 12 numeric digits in length). String datatype to ensure leading zeros are not truncated

Examples

import base64
import json
import random

# pip install pycryptodome
from Crypto.Cipher    import PKCS1_OAEP
from Crypto.PublicKey import RSA

pin_block =  {
    "nonce": random.randint(1e8, 1e12),
    "pin": "1234"
}

with open("path/to/api.lithic.com.pub.pem") as f:
    cipher = PKCS1_OAEP.new(RSA.importKey(f.read()))

ciphertext = cipher.encrypt(json.dumps(pin_block).encode('utf-8'))

# Use this for the "pin" field value when creating or updating cards
encrypted_pin_block = base64.b64encode(ciphertext)
const fs = require("fs");

// npm install node-forge
const forge = require("node-forge");

const pem = fs.readFileSync("path/to/api.lithic.com.pub.pem", "utf8");
const publicKey = forge.pki.publicKeyFromPem(pem);

function randomInt(low, high) {
  // Generate random integer between low and high, inclusive
  return Math.floor(Math.random() * (high - low + 1) + low)
}

const pinBlock =  {
  "nonce": randomInt(1e8, 1e12),
  "pin": "1234"
}

const ciphertext = publicKey.encrypt(JSON.stringify(pinBlock), "RSA-OAEP", {
  md: forge.md.sha1.create(),
  mgf1: {
    md: forge.md.sha1.create()
  }
});

// Use this for the "pin" field value when creating or updating cards
const encryptedPinBlock = forge.util.encode64(ciphertext);
console.log(encryptedPinBlock);
package main

import (
    crand "crypto/rand"
    "crypto/rsa"
    "crypto/sha1"
    "crypto/x509"
    "encoding/base64"
    "encoding/json"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    rand "math/rand"
    "os"
    "time"
)

type PinBlock struct {
    Nonce int    `json:"nonce"`
    Pin   string `json:"pin"`
}

func checkError(err error) {
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
        os.Exit(1)
    }
}

func loadKey(fileName string) (*rsa.PublicKey, error) {
    rawPem, err := ioutil.ReadFile(fileName)
    checkError(err)

    pemBlock, _ := pem.Decode(rawPem)

    return x509.ParsePKCS1PublicKey(pemBlock.Bytes)
}

func encrypt(msg []byte, publicKey *rsa.PublicKey) (string, error) {
    encryptedBytes, err := rsa.EncryptOAEP(
        sha1.New(),
        crand.Reader,
        publicKey,
        msg,
        nil,
    )
    if err != nil {
        return "", err
    }
    encodedData := base64.StdEncoding.EncodeToString(encryptedBytes)
    return encodedData, nil
}

func generateNonce() int {
    rand.Seed(time.Now().UnixNano())
    min := int(1e8)
    max := int(1e12)
    return min + rand.Intn(max-min+1)
}

func main() {
    pemFile := "path/to/api.lithic.com.pub.pem"

    publicKey, err := loadKey(pemFile)
    
    pinBlock := &PinBlock{Nonce: generateNonce(), Pin: "1234"}
    pinBlockBytes, err := json.Marshal(pinBlock)
    checkError(err)
    fmt.Println(string(pinBlockBytes))

    // Use this for the "pin" field value when creating or updating cards
    encoded, err := encrypt(pinBlockBytes, publicKey)
    checkError(err)

    fmt.Println(encoded)
}

Reissue Card (Enterprise)

API reference: Reissue Card

Initiate print and shipment of a duplicate card. Only applies to cards of type PHYSICAL [beta].

POST https://api.lithic.com/v1/card/reissue

Sample Request

curl https://api.lithic.com/v1/card/reissue \
  -X POST \
  -H "Authorization: api-key YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"card_token":"589e1412-b132-48ac-ab5c-befd02535a57"}'

Sample Response

{
  "created": "2021-06-28T22:58:36Z",
  "cvv": "162",
  "exp_month": "06",
  "exp_year": "2027",
  "funding": {
    "account_name": "Sandbox",
    "created": "2020-07-08 17:57:36",
    "last_four": "5263",
    "nickname": "",
    "state": "ENABLED",
    "token": "b0f0d91a-3697-46d8-85f3-20f0a585cbea",
    "type": "DEPOSITORY_CHECKING"
  },
  "hostname": "",
  "last_four": "5205",
  "memo": "",
  "pan": "4111111540285205",
  "spend_limit": 0,
  "spend_limit_duration": "TRANSACTION",
  "state": "PENDING_FULFILLMENT",
  "token": "589e1412-b132-48ac-ab5c-befd02535a57",
  "type": "PHYSICAL"
}
card_tokenThe unique token of the card to update
shipping_address (optional)Shipping address. If omitted, the previous shipping address will be used
product_id (optional)Specifies the configuration (e.g., physical card art) that the card should be manufactured with, and only applies to cards of type PHYSICAL [beta]. This must be configured with Lithic before use

Enumerations

Card.type

SINGLE_USECard will close shortly after the first transaction
MERCHANT_LOCKEDCard is locked to first merchant that successfully authorizes the card
UNLOCKED (Issuing) Card will authorize at any merchant. Creating these cards requires additional privileges
PHYSICAL (Enterprise) Manufactured and sent to the cardholder. We offer white label branding, credit, ATM, PIN debit, chip/EMV, NFC and magstripe functionality. Contact [email protected] for more information
DIGITAL_WALLET (Enterprise) Cards that can be provisioned to a digital wallet like Google Pay or Apple Wallet

Card.state

OPENCard will approve authorizations (if they match card and account parameters)
PAUSEDCard will decline authorizations but can be resumed at a later time
CLOSEDCard will no longer approve authorizations. Closing a card cannot be undone
PENDING_FULFILLMENTThe initial state for cards of type PHYSICAL. The card is provisioned pending manufacturing and fulfillment. Cards in this state can accept authorizations for e-commerce purchases, but not for "Card Present" purchases where the physical card itself is present
PENDING_ACTIVATIONEach business day at 2pm Eastern Time Zone (ET), cards of type PHYSICAL in state PENDING_FULFILLMENT are sent to the card production warehouse and updated to state PENDING_ACTIVATION. Similar to PENDING_FULFILLMENT, cards in this state can be used for e-commerce transactions. API clients should update the card's state to OPEN only after the cardholder confirms receipt of the card.

In Sandbox, the same daily batch fulfillment occurs, but no cards are actually manufactured

Card.spend_limit_duration

TRANSACTIONCard will authorize multiple transactions if each individual transaction is under the spend limit
MONTHLYCard will authorize transactions up to spend limit for the trailing month. (Note month is calculated as this calendar date one month prior)
ANNUALLYCard will authorize transactions up to spend limit in a calendar year
FOREVERCard will authorize only up to spend limit for the entire lifetime of the card

Did this page help you?