> 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/classic-push-provisioning/es/casos-de-uso/aprovisionamiento-push-para-carteras-xpay/ios/aprovisionamiento-push.md).

# Aprovisionamiento push

## Paso 1: Mostrar el **Agregar a Wallet** botón <a href="#step-1-showing-the-add-to-wallet-button" id="step-1-showing-the-add-to-wallet-button"></a>

Cuando el usuario final inicia por primera vez la aplicación del emisor, debe determinar si mostrar u ocultar el **Agregar a Apple Wallet** botón para una tarjeta específica.

Lo antes posible, determine si el usuario final tiene un iPhone o un iPhone emparejado con un Apple Watch.

Luego combine este estado de emparejamiento con el `getToken` resultado de la API para decidir si mostrar u ocultar el **Agregar a Apple Wallet** botón.

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

```swift
importar WatchConnectivity

class ViewController: UIViewController, TPCSDKProvisionDelegate, WCSessionDelegate {    
    // Para almacenar el valor isWatchPaired antes de llamar a la función TPC
    var isWatchPaired = false

    override func viewDidLoad() {
        super.viewDidLoad()
        // Realizar cualquier configuración adicional después de cargar la vista.
        if WCSession.isSupported() {
            let session = WCSession.default
            session.delegate = self
            session.activate()
        }
    }
    
    // MARK: WCSessionDelegate
    func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
        if error != nil {
            //manejar error
        } else if activationState == .activated && session.isPaired {
            isWatchPaired = true
        }
    }
    
    func sessionDidBecomeInactive(_ session: WCSession) {
        // manejar sessionDidBecomeInactive
        isWatchPaired = false
    }
    
    func sessionDidDeactivate(_ session: WCSession) {
        // manejar sessionDidDeactivate
        isWatchPaired = false
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
#import <WatchConnectivity/WatchConnectivity.h>

@interface ViewController : UIViewController <TPCSDKProvisionDelegate, WCSessionDelegate>
@property BOOL isWatchPaired;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    if ([WCSession isSupported]) {
        WCSession* session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }
}

// MARK: WCSessionDelegate
- (void)session:(nonnull WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState error:(nullable NSError *)error { 
    if (error != nil) {
        // manejar error
    } else if (activationState == WCSessionActivationStateActivated && session.isPaired == TRUE)  {
        _isWatchPaired = TRUE;
    }
}

- (void)sessionDidBecomeInactive:(nonnull WCSession *)session { 
    // manejar sessionDidBecomeInactive
    _isWatchPaired = FALSE;
}

- (void)sessionDidDeactivate:(nonnull WCSession *)session { 
    // manejar sessionDidDeactivate
    _isWatchPaired = FALSE;
}
```

{% endtab %}
{% endtabs %}

Luego llame a la `getToken` API para actualizar el resultado.

> <i class="fa-info-circle">:info-circle:</i>
>
> #### Nota <a href="#note" id="note"></a>
>
> Consulte las [PKAddPassButton](https://developer.apple.com/documentation/passkit/pkaddpassbutton) directrices para usar el **Agregar a Apple Wallet** botón en su aplicación del emisor.

Lo siguiente se aplica a iOS SDK 2.0.0 y versiones anteriores.

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

```swift
func getCardDigitizationResultWithFundingCardWithSchemeAndPayload() {
    let scheme = CardScheme.Mastercard
    let payload = "PAN cifrado PKCS7"
    
    let card = FundingCard(scheme: scheme,
                            encryptedPayload: payload)
    
    TPCSDK.getCardDigitizationResult(card: card) { [weak self]
        (primaryAccountIdentifier, sdkResult, error) in
        self?.updateUI(for: sdkResult, sdkError: error)
    }
  }

  func getCardDigitizationResultWithPrimaryAccountIdentifier() {
    let primaryAccountIdentifier = "primaryAccountIdentifier"

    TPCSDK.getCardDigitizationResult(primaryAccountIdentifier: primaryAccountIdentifier) { [weak self]
        (primaryAccountIdentifier, sdkResult, error) in
        self?.updateUI(for: sdkResult, sdkError: error)
    }
  }

  func getCardDigitizationResultWithPrimaryAccountNumberSuffix() {
      let scheme = "SCHEME" // VISA, MASTERCARD, AMEX, DISCOVER
      let encryptedPayload = "PAN cifrado PKCS7"
      let primaryAccountNumberSuffix = "Últimos 4 dígitos del PAN"

      let card = FundingCard(schemeString: scheme,
              encryptedPayload: encryptedPayload)

      TPCSDK.getCardDigitizationResult(card: card, primaryAccountNumberSuffix: primaryAccountNumberSuffix) { [weak self]
          (primaryAccountIdentifier, sdkResult, error) in
          self?.updateUI(for: sdkResult, sdkError: error)
      }
  }

func updateUI(for sdkResult: CardDigitizationResult?, sdkError: Error?) {
    if let error = sdkError {
      // manejar error
    } else if let sdkResult = sdkResult {
      if sdkResult.localPKPass?.secureElementPass?.passActivationState == .requiresActivation {
        // Consulte la gestión del ciclo de vida del token para la acción Activar. 
        // Hay una activación de tarjeta pendiente en el iPhone.
      } else if sdkResult.remotePKPass?.secureElementPass?.passActivationState == .requiresActivation {
        // Consulte la gestión del ciclo de vida del token para la acción Activar. 
        // Hay una activación de tarjeta pendiente en el Apple Watch.
      } else if sdkResult.localPKPass != nil && sdkResult.remotePKPass == nil {
        if isWatchPaired {
          // mostrar el botón "Agregar a Apple Wallet" para Apple Watch.
        } else {
          // Ocultar el botón "Agregar a Apple Wallet".
        }
      } else if sdkResult.localPKPass == nil {
        // mostrar el botón "Agregar a Apple Wallet".
      } else if sdkResult.localPKPass != nil && sdkResult.remotePKPass != nil {
        // la tarjeta ya está provisionada. Ocultar el botón "Agregar a Apple Wallet".
      }
    }
  }
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
- (void)getCardDigitizationResultWithFundingCardWithSchemeAndPayload {
    CardScheme scheme = CardSchemeMastercard;
    NSString* payload = @"PAN cifrado PKCS7";

    FundingCard* card = [[FundingCard alloc] initWithScheme:scheme
                                            encryptedPayload:payload];

    [TPCSDK getCardDigitizationResultWithCard:card
                     primaryAccountIdentifier:nil
                   primaryAccountNumberSuffix:nil
                                   completion:^(NSString* primaryAccountIdentifier, CardDigitizationResult* _Nullable sdkResult, NSError* _Nullable error) {
        [self updateUIForResult:sdkResult sdkError:error];
    }];
}

- (void)getCardDigitizationResultWithPrimaryAccountIdentifier {
    NSString* primaryAccountIdentifier = @"primaryAccountIdentifier";

    [TPCSDK getCardDigitizationResultWithCard:nil
                     primaryAccountIdentifier:primaryAccountIdentifier
                   primaryAccountNumberSuffix:nil
                                   completion:^(NSString* primaryAccountIdentifier, CardDigitizationResult* _Nullable sdkResult, NSError* _Nullable error) {
        [self updateUIForResult:sdkResult sdkError:error];
    }];
}

- (void)getCardDigitizationResultWithPrimaryAccountNumberSuffix {
    CardScheme scheme = CardSchemeMastercard;
    NSString* payload = @"PAN cifrado PKCS7";
    NSString* primaryAccountNumberSuffix = @"Últimos 4 dígitos del PAN";

    FundingCard * card = [[FundingCard alloc] initWithScheme:scheme
                                            encryptedPayload:payload];

    [TPCSDK getCardDigitizationResultWithCard:nil
                     primaryAccountIdentifier:nil
                   primaryAccountNumberSuffix:primaryAccountNumberSuffix
                                   completion:^(NSString* primaryAccountIdentifier, CardDigitizationResult* _Nullable sdkResult, NSError* _Nullable error) {
        [self updateUIForResult:sdkResult sdkError:error];
    }];
}

- (void)updateUIForResult:(CardDigitizationResult* _Nullable)sdkResult sdkError:(NSError * _Nullable) error {
    if (error != nil ) {
        // manejar el error
    } else if(sdkResult != nil){
        if ( sdkResult.localPKPass.secureElementPass.passActivationState == PKSecureElementPassActivationStateRequiresActivation ) {
            // Consulte la gestión del ciclo de vida del token para la acción Activar. 
            // Hay una activación de tarjeta pendiente en el iPhone.
        } else if ( sdkResult.remotePKPass.secureElementPass.passActivationState == PKSecureElementPassActivationStateRequiresActivation ) {
            // Consulte la gestión del ciclo de vida del token para la acción Activar. 
            // Hay una activación de tarjeta pendiente en el Apple Watch.
        } else if ( sdkResult.localPKPass != nil && sdkResult.remotePKPass == nil ) {
            if ( [self isWatchPaired] ) {
                // mostrar el botón "Agregar a Apple Wallet" para Apple Watch.
            } else {
                // Ocultar el botón "Agregar a Apple Wallet".
            }
        } else if ( sdkResult.localPKPass == nil ) {
            // mostrar el botón "Agregar a Apple Wallet".
        } else if ( sdkResult.localPKPass != nil && sdkResult.remotePKPass != nil ) {
            // la tarjeta ya está provisionada. Ocultar el botón "Agregar a Apple Wallet".
        }
    }
}
```

{% endtab %}
{% endtabs %}

Lo siguiente se aplica a iOS SDK 2.1.0 y posteriores.

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

```swift
func getTokenWithInputByLast4() {
    // Últimos cuatro dígitos de la tarjeta física (FPAN).
    let last4 = "1234" 
    let tokenInput = GetTokenInput(last4: last4)
    TPCSDK.getToken(input: tokenInput) { [weak self]
        (localPass, remotePass, error) in
        self?.updateUI(for: localPass, remotePass: remotePass, sdkError: error)
    }
}

// - Desde: 2.3.0
func getTokenWithInputBySerialNumber() {
    // Número de serie proporcionado por Apple Pay.
    let serialNumber = "Número de serie"
    let tokenInput = GetTokenInput(serialNumber: serialNumber)
    TPCSDK.getToken(input: tokenInput) { [weak self]
        (localPass, remotePass, error) in
        self?.updateUI(for: localPass, remotePass: remotePass, sdkError: error)
    }
}

func updateUI(for localPass: PKPass?, remotePass: PKPass?, sdkError: Error?) {
    if let error = sdkError {
        // Maneja el error.
    } else {
        if localPass?.secureElementPass?.passActivationState == .requiresActivation {
            // Consulte la gestión del ciclo de vida del token para la acción Activar. 
            // Hay una activación de tarjeta pendiente en el iPhone.
        } else if remotePass?.secureElementPass?.passActivationState == .requiresActivation {
            // Consulte la gestión del ciclo de vida del token para la acción Activar. 
            // Hay una activación de tarjeta pendiente en el Apple Watch.
        } else if localPass != nil && remotePass == nil {
            if isWatchPaired {
                // Muestra el botón "Agregar a Apple Wallet" para Apple Watch.
            } else {
                // Oculta el botón "Agregar a Apple Wallet".
            }
        } else if localPass == nil {
            // Muestra el botón "Agregar a Apple Wallet".
        } else if localPass != nil && remotePass != nil {
            // La tarjeta ya está provisionada. Ocultar el botón "Agregar a Apple Wallet".
        }
    }
}
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
- (void)getTokenWithInputByLast4 {
    // Últimos cuatro dígitos de la tarjeta física (FPAN).
    NSString *last4 = @"1234";

    GetTokenInput *tokenInput = [[GetTokenInput alloc] initWithLast4:last4];

    [TPCSDK getTokenWithInput:tokenInput completion:^(PKPass *_Nullable localPass, PKPass *_Nullable remotePass, NSError *_Nullable error) {
        [self updateUIForLocalPass:localPass remotePass:remotePass sdkError:error];
    }];
}

// - Desde: 2.3.0
- (void)getTokenWithInputBySerialNumber {
    // Número de serie proporcionado por Apple Pay.
    NSString *serialNumber = @"Número de serie";

    GetTokenInput *tokenInput = [[GetTokenInput alloc] initWithSerialNumber:serialNumber];

    [TPCSDK getTokenWithInput:tokenInput completion:^(PKPass *_Nullable localPass, PKPass *_Nullable remotePass, NSError *_Nullable error) {
        [self updateUIForLocalPass:localPass remotePass:remotePass sdkError:error];
    }];
}

- (void)updateUIForLocalPass:(PKPass *_Nullable)localPass remotePass:(PKPass *_Nullable)remotePass sdkError:(NSError *_Nullable)error {
    if (error != nil) {
        // Maneja el error.
    } else {
        if (localPass != nil && localPass.secureElementPass.passActivationState == PKSecureElementPassActivationStateRequiresActivation) {
            // Consulte la gestión del ciclo de vida del token para la acción Activar. 
            // Hay una activación de tarjeta pendiente en el iPhone.
        } else if (remotePass != nil && remotePass.secureElementPass.passActivationState == PKSecureElementPassActivationStateRequiresActivation) {
            // Consulte la gestión del ciclo de vida del token para la acción Activar. 
            // Hay una activación de tarjeta pendiente en el Apple Watch.
        } else if (localPass != nil && remotePass == nil) {
            if ([self isWatchPaired]) {
                // Muestra el botón "Agregar a Apple Wallet" para Apple Watch.
            } else {
                // Oculta el botón "Agregar a Apple Wallet".
            }
        } else if (localPass == nil) {
            // Muestra el botón "Agregar a Apple Wallet".
        } else if (localPass != nil && remotePass != nil) {
            // La tarjeta ya está provisionada. Ocultar el botón "Agregar a Apple Wallet".
        }
    }
}
```

{% endtab %}
{% endtabs %}

> <i class="fa-exclamation-circle">:exclamation-circle:</i>
>
> #### Precaución <a href="#caution" id="caution"></a>
>
> * Si la tarjeta aún aparece como "NOT\_DIGITIZED" después de la provisión, verifique que la aplicación del emisor esté configurada correctamente en el portal TSP.
> * El `TPCSDK.isCardDigitized` API está en desuso y no se recomienda. Use la `getToken` API en su lugar. El `isCardDigitized` API no indica si la tarjeta está pendiente de activación o si está en un iPhone o en un Apple Watch.

## Paso 2: Provisionar una tarjeta <a href="#step-2-provisioning-a-request" id="step-2-provisioning-a-request"></a>

El delegado de provisión devuelve un [PKPass](https://developer.apple.com/documentation/passkit/pkpass) después de que la provisión se complete. Úselo para verificar el estado de digitalización de la tarjeta. Si el delegado devuelve `nil`, el SDK también devuelve un error.

Antes de usar la clase PKPass, asegúrese de agregar PassKit.framework a su proyecto.

> <i class="fa-exclamation-circle">:exclamation-circle:</i>
>
> #### Advertencia <a href="#warning" id="warning"></a>
>
> Debe agregar el derecho de Push Provisioning a la aplicación del emisor antes de llamar a esta API. De lo contrario, la API devolverá un error. Para obtener el derecho, siga las [directrices de acceso a Push Provisioning](/classic-push-provisioning/es/guia-del-desarrollador/configuracion-del-sdk/ios.md).

> <i class="fa-info-circle">:info-circle:</i>
>
> Use la `getToken` API para obtener `localPKPass` o `remotePKPass`. Si cualquiera de los `localPKPass` o `remotePKPass` no es `nil`, acceda a la `primaryAccountIdentifier` propiedad del [`PKSecureElementPass`](https://developer.apple.com/documentation/passkit/pksecureelementpass) objeto. Pase el `primaryAccountIdentifier` recuperado `a la` provision

### API. <a href="#provisioning-with-standard-scheme-enum-types-for-visa-mastercard-amex-and-discover" id="provisioning-with-standard-scheme-enum-types-for-visa-mastercard-amex-and-discover"></a>

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

```swift
Provisión con valores de enumeración de esquema estándar para Visa, Mastercard, Amex y Discover
    func onProvisionCompletion(pass: PKPaymentPass?, error: Error?) {
      if let error = error {
          if let tpcError = error as? TPCError {
      } else {
          // manejar TPCError
          let provisionError = error as NSError
              if provisionError.domain == PKPassKitErrorDomain  {
              // error de Apple
              // https://developer.apple.com/documentation/passkit/pkaddpaymentpasserror
                  switch provisionError.code {
                      case PKAddPaymentPassError.unsupported.rawValue:
                  print("La aplicación no puede agregar tarjetas a Apple Pay.")
                      case PKAddPaymentPassError.userCancelled.rawValue:
                  print("El usuario canceló la solicitud para agregar una tarjeta a Apple Pay.")
                      case PKAddPaymentPassError.systemCancelled.rawValue:
                  print("El sistema canceló la solicitud para agregar una tarjeta a Apple Pay.")
                      default:
              }
          }
      }
    break
        } else if let pass = pass {
    }
  }
  
  // manejar resultado exitoso con el objeto pass
    func provision() {
    let suffix = "1234"
    let scheme = CardScheme.Mastercard
    let payload = "PAN cifrado PKCS7"
    let cardholderName = "John Doe"
    
    let code = "code"
                     TPCSDK.provision(fromController: self,
                     primaryAccountSuffix: suffix,
                     cardholderName: cardholderName,
                     scheme: scheme,
                     encryptedPayload: payload,
                     authorizationCode: code,
  }
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
provisionDelegate: self)
                                - (void)onProvisionCompletionWithPass:(PKPaymentPass * _Nullable)pass
    if (error != nil) {
        error:(NSError * _Nullable)error {
        // TODO: problema con la provisión
    }
}

// Consulte el código Swift para obtener más información
  - (void)provision {
  NSString * suffix = @"1234";
  NSString * cardholderName = @"John Doe";
  NSString * scheme = CardSchemeMastercard;
  NSString * payload = @"PAN cifrado PKCS7";

  NSString * code = @"code";
             [TPCSDK provisionFromController:self
                   primaryAccountSuffix:suffix
                           cardholderName:cardholderName
                 scheme:scheme
                encryptedPayload:payload
                authorizationCode:code
}
```

{% endtab %}
{% endtabs %}

### provisionDelegate:self]; <a href="#provisioning-with-a-scheme-string---standard" id="provisioning-with-a-scheme-string---standard"></a>

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

```swift
Provisión con valores de enumeración de esquema estándar para Visa, Mastercard, Amex y Discover
    func onProvisionCompletion(pass: PKPaymentPass?, error: Error?) {
      if let error = error {
          if let tpcError = error as? TPCError {
      } else {
          // manejar TPCError
          let provisionError = error as NSError
              if provisionError.domain == PKPassKitErrorDomain  {
              // error de Apple
              // https://developer.apple.com/documentation/passkit/pkaddpaymentpasserror
                  switch provisionError.code {
                      case PKAddPaymentPassError.unsupported.rawValue:
                  print("La aplicación no puede agregar tarjetas a Apple Pay.")
                      case PKAddPaymentPassError.userCancelled.rawValue:
                  print("El usuario canceló la solicitud para agregar una tarjeta a Apple Pay.")
                      case PKAddPaymentPassError.systemCancelled.rawValue:
                  print("El sistema canceló la solicitud para agregar una tarjeta a Apple Pay.")
                      default:
              }
          }
      }
    break
        } else if let pass = pass {
    }
  }
  
  // manejar resultado exitoso con el objeto pass
    func provision() {
    let suffix = "1234"
    let scheme = "SCHEME" // VISA, MASTERCARD, AMEX, DISCOVER
    let payload = "PAN cifrado PKCS7"
    let cardholderName = "John Doe"
    Provisión con una cadena de esquema (estándar)
    let primaryAccountIdentifier = "primaryAccountIdentifier"
    
    let code = "code"
                     TPCSDK.provision(fromController: self,
                     primaryAccountSuffix: suffix,
                     let productId = "productId" // Aplicable solo para esquemas nacionales. Esto puede obtenerse del Sistema de Gestión de Tarjetas del banco.
                     scheme: scheme,
                     encryptedPayload: payload,
                     schemeString: scheme,
                     productId: productId,
                     authorizationCode: code,
  }
```

{% endtab %}

{% tab title="Objective-C" %}

```objective-c
provisionDelegate: self)
                                - (void)onProvisionCompletionWithPass:(PKPaymentPass * _Nullable)pass
    if (error != nil) {
        error:(NSError * _Nullable)error {
        // TODO: problema con la provisión
    }
}

// Consulte el código Swift para obtener más información
  - (void)provision {
  NSString * suffix = @"1234";
  primaryAccountIdentifier:primaryAccountIdentifier,
  NSString * scheme = CardSchemeMastercard;
  NSString * payload = @"PAN cifrado PKCS7";
  NSString * scheme = @"SCHEME"; // VISA, MASTERCARD, AMEX, DISCOVER
  NSString * productId = @"productId"; // Aplicable solo para esquemas nacionales. Esto puede obtenerse del Sistema de Gestión de Tarjetas del banco.

  NSString * code = @"code";
             [TPCSDK provisionFromController:self
                   primaryAccountSuffix:suffix
                     NSString * primaryAccountIdentifier = @"primaryAccountIdentifier";
                 scheme:scheme
                encryptedPayload:payload
                        schemeString:scheme
         primaryAccountIdentifier:primaryAccountIdentifier                
                authorizationCode:code
}
```

{% 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/classic-push-provisioning/es/casos-de-uso/aprovisionamiento-push-para-carteras-xpay/ios/aprovisionamiento-push.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.
