--- title: "Change PIN using Adyen's iOS SDK" description: "Allow your cardholders change their personal identification number (PIN)." url: "https://docs.adyen.com/issuing/manage-card-data/change-pin-ios-sdk" source_url: "https://docs.adyen.com/issuing/manage-card-data/change-pin-ios-sdk.md" canonical: "https://docs.adyen.com/issuing/manage-card-data/change-pin-ios-sdk" last_modified: "2026-05-24T12:54:31+02:00" language: "en" --- # Change PIN using Adyen's iOS SDK Allow your cardholders change their personal identification number (PIN). [View source](/issuing/manage-card-data/change-pin-ios-sdk.md) In addition to allowing cardholders to view their card PIN, you can allow them to change their PIN within your app. This page explains how to implement a feature to securely change PINs in your user interface. To securely request a PIN change, you must use a base64-encoded [RSA](https://en.wikipedia.org/wiki/RSA_\(cryptosystem\)) public key and [Adyen's Card Reveal iOS SDK](https://github.com/Adyen/adyen-card-reveal-ios). With this SDK, you can generate a [PIN block](https://www.pcisecuritystandards.org/glossary/pin-block) that contains the new PIN that your cardholder wants to assign to their Adyen-issued card. You must send the encrypted PIN block to Adyen in a POST  [/pins/change](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change) request. Adyen then decrypts the PIN block and registers the new PIN. The following sequence diagram illustrates the workflow. ![](/user/pages/docs/07.issuing/17.manage-card-data/07.change-pin-ios-sdk/pin-change-sdk.svg?decoding=auto\&fetchpriority=auto) As shown in the diagram, the steps for changing a PIN are: 1. [Get a public key from Adyen](#get-public-key). 2. [Generate an encrypted PIN block](#generate-encrypted-pin-block). 3. [Request a PIN change to Adyen](#request-pin-change). ## Requirements Make sure that: * You have [API credentials](/issuing/manage-access/api-credentials-web-service) for the [Configuration API](https://docs.adyen.com/api-explorer/balanceplatform/latest/overview). * Your API credential has the **Bank Issuing PIN Change Webservice role**. * Your application uses iOS version 13.0 or higher. * You installed [Adyen's Card Reveal iOS SDK](https://github.com/Adyen/adyen-card-reveal-ios). ## Get a public key from Adyen You need a base64-encoded [RSA](https://en.wikipedia.org/wiki/RSA_\(cryptosystem\)) public key to [generate an encrypted session key](#encrypt-aes-key). Use the [Configuration API](https://docs.adyen.com/api-explorer/balanceplatform/latest/overview) to get the public key from Adyen. To get a public key: 1. Make a GET [/publicKey](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/publicKey) request, specifying the following query parameters: * [purpose](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/publicKey#query-purpose): **pinChange** * [format](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/publicKey#query-format): **pem** **Get a public key** #### curl ```bash curl https://balanceplatform-api-test.adyen.com/bcl/v2/publicKey?purpose=pinChange&format=pem \ -H 'x-api-key: ADYEN_BALANCE_PLATFORM_API_KEY' \ -H 'content-type: application/json' \ -X GET \ -d '' ``` #### Java ```java // Adyen Java API Library v33.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.balanceplatform.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.service.balancePlatform.*; Client client = new Client("ADYEN_BALANCE_PLATFORM_API_KEY", Environment.TEST); // Send the request ManageCardPinApi service = new ManageCardPinApi(client); PublicKeyResponse response = service.publicKey("String", "String", null); ``` #### PHP ```php setXApiKey("ADYEN_BALANCE_PLATFORM_API_KEY"); $client->setEnvironment(Environment::TEST); $requestOptions['queryParams'] = array('purpose' => 'string', 'format' => 'string'); // Send the request $service = new ManageCardPINApi($client); $response = $service->publicKey($requestOptions); ``` #### C\# ```cs // Adyen .net API Library v28.0.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.BalancePlatform; using Adyen.Service.BalancePlatform; var config = new Config() { XApiKey = "ADYEN_BALANCE_PLATFORM_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Send the request var service = new ManageCardPINService(client); var response = service.PublicKey(purpose: "string", format: "string"); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v23.3.0 const { Client, BalancePlatformAPI } = require('@adyen/api-library'); const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Send the request const balancePlatformAPI = new BalancePlatformAPI(client); const response = balancePlatformAPI.ManageCardPINApi.publicKey("string", "string"); ``` #### Go ```go // Adyen Go API Library v17.0.0 import ( "context" "github.com/adyen/adyen-go-api-library/v17/src/common" "github.com/adyen/adyen-go-api-library/v17/src/adyen" "github.com/adyen/adyen-go-api-library/v17/src/balancePlatform" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", Environment: common.TestEnv, }) // Send the request service := client.BalancePlatform() req := service.ManageCardPINApi.PublicKeyInput() req = req.Purpose("string").Format("string") res, httpRes, err := service.ManageCardPINApi.PublicKey(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.3.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_BALANCE_PLATFORM_API_KEY" adyen.client.platform = "test" # The environment to use library in. query_parameters = { "purpose" : "string", "format" : "string" } # Send the request result = adyen.balancePlatform.manage_card_pin_api.public_key(query_parameters=query_parameters) ``` #### Ruby ```rb # Adyen Ruby API Library v10.1.1 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_BALANCE_PLATFORM_API_KEY' adyen.env = :test # Set to "live" for live environment # Create the request object(s) query_params = { :purpose => 'string', :format => 'string' } # Send the request result = adyen.balancePlatform.manage_card_pin_api.public_key(query_params: query_params) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v23.3.0 import { Client, BalancePlatformAPI, Types } from "@adyen/api-library"; const client = new Client({ apiKey: "ADYEN_BALANCE_PLATFORM_API_KEY", environment: "TEST" }); // Send the request const balancePlatformAPI = new BalancePlatformAPI(client); const response = balancePlatformAPI.ManageCardPINApi.publicKey("string", "string"); ``` The response contains: * The public key * The expiry date of the public key **Response** ```json { "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMII...", "publicKeyExpiryDate": "2023-12-12" } ``` 2. Pass the [publicKey](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/publicKey#responses-200-publicKey) to your client. ## Generate an encrypted PIN block You must embed the PIN in an encrypted PIN block before sending it to Adyen. Do this with Adyen's Card Reveal iOS SDK as follows: 1. Initialize the `PinChangeService` method. **Initialize the service** ```swift let revealService = PinChangeService() ``` 2. Call the `encryptedPinBlock` method, passing the [publicKey](https://docs.adyen.com/api-explorer/balanceplatform/latest/get/publicKey#responses-200-publicKey) and the new PIN as parameters. **Generate encrypted PIN block** ```swift let encryptedPinBlock = revealService.encryptedPinBlock(withPem: publicKey, pin: pin) ``` Now, the `encryptedPinBlock` object contains the following data: * The [encryptedPinBlock](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-encryptedPinBlock) that you must send to Adyen. * The symmetric session [encryptedKey](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-encryptedKey) that you need to securely send the PIN block to Adyen. * The [token](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-token) that Adyen needs to decrypt your PIN block. ## Request a PIN change to Adyen To request a PIN change, make a POST  [/pins/change](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change) call and specify the following request parameters: | Parameter | Description | | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | | [paymentInstrumentId](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-paymentInstrumentId) | The unique identifier of the card for which you are changing the PIN. | | [encryptedKey](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-encryptedKey) | The symmetric session AES key. | | [token](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-token) | The token that you used to generate the encrypted PIN block. | | [encryptedPinBlock](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#request-encryptedPinBlock) | The [encrypted PIN block](#generate-encrypted-pin-block). | The following code sample shows how to request a PIN change. **Request a PIN change** #### curl ```bash curl https://balanceplatform-api-test.adyen.com/bcl/v2/pins/change \ -H 'x-api-key: ADYEN_BALANCE_PLATFORM_API_KEY' \ -H 'content-type: application/json' \ -X POST \ -d '{ "paymentInstrumentId": "PI0000000000000000000001", "encryptedKey": "75989E8881284D10153ABACF022EEA09F5...", "encryptedPinBlock": "63E5060591EF65F48DD1D4FECD0FECD5", "token" : "8374188662676926" }' ``` #### Java ```java // Adyen Java API Library v25.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.balancePlatform.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.service.balancePlatform.*; Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) PinChangeRequest pinChangeRequest = new PinChangeRequest() .encryptedKey("75989E8881284D10153ABACF022EEA09F5...") .paymentInstrumentId("PI6789678967896789") .encryptedPinBlock("63E5060591EF65F48DD1D4FECD0FECD5") .token("5555341244441115"); // Make the API call ManageCardPinApi service = new ManageCardPinApi(client); PinChangeResponse response = service.changeCardPin(pinChangeRequest, null); ``` #### PHP ```php // Adyen PHP API Library v17.4.0 use Adyen\Client; use Adyen\Environment; use Adyen\Model\BalancePlatform\PinChangeRequest; use Adyen\Service\BalancePlatform\ManageCardPINApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); $client->setEnvironment(Environment::TEST); // Create the request object(s) $pinChangeRequest = new PinChangeRequest(); $pinChangeRequest ->setEncryptedKey("75989E8881284D10153ABACF022EEA09F5...") ->setPaymentInstrumentId("PI6789678967896789") ->setEncryptedPinBlock("63E5060591EF65F48DD1D4FECD0FECD5") ->setToken("5555341244441115"); // Make the API call $service = new ManageCardPINApi($client); $response = $service->changeCardPin($pinChangeRequest); ``` #### C\# ```cs // Adyen .net API Library v14.4.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.BalancePlatform; using Adyen.Service.BalancePlatform; var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) PinChangeRequest pinChangeRequest = new PinChangeRequest { EncryptedKey = "75989E8881284D10153ABACF022EEA09F5...", PaymentInstrumentId = "PI6789678967896789", EncryptedPinBlock = "63E5060591EF65F48DD1D4FECD0FECD5", Token = "5555341244441115" }; // Make the API call var service = new ManageCardPINService(client); var response = service.ChangeCardPin(pinChangeRequest); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use const { Client, BalancePlatformAPI } = require('@adyen/api-library'); // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const pinChangeRequest = { paymentInstrumentId: "PI6789678967896789", encryptedKey: "75989E8881284D10153ABACF022EEA09F5...", encryptedPinBlock: "63E5060591EF65F48DD1D4FECD0FECD5", token: "5555341244441115" } // Make the API call const balancePlatformAPI = new BalancePlatformAPI(client); const response = balancePlatformAPI.ManageCardPINApi.changeCardPin(pinChangeRequest); ``` #### Go ```go // Adyen Go API Library v9.3.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/balancePlatform" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) pinChangeRequest := balancePlatform.PinChangeRequest{ EncryptedKey: "75989E8881284D10153ABACF022EEA09F5...", PaymentInstrumentId: "PI6789678967896789", EncryptedPinBlock: "63E5060591EF65F48DD1D4FECD0FECD5", Token: "5555341244441115", } // Make the API call service := client.BalancePlatform() req := service.ManageCardPINApi.ChangeCardPinInput().PinChangeRequest(pinChangeRequest) res, httpRes, err := service.ManageCardPINApi.ChangeCardPin(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.2.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "paymentInstrumentId": "PI6789678967896789", "encryptedKey": "75989E8881284D10153ABACF022EEA09F5...", "encryptedPinBlock": "63E5060591EF65F48DD1D4FECD0FECD5", "token": "5555341244441115" } # Make the API call result = adyen.balancePlatform.manage_card_pin_api.change_card_pin(request=json_request) ``` #### Ruby ```rb # Adyen Ruby API Library v9.3.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :paymentInstrumentId => 'PI6789678967896789', :encryptedKey => '75989E8881284D10153ABACF022EEA09F5...', :encryptedPinBlock => '63E5060591EF65F48DD1D4FECD0FECD5', :token => '5555341244441115' } # Make the API call result = adyen.balancePlatform.manage_card_pin_api.change_card_pin(request_body) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use import { Client, BalancePlatformAPI, Types } from "@adyen/api-library"; // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object(s) const pinChangeRequest: Types.balancePlatform.PinChangeRequest = { encryptedKey: "75989E8881284D10153ABACF022EEA09F5...", paymentInstrumentId: "PI6789678967896789", encryptedPinBlock: "63E5060591EF65F48DD1D4FECD0FECD5", token: "5555341244441115" }; // Make the API call const balancePlatformAPI = new BalancePlatformAPI(client); const response = balancePlatformAPI.ManageCardPINApi.changeCardPin(pinChangeRequest); ``` The response contains the [status](https://docs.adyen.com/api-explorer/balanceplatform/latest/post/pins/change#responses-200-status) of the request. Possible values: **completed**, **pending**, **unavailable**.