> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/pin-management/implement-pin-management/change-a-pin.md).

# Change a PIN

To limit the exposure of the PIN in a physical card, the issuer application delegates the task of changing the PIN to D1 SDK.

These are the PIN formats (from issuer backend) that are currently supported:

* PIN ISO0
* PIN 3DES Seccos

### User Experience

<figure><img src="/files/iMmbs7bCrCpiU1C9qm2o" alt=""><figcaption><p>Sample PIN change screen in the Issuer Application</p></figcaption></figure>

### Flow

<figure><img src="/files/2OLBw5xXg90sLUCZkrUk" alt=""><figcaption><p>High-level flow to change a PIN</p></figcaption></figure>

1. The user authenticates on the banking app and request to change the PIN
2. An internal call is made to the SDK
3. Capture securely the PIN
4. D1 BackEnd API
5. D1 transciphers the PIN from device key to Issuer key
6. Set the PIN to Issuer backend

### Sequence Diagram

#### Pre-requisites

* Consumer, account and card already registered in D1
* SDK is properly initialized
* Issuer App called D1 SDK login API.

<figure><img src="/files/WwoJSXekLX24YV43x2Ap" alt=""><figcaption><p>Sequence diagram for PIN change</p></figcaption></figure>

<figure><img src="/files/ZidavxDdwQT7M5kaVP06" alt=""><figcaption></figcaption></figure>

### Required APIs

| API                                                                                                                                                          | Inbound/Outbound    | Description                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------- | --------------------------------------------------------- |
| [Get authorization token](/pin-management/integrate-the-d1-api/d1-api-reference/outbound-api-from-d1/oauth2-api.md#post-oauth2-token)                        | Issuer <- Thales D1 | Get an OAuth 2.0 access token to call the Issuer backend. |
| [Set PIN](/pin-management/integrate-the-d1-api/d1-api-reference/outbound-api-from-d1/pin-management-api.md#put-cms-api-v1-issuers-issuerid-cards-cardid-pin) | Issuer <- Thales D1 | Set the PIN from mobile app to the Issuer backend.        |

### Conditional APIs

| API                                                                                                                                                                                           | Inbound/Outbound    | Description                                                                               |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----------------------------------------------------------------------------------------- |
| [Get PIN Change Counter API](/pin-management/integrate-the-d1-api/d1-api-reference/outbound-api-from-d1/pin-management-api.md#get-cms-api-v1-issuers-issuerid-cards-cardid-pin-changecounter) | Issuer <- Thales D1 | In case of PIN Seccos. Used to retreive the PIN Change Counter needed for PIN Computation |

### SDK

> #### Note
>
> For enhanced security, the Change PIN API has a stricter default last login timeout period than the other APIs. To ensure successful PIN change, you have to manage the login/re-login flow to complete the login within the allocated time before submitting the PIN change.

{% tabs %}
{% tab title="Android" %}

```java
@Nullable
@Override
public View onCreateView(
        @NonNull LayoutInflater inflater,
        @Nullable ViewGroup container,
        @Nullable Bundle savedInstanceState
) {
    View view = inflater.inflate(R.layout.fragment_main, container, false);

    SecureEditText entryEditPin = (SecureEditText)view.findViewById(R.id.pin_entry);
    SecureEditText confirmEditPin = (SecureEditText)view.findViewById(R.id.pin_confirm);
    PINEntryUI.PINEventListener listener = new PINEntryUI.PINEventListener() {
        @Override
        public void onPinEvent(PINEntryUI.PINEvent pinEvent, String additionalInfo) {
            switch (pinEvent){
                case FIRST_ENTRY_FINISH:
                    // switch focus to confirmEditPin
                    break;
                case PIN_MATCH:
                    // enable Continue/Submit button
                    break;
                case PIN_MISMATCH:
                    // disable Continue/Submit button and show error of PIN_MISMATCH
                    break;
            }
        }
    };

    String cardID = ""; // obtained e.g. from server
    ChangePINOptions options = new ChangePINOptions(4);
    pinEntryUI = d1Task.changePIN(cardID, entryEditPin, confirmEditPin, options, listener);

    Button button = (Button)view.findViewById(R.id.pin_submit);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            pinEntryUI.submit(new D1Task.Callback<Void>() {
                @Override
                public void onSuccess(final Void data) {
                }

                @Override
                public void onError(@NonNull final D1Exception exception) {
                }
            });
        }
    });
    
    return view;
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
class ViewController: UIViewController {
    var pinEntryUI: PINEntryUI? = nil
    override func viewDidLoad() {
        let entryEditPin = D1SecureTextField()
        let confirmEditPin = D1SecureTextField()
        let cardID = "" // obtained e.g. from server
        let options = ChangePINOptions(pinLength: 4)
        pinEntryUI = d1Task.changePIN(cardID, textFieldNew: entryEditPin, textFieldConfirm: confirmEditPin, options: options, delegate: self)
    }

    func onButtonClick() {
        pinEntryUI?.submit { error in 
        }
    }
}

extension ViewController: PINEntryUIDelegate {
    func pinEntryUI(_ pinEntryUI: PINEntryUI, pinEvent: PINEntryUI.PINEvent, additionalInfo: String) {
        switch pinEvent {
            case .firstEntryFinish: 
                // switch focus to confirmEditPin
                break
            case .pinMismatch:
                // enable Continue/Submit button
                break
            case .pinMatch:
                // disable Continue/Submit button and show error of PIN_MISMATCH
                break
        }
    }
}

```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/pin-management/implement-pin-management/change-a-pin.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
