Cards

Creating a Virtual Card

Account ID and a single-use 4096 bit RSA key pair (private and public key) in PKCS#1 or PKCS#1.5 format is required in order to create a virtual card. The RSA key pair should be discarded after use, and should originate from the client’s device. These key pairs are monitored for duplicates.

Account ID can be retrieved by following the steps here.

The public key will be used to encrypt sensitive information of the card (i.e. CVV, PAN, and expiration date) which will be included in the response. Response will return card_id, encrypted_cvv, encrypted_pan, and encrypted_expiration. The encrypted data can then be decrypted using the private key.

public_key="public_key.pem"
private_key="private_key.pem"
openssl genrsa -out $private_key 4096
openssl rsa -in $private_key -pubout -out $public_key


body=$(jq --null-input -c -r --arg public_key_body "$(<public_key.pem)" '{public_key: $public_key_body}')
response=$(send_jiko_request "POST" "/api/v1/jiko-accounts/$account_id/virtual-cards/" $body);


fields=("pan" "cvv" "expiration")
for field in "${fields[@]}"; do
   echo $response | jq -r ".encrypted_$field" | base64 -d > .temp_encrypted_data
   echo $field = $(openssl rsautl -decrypt -inkey private_key.pem -in .temp_encrypted_data)
done


rm .temp_encrypted_data $public_key $private_key

Getting Virtual Card Information

Similar to creating a virtual card, Account ID and a single-use 4096 bit RSA key pair in PKCS#1 or PKCS#1.5 format is required apart from the card_id.

Please note that the request method will be POST since the public_key must be included in the request body.

public_key="public_key.pem"
private_key="private_key.pem"
openssl genrsa -out $private_key 4096
openssl rsa -in $private_key -pubout -out $public_key


body=$(jq --null-input -c -r --arg public_key_body "$(<public_key.pem)" '{public_key: $public_key_body}')
response=$(send_jiko_request "POST" "/api/v1/jiko-accounts/$account_id/virtual-cards/$card_id/" $body);


fields=("pan" "cvv" "expiration")
for field in "${fields[@]}"; do
   echo $response | jq -r ".encrypted_$field" | base64 -d > .temp_encrypted_data
   echo $field = $(openssl rsautl -decrypt -inkey private_key.pem -in .temp_encrypted_data)
done


rm .temp_encrypted_data $public_key $private_key

Ordering a Physical Card

To order a physical card, a card order must be created. Like applications, card orders have statuses. The statuses are as follows:

Status Description
INITIAL A new card order starts out in this state.
CARD_CREATED The card order has been partially processed and now contains a card_id that can be used to set PIN, close the card and more. This state is very short-lived.
ORDERED The physical card has been ordered and will be delivered to the given address.
RECEIVED Once the PIN has been set by the end user, the card will be considered received. The card itself also has a status, NOT_ACTIVATED, that will be updated when the PIN is set.

In production, card orders are batch processed periodically, and will stay in the INITIAL state until processing starts. In the sandbox environment, each card order can be selectively processed by calling Generate Physical Card From Order.

To create a card order, call Create Physical Card Order:

body='{
  "name_on_card": "Jiko Customer",
  "shipping_address": {
    "street_address": "2000 Allston Way",
    "city": "Berkeley",
    "postal_code": "94701",
    "state": "CA",
    "country": "USA"
  }
}';
send_jiko_request "POST" "/api/v1/jiko-accounts/$account_id/card-orders/" $body);

In the sandbox, you can force the card order by extracting the card order id and calling POST:

card_order_id="id-from-response"
body='{
 "card_order_id": "'$card_order_id'"
}'
send_jiko_request "POST" "/api/v1/sandbox/generate-card/" $body);

After the card order is processed, a PIN must be set. Preferably, this happens once the end user has received their card, but can be done as soon as CARD_CREATED status is reached. Only once the PIN has been set will the user be able to swipe, dip, lock and open the card.

Setting the PIN

PIN is required to be encrypted at the client device before sending a request to the partner API service. Encryption should be done using the public key provided via Jiko Partner API.

Obtain available public keys:

endpoint="/api/v1/public_keys/";
curl --request GET --url https://$PREFIX.sandbox-api.jikoservices.com$endpoint

The response should return a public key in set_pin field. Encrypt the 4 digit pin using the public key in set_pin (4096-bit RSA with padding) and encode in base64.

curl --request GET \
 --url https://$PREFIX.sandbox-api.jikoservices.com/api/v1/public_keys/ | jq -r '.set_pin' > set_pin.pub
pin="1234"
encrypted_pin=$(echo $pin | openssl rsautl -encrypt -pubin -inkey set_pin.pub  | base64)
endpoint="/api/v1/jiko-accounts/$account_id/cards/$card_id/pin";
body='{
 "encrypted_pin": "'$encrypted_pin'"
}'
send_jiko_request "POST" "/api/v1/jiko-accounts/$account_id/cards/$card_id/pin" $body

Last updated: December 18, 2023