PIN management Invite Only

     

    Learn how to enable your customers to update or retrieve their PIN (Personal Identification Number).

    Retrieving and updating the PIN on a card is a flow that involves two-factor authentication (2FA) with the cardholder, and is initiated from the cardholder’s device. Stripe recommends that you implement that flow using the built-in services in the IOS and Android SDK, but you control the UI for your cardholders.

    For the cardholder, the UI will involve these steps:

    1. Request to retrieve their PIN or enter a new PIN to update, on a given card.
    2. Select a method for 2FA, either email or sms.
    3. An email or a SMS containing a one-time password gets sent to the phone number associated with the email configured in their cardholder object.
    4. A UI instructs them to enter that one-time password.
    5. The current PIN can be shown.as

    In the background, several actions involving both the phone and your servers will take place:

    Flow of action during the PIN retrieve or update actions

    Notes:

    • The PIN expires after five minutes. Use the expires_at property in the verification object to find out exactly when it will expire.
    • The PIN can be attempted three times, after which it will be rejected.
    • The limits (expiry and attempt counts) are per verification object. If your server requests a new verification object, then a new email/SMS will be sent and that new Verification object will have five minutes and three attempts.
    • In the process, your servers make two calls to Stripe on a given card: one sending a verification and one requesting an ephemeral key. Stripe expects your server to authenticate the cardholder owning the card before making those calls.
    • Stripe recommends that you have the cardholder enter a new PIN before starting the verification process, as the verification expires within five minutes.

    As a developer, to support PIN management, you must expose several new functionalities:

    On the server side

    • A new endpoint that receives a request for verification from an authenticated cardholder, and will call /v1/issuing/verifications. Pass the parameters:

      • card the id of the card considered
      • scope one of card_pin_retrieve, card_pin_update
      • verification_method one of sms, email
    • A new endpoint that receives a request for ephemeral key from an authenticated cardholder, and will call /v1/ephemeral_keys with:

      • issuing_card the id of the card considered

    On the Android side

    Download the latest Stripe Android SDK and implement the following:

    • A class that implements EphemeralKeyProvider where you write the createEphemeralKey method which will call your server and request an ephemeral key for a given card. Read more about Android ephemeral keys
    • When you have the verification id and one_time_code you can create a IssuingCardPinService and call either
      • retrievePin
      • updatePin Because those calls are asynchronous, you need to implement a IssuingCardPinRetrievalListener or IssuingCardPinUpdateListener to get success or error states.

    Example code:

    import com.stripe.android.EphemeralKeyProvider;
    import com.stripe.android.IssuingCardPinService;
    
    class CardEphemeralKeyProvider implements EphemeralKeyProvider {
    
      @Override
      public void createEphemeralKey(
        @NonNull @Size(min = 4) String apiVersion,
        @NonNull final EphemeralKeyUpdateListener keyUpdateListener) {
        // Here implement the call to your server to retrieve the ephemeral key
        keyUpdateListener.onKeyUpdate(responseStringFromServer);
      }
    
    }
    
     // Once you get the verificationId and oneTimeCode
     public void retrievePin(){
      CardEphemeralKeyProvider ephemeralKeyProvider = new CardEphemeralKeyProvider(cardId);
      IssuingCardPinService service = IssuingCardPinService.create(
        ApplicationProvider.getApplicationContext(),
        ephemeralKeyProvider);
      service.retrievePin(
        cardId, // eg: "ic_abc1234"
        verificationId, // eg: "iv_abc1234"
        oneTimeCode, // eg: "123456""
        new IssuingCardPinService.IssuingCardPinRetrievalListener() {
    
          @Override
          public void onIssuingCardPinRetrieved(@NonNull String pin) {
            // Implement the actions to take once the
            // PIN has been retrieved
          }
    
          @Override
          public void onError(
            @NonNull IssuingCardPinService.CardPinActionError errorCode,
            @Nullable String errorMessage,
            @Nullable Throwable exception) {
            // Handle errors. Errors codes will include
            // various one-time password errors
          }
    
      });
    

    On the IOS side

    Download the latest Stripe IOS SDK and implement the following:

    • A class that implements the protocol STPIssuingCardEphemeralKeyProvider where you write the createIssuingCardKeyWithAPIVersion method which will call your server and request an ephemeral key for a given card. Read more about IOS ephemeral keys
    • When you have the verification id and one_time_code you can create a STPPinManagementService and call either
      • retrievePin
      • updatePin Because those calls are asynchronous, you need to pass a completion block to get success or error states.

    Example code:

    #import "Stripe.h"
    
    @interface CardEphemeralKeyProvider : STPAPIClient<STPIssuingCardEphemeralKeyProvider>
    @end
    
    @implementation CardEphemeralKeyProvider
    - (void)createIssuingCardKeyWithAPIVersion:(nonnull NSString *)apiVersion
      completion:(nonnull STPJSONResponseCompletionBlock)completion {
        // Here implement the call to your server to retrieve the ephemeral key
        completion(responseStringFromServer, nil);
    }
    @end
    
    // Once you get the verificationId and oneTimeCode
    - (void)retrievePin {
      CardEphemeralKeyProvider *keyProvider = [[CardEphemeralKeyProvider alloc] init];
      STPPinManagementService *service = [[STPPinManagementService alloc] initWithKeyProvider:keyProvider]];
    
      [service retrievePin:@"ic_abc1234"
        verificationId:@"iv_abc1234"
        oneTimeCode:@"123456"
        completion:^(
          STPIssuingCardPin *cardPin,
          STPPinStatus status,
          NSError *error) {
            if (error == nil && status == STPPinSuccess) {
              NSString *pin = cardPin.pin;
              // Implement the actions to take once the
              // PIN has been retrieved
            }
            else{
              // Handle errors. Errors codes will include
              // various one-time password errors
            }
      }];
    }
    

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    On this page