Issue a business card

In sandbox, issue a card printed with a business customer's name to one of its associated persons.

Use this recipe in sandbox to issue a card printed with a business customer's name to one of the business's associated persons.

Who it is for. This recipe is for an expense platform whose client company wants its name printed on staff cards.

Status. Available in sandbox only. Not yet available in live. Contact support before you offer business cards.

Money example

The card shows the business name "Northwind Logistics".

  1. Jane, the finance lead, gets a card.
  2. You move 1,000 USD from the company account to the card.
  3. Jane pays a 240 USD software invoice. The card now holds 760 USD.

Before you start

KYB is KYC for a business, which checks the company and its people. See the Glossary.

Prerequisite How to check
A business customer with a business_name GET /v1/customers/{customer_id} on the business shows type business
The business finished KYB The business's basic KYC is completed
The cardholder is one of the business's associated persons and is verified The person is in associated_persons[].id, and that person's basic KYC is completed
Your card account See the hosted-check recipe
The person has no card application yet GET /v1/cards?customer_id=… returns nothing

Find out what is required

GET /v1/customers/{customer_id} on the business returns the business name, its KYB status and its associated persons. If one of them is missing, the application call names it.

Steps

1. Open the business card application

curl --request POST \
 --url https://api.gravv.xyz/v1/cards/applications/new \
 --header 'Api-Key: <API_KEY>' \
 --header 'Idempotency-Key: 19781350-fe75-4ff1-a062-47c62eb6352f' \
 --header 'Content-Type: application/json' \
 --data '
{
"type": "business",
"customer_id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
"business_customer_id": "0d6c2f4e-6a1b-4f0e-9b8f-5c2a7d3e1f00",
"account_id": "9b40be8d-9d74-4d2a-8897-dea3ef80ad23",
"annual_remuneration": 60000,
"estimated_monthly_limit": 3000,
"ip_address": "203.0.113.24"
}
'
const response = await fetch("https://api.gravv.xyz/v1/cards/applications/new", {
method: "POST",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Idempotency-Key": "19781350-fe75-4ff1-a062-47c62eb6352f",
"Content-Type": "application/json",
},
body: JSON.stringify({
"type": "business",
"customer_id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
"business_customer_id": "0d6c2f4e-6a1b-4f0e-9b8f-5c2a7d3e1f00",
"account_id": "9b40be8d-9d74-4d2a-8897-dea3ef80ad23",
"annual_remuneration": 60000,
"estimated_monthly_limit": 3000,
"ip_address": "203.0.113.24"
}),
});
console.log(response.status, await response.json());
import os

import requests

response = requests.post(
"https://api.gravv.xyz/v1/cards/applications/new",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
    "Idempotency-Key": "19781350-fe75-4ff1-a062-47c62eb6352f",
    "Content-Type": "application/json",
},
json={
    "type": "business",
    "customer_id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
    "business_customer_id": "0d6c2f4e-6a1b-4f0e-9b8f-5c2a7d3e1f00",
    "account_id": "9b40be8d-9d74-4d2a-8897-dea3ef80ad23",
    "annual_remuneration": 60000,
    "estimated_monthly_limit": 3000,
    "ip_address": "203.0.113.24",
},
)
print(response.status_code, response.json())
{
  "data": {
    "message": "Card application request successful",
    "status": true,
    "id": "b25fd467-a44e-4495-8b79-5e0cab2a876c"
  },
  "error": null
}

Set customer_id to the person and business_customer_id to the business. estimated_monthly_limit must not be above annual_remuneration. ip_address is the cardholder's IP address.

2. Check approval

List the applications with GET /v1/cards/applications. The item with this id shows application_status approved. Sandbox approves applications at once.

3. Issue the card

curl --request POST \
 --url https://api.gravv.xyz/v1/cards \
 --header 'Api-Key: <API_KEY>' \
 --header 'Idempotency-Key: 368f9b5b-3958-4de3-87c7-ea03e27a5165' \
 --header 'Content-Type: application/json' \
 --data '
{
"customer_id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
"card_type": "virtual",
"card_limit": 500,
"name_on_card": "Jane Doe"
}
'
const response = await fetch("https://api.gravv.xyz/v1/cards", {
method: "POST",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
"Idempotency-Key": "368f9b5b-3958-4de3-87c7-ea03e27a5165",
"Content-Type": "application/json",
},
body: JSON.stringify({
"customer_id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
"card_type": "virtual",
"card_limit": 500,
"name_on_card": "Jane Doe"
}),
});
console.log(response.status, await response.json());
import os

import requests

response = requests.post(
"https://api.gravv.xyz/v1/cards",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
    "Idempotency-Key": "368f9b5b-3958-4de3-87c7-ea03e27a5165",
    "Content-Type": "application/json",
},
json={
    "customer_id": "9e8d7c6b-5a49-4382-a1b0-c9d8e7f6a5b4",
    "card_type": "virtual",
    "card_limit": 500,
    "name_on_card": "Jane Doe",
},
)
print(response.status_code, response.json())

The first card's id is the application id. Next, top up the card.

What can go wrong

Response (HTTP 400) Why Fix
a business customer cannot hold a card; apply with type "business" for one of its associated persons customer_id is the business Send the person as customer_id and the business as business_customer_id
an associated person's card must be a business card; apply with type "business" and their business_customer_id The request has no type Add "type": "business"
business_customer_id is required when type is "business" business_customer_id is missing Send it
the business must complete KYB before cards can be issued under it The business is not verified Finish KYB
the business has no business_name to print on its cards The business has no business_name Update the business
customer_id is not an associated person of this business The person is not linked to the business Add the person to the business
basic level kyc needs to be completed to create an application The person is not verified. The API checks this first Verify the person
estimated_monthly_limit must be lesser than annual_renumeration estimated_monthly_limit is above annual_remuneration Lower estimated_monthly_limit
200 with an application that has no message The person already has a card application, and the API returns it unchanged Use a person with no application yet

Webhooks you will receive

Gravv sends no webhook when the application opens in sandbox. For funding and card events, see Top up a card.

Testing in sandbox

This recipe runs in sandbox. Sandbox KYC does not complete today, so you need an associated person verified earlier and with no card application.

Reference

Was this page helpful?