# Cards ## Creating a Virtual Card **Pocket ID** and a single-use **4096 bit RSA** key pair (private and public key) in [PKCS#1](https://datatracker.ietf.org/doc/html/rfc8017) or [PKCS#1.5](https://datatracker.ietf.org/doc/html/rfc8017) 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. Pocket ID can be retrieved by following the steps [here](/products/partner-api/guides/building/pockets). 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. ```bash 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 "$( .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](https://datatracker.ietf.org/doc/html/rfc8017) or [PKCS#1.5](https://datatracker.ietf.org/doc/html/rfc8017) 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. ```bash 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 "$( .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](/products/partner-api/reference/sandbox/generate_physical_card_from_order_api_v1_sandbox_generate_card__post). To create a card order, call [Create Physical Card Order](/products/partner-api/reference/physical-cards/create_physical_card_order_api_v1_jiko_accounts__account_id__card_orders__post): ```bash 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: ```bash 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: ```bash 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. ```bash 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 ```