PIN management
Let your cardholders manage their personal identification numbers.
Some Point-of-Sale and ATM card terminals require cardholders to enter their card’s PIN to authenticate transactions. Cardholders also need to use their PINs with physical cards in many regions of the world. You can use the Stripe API and Stripe Elements to manage and view PINs on your issued cards.
Both physical card and virtual card PINs are set to a random value at creation. Cards created as a replacement for other cards won’t inherit the old card’s PIN. In test mode, all PINs are set to 0000 by default.
Set a card’s initial PIN at creation
When issuing a new card through the API, you can provide a desired PIN to be pre-set on the card. This is optional, and if you don’t provide an initial PIN, we randomly generate one for you. You can always view a card’s PIN.
To pre-set a PIN when issuing a new card, pass it in encrypted form as the pin.
parameter to the Create Card API method:
curl https://api.stripe.com/v1/issuing/cards \ -u
: \ -d "cardholder"="ich_1D4b3fdsa" \ -d "pin[encrypted_number]"="eyJhbGciOiJSU0..." -d "type"="virtual" \ -d "currency"="usd"sk_test_4eC39HqLyjWDarjtT1zdp7dc
See Encrypting PINs for more information about how to encrypt a PIN before passing it to the Stripe API or your own servers.
Note
When setting a card’s initial PIN in a request to the Create Card API method, the response to the creation request won’t return the PIN (in either encrypted or plain-text form).
View a card’s PIN
You can use Issuing Elements to retrieve a card’s PIN in a PCI-DSS-compliant way.
Use Issuing Elements
Stripe provides a browser-side JavaScript library that allows you to display the sensitive data (including PINs) of your Issuing cards in a PCI-compliant manner. The PIN renders inside of a Stripe-hosted iframe
and never touches your servers. Stripe offers this library as a part of Stripe.js.
All Issuing users, whether they’re PCI-compliant or not, can use Issuing Elements to retrieve PINs.
To retrieve a card’s PIN using Issuing Elements, first create an Issuing Elements integration, and then use it to display the issuingCardPinDisplay
Element:
const stripe = Stripe(
); const cardId = 'ic_abc123'; // ID of the issued Card you want to retrieve the PIN for const ephemeralKeyNonce = ...; const ephemeralKey = ...; // create the PIN Element with Stripe.js const pinElement = stripe.elements().create('issuingCardPinDisplay', { issuingCard: cardId, nonce: ephemeralKeyNonce, ephemeralKeySecret: ephemeralKey.secret, }); // Mount the PIN element onto DOM elements on your web page pinElement.mount('#card-pin');"pk_test_TYooMQauvdEDq54NiTphI7jx"
Change a card’s PIN
Change a card’s PIN at an ATM
Cardholders can change the PIN for their Stripe Issuing card at most ATMs. The cardholder must know the card’s current PIN to change it at an ATM. You can retrieve a card’s PIN before changing it. Some countries, such as France, don’t provide PIN management features at ATMs.
Unblock a card’s PIN
If you incorrectly enter a card’s PIN three consecutive times, the PIN becomes blocked. No further PIN-authenticated payments can be made through the card until the PIN is unblocked. Additionally, when a card’s online PIN is blocked, the card’s status is set to inactive
, and no payments of any kind can be made until the card is reactivated.
To unblock a card’s online PIN, and reactivate the card, use the Cards API to set its status to active
. You can also reactivate a card in your Stripe Dashboard.
In most countries, cardholders can unblock a card’s offline PIN at an ATM.
Encrypting PINs
To enable you to set a card’s PIN in a way that doesn’t require it to pass through your servers in plain text, the Stripe API expects you to provide PINs in an encrypted form.
Encrypt the desired PIN (for example, "0123"
) in JWE (JSON Web Encryption) format using Stripe’s RSA public key. When encrypting, use the RSA-OAEP
algorithm for key wrapping and A128CBC-HS256
for content encryption.
Stripe provides its public key for PIN encryption in both PKCS#8 and JWK format. Depending on your client environment and the library used, one might be easier to use than the other.
PIN encryption best practices
- Don’t cache, store, or reuse encrypted PINs for longer than necessary to call the Stripe API.
- Don’t encrypt PINs on your servers. Instead, perform encryption as soon as your user provides the PIN (for example, in your mobile application or in your web application’s frontend) and pass the encrypted form to your servers, and then on to the Stripe API.
- Don’t cache Stripe’s Issuing public key: we can change it or rotate it without notice. Instead, fetch it for every PIN operation you perform on the Stripe API.
- Don’t roll your own cryptography. JWE libraries are available for most common languages and platforms.
PIN encryption examples
The example above encrypts a PIN (0123) using JSON Object Signing and Encryption libraries for various languages. Equivalent libraries exist for other languages: