> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PrimerDelegate

export const TxnTag = ({status}) => {
  const getStyles = status => {
    const baseStyle = {
      display: 'inline-block',
      padding: '4px 8px',
      borderRadius: '4px',
      fontSize: '13px',
      fontWeight: '400'
    };
    switch (status) {
      case "PENDING":
        return {
          ...baseStyle,
          backgroundColor: '#ececec',
          color: '#9f9f9f'
        };
      case "AUTHORIZED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "SETTLED":
      case "PARTIALLY_SETTLED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "DECLINED":
      case "FAILED":
        return {
          ...baseStyle,
          backgroundColor: '#fef2f2',
          color: '#dc2626'
        };
      case "CANCELLED":
        return {
          ...baseStyle,
          backgroundColor: '#fefce8',
          color: '#d78203'
        };
      case "SETTLING":
        return {
          ...baseStyle,
          backgroundColor: '#e0f2fe',
          color: '#0c4a6e'
        };
      default:
        return {
          ...baseStyle,
          backgroundColor: '#f3f4f6',
          color: '#374151'
        };
    }
  };
  return <span style={getStyles(status)}>{status}</span>;
};

## Overview

Set the `PrimerDelegate` in order to receive different callbacks from Primer SDK.

## primerDidCompleteCheckoutWithData

```swift SWIFT theme={"dark"}
primerDidCompleteCheckoutWithData(_:additionalInfo:)
```

This method will be called with the when the payment has been completed, returning the payment's data.<br /><br />
⚠️ This method won't be called when you are using manual payment handling, or the vault manager.

### Parameters

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="additionalInfo" type="PrimerCheckoutAdditionalInfo">
    <Expandable title="direct subclasses" defaultOpen>
      <ResponseField name="XenditCheckoutVoucherAdditionalInfo">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="expiresAt" type="String" required />

          <ResponseField name="couponCode" type="String" required />

          <ResponseField name="retailerName" type="String" required />
        </Expandable>
      </ResponseField>

      <ResponseField name="PromptPayCheckoutAdditionalInfo">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="expiresAt" type="String" required />

          <ResponseField name="qrCodeUrl" type="String" />

          <ResponseField name="qrCodeBase64" type="String" required />
        </Expandable>
      </ResponseField>

      <ResponseField name="MultibancoCheckoutAdditionalInfo">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="expiresAt" type="String" />

          <ResponseField name="entity" type="String" />

          <ResponseField name="reference" type="String" />
        </Expandable>
      </ResponseField>

      <ResponseField name="ACHAdditionalInfo">
        <Expandable title="Subclasses" defaultOpen>
          <ResponseField name="ACHBankAccountCollectorAdditionalInfo" type="ACHAdditionalInfo">
            <Expandable title="Properties" defaultOpen>
              <ResponseField name="collectorViewController" type="UIViewController">
                Provides the bank account collector for ACH bank account
                selection.
              </ResponseField>
            </Expandable>
          </ResponseField>

          <ResponseField name="ACHMandateAdditionalInfo" type="ACHAdditionalInfo">
            <p>
              Provides an empty <code>ACHMandateAdditionalInfo</code> object to
              prompt the merchant to display the mandate information.
            </p>
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Expandable>
  </ResponseField>
</Expandable>

### Example

```swift SWIFT theme={"dark"}
// 👇 Add this
import PrimerSDK

// 👇 Conform to PrimerDelegate
class MyViewController: UIViewController, PrimerDelegate {

	// ...

    // 👇 Add this
	func primerDidCompleteCheckoutWithData(_ data: PrimerCheckoutData) {
        // Do something with the payment's data
    }
}
```

## primerDidTokenizePaymentMethod

```swift SWIFT theme={"dark"}
func primerDidTokenizePaymentMethod(_:decisionHandler:)
```

This method will be called with the when the payment method has been tokenized, returning the payment method's tokenization data. Use the `token` to create a payment on your backend. Make sure that you call the `decisionHandler` once your operation has been completed.<br /><br />
⚠️ This method will be called only on the manual flow, or when vaulting.

### Parameters

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="paymentMethodTokenData" type="PrimerPaymentMethodTokenData">
    <Expandable title="Parameters" defaultOpen>
      <ResponseField name="analyticsId" type="String" />

      <ResponseField name="id" type="String" />

      <ResponseField name="paymentInstrumentData" type="PaymentInstrumentData">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="paymentMethodConfigId" type="String" />

          <ResponseField name="paymentMethodType" type="String" />

          <ResponseField name="sessionInfo" type="SessionInfo" />

          <ResponseField name="first6Digits" type="String" />

          <ResponseField name="last4Digits" type="String" />

          <ResponseField name="accountNumberLast4Digits" type="String" />

          <ResponseField name="expirationMonth" type="String" />

          <ResponseField name="expirationYear" type="String" />

          <ResponseField name="cardholderName" type="String" />

          <ResponseField name="network" type="String" />

          <ResponseField name="isNetworkTokenized" type="String" />

          <ResponseField name="binData" type="BinData" />

          <ResponseField name="threeDSecureAuthentication" type="ThreeDS.AuthenticationDetails" />

          <ResponseField name="paypalBillingAgreementId" type="String" />

          <ResponseField name="externalPayerInfo" type="ExternalPayerInfo">
            Additional PayPal data.

            <Expandable title="Properties" defaultOpen>
              <ResponseField name="email" type="String">
                The payer's email address.
              </ResponseField>

              <ResponseField name="externalPayerId" type="String?">
                The payer's unique ID.
              </ResponseField>

              <ResponseField name="firstName" type="String?">
                The payer's given name.
              </ResponseField>

              <ResponseField name="lastName" type="String?">
                The payer's given surname.
              </ResponseField>
            </Expandable>
          </ResponseField>

          <ResponseField name="shippingAddress" type="ShippingAddress" />

          <ResponseField name="klarnaCustomerToken" type="String" />

          <ResponseField name="sessionData" type="SessionData" />

          <ResponseField name="bankName" type="String" />
        </Expandable>
      </ResponseField>

      <ResponseField name="paymentInstrumentType" type="PaymentInstrumentType">
        <Expandable title="Cases" defaultOpen>
          <ResponseField name="paymentCard" />

          <ResponseField name="offSession" />

          <ResponseField name="cardOffSession" />

          <ResponseField name="payPalOrder" />

          <ResponseField name="payPalBillingAgreement" />

          <ResponseField name="applePay" />

          <ResponseField name="googlePay" />

          <ResponseField name="klarna" />

          <ResponseField name="klarnaPaymentSession" />

          <ResponseField name="klarnaCustomerToken" />

          <ResponseField name="apayaToken" />

          <ResponseField name="hoolah" />

          <ResponseField name="unknown" />
        </Expandable>
      </ResponseField>

      <ResponseField name="threeDSecureAuthentication" type="ThreeDS.AuthenticationDetails" />

      <ResponseField name="token" type="String" required />

      <ResponseField name="tokenType" type="TokenType">
        <Expandable title="Cases" defaultOpen>
          <ResponseField name="multiUse" />

          <ResponseField name="singleUse" />
        </Expandable>
      </ResponseField>

      <ResponseField name="vaultData" type="VaultData" />
    </Expandable>
  </ResponseField>

  <ResponseField name="decisionHandler" type="enum PrimerResumeDecision" required>
    <Expandable title="Cases" defaultOpen>
      <ResponseField name="succeed()">
        Call `.succeed` when you want to show the success screen, or finalize the flow successfully in case you have hidden the success screen.
      </ResponseField>

      <ResponseField name=".fail(withErrorMessage:)">
        Call `.fail` when you want to show the error screen, or finalize the flow with error in case you have hidden the error screen.
      </ResponseField>

      <ResponseField name=".continueWithNewClientToken(_:)">
        Call `.continueWithNewClientToken` when the payment has entered in a <TxnTag status="PENDING" /> state and a required action client token has been provided.
      </ResponseField>
    </Expandable>
  </ResponseField>
</Expandable>

### Example

```swift SWIFT theme={"dark"}
// 👇 Add this
import PrimerSDK

// 👇 Conform to PrimerDelegate
class MyViewController: UIViewController, PrimerDelegate {

	// ...

    // 👇 Add this
	func primerDidTokenizePaymentMethod(_ paymentMethodTokenData: PrimerPaymentMethodTokenData, decisionHandler: @escaping (PrimerResumeDecision) -> Void) {
        // Create your payment
        createPayment(with: paymentMethodTokenData.token) { res, err in
            if let err = err {
                // 👇 Call the decisionHandler to show the error screen with your custom error message
                decisionHandler(.fail(withErrorMessage: "Oh no, something went wrong creating the payment..."))

            } else if let res = res {
                if let newClientToken = res.requiredAction?.clientToken {
                    // 👇 Call the decisionHandler with the new client token to continue the flow
                    decisionHandler(.continueWithNewClientToken(requiredAction.clientToken))
                } else {
                    // 👇 Call the decisionHandler to show the success screen
                    decisionHandler(.succeed())
                }
            }
        }
    }
}
```

## primerDidResumeWith

```swift SWIFT theme={"dark"}
func primerDidResumeWith(_:decisionHandler:)
```

This method will be called providing a `resumeToken` so you can resume the payment.<br /><br />
⚠️ This method will be called only on the manual flow when the payment is in a `.PENDING` state..

### Parameters

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="resumeToken" type="String" required>
    The token used to resume the payment.
  </ResponseField>

  <ResponseField name="decisionHandler" type="enum PrimerResumeDecision" required>
    <Expandable title="Cases" defaultOpen>
      <ResponseField name="succeed()">
        Call `.succeed` when you want to show the success screen, or finalize the flow successfully in case you have hidden the success screen.
      </ResponseField>

      <ResponseField name=".fail(withErrorMessage:)">
        Call `.fail` when you want to show the error screen, or finalize the flow with error in case you have hidden the error screen.
      </ResponseField>

      <ResponseField name=".continueWithNewClientToken(_:)">
        Call `.continueWithNewClientToken` when the payment has entered in a <TxnTag status="PENDING" /> state and a required action client token has been provided.
      </ResponseField>
    </Expandable>
  </ResponseField>
</Expandable>

### Example

```swift SWIFT theme={"dark"}
// 👇 Add this
import PrimerSDK

// 👇 Conform to PrimerDelegate
class MyViewController: UIViewController, PrimerDelegate {

	// ...

    // 👇 Add this
	func primerDidResumeWith(_ resumeToken: String, decisionHandler: @escaping (PrimerResumeDecision) -> Void)
        // Resume your payment
        resumePayment(with: resumeToken) { res, err in
            if let err = err {
                // 👇 Call the decisionHandler to show the error screen with your custom error message
                decisionHandler(.fail(withErrorMessage: "Oh no, something went wrong creating the payment..."))

            } else if let res = res {
                if let newClientToken = res.requiredAction?.clientToken {
                    // 👇 Call the decisionHandler with the new client token to continue the flow
                    decisionHandler(.continueWithNewClientToken(requiredAction.clientToken))
                } else {
                    // 👇 Call the decisionHandler to show the success screen
                    decisionHandler(.succeed())
                }
            }
        }
    }
}
```

## primerClientSessionWillUpdate

This method will be called to notify you that the client session will be updated, e.g.
a surcharge needs to be applied when a payment method has been chosen.

```swift SWIFT theme={"dark"}
func primerClientSessionWillUpdate()
```

## primerClientSessionDidUpdate

```swift SWIFT theme={"dark"}
func primerClientSessionDidUpdate(_ clientSession: PrimerClientSession)
```

This method will be called to notify you that the client session has been updated, e.g.
surcharge has been applied when a payment method has been chosen.

### Parameters

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="clientSession" type="PrimerClientSession" required>
    {}
  </ResponseField>
</Expandable>

## primerWillCreatePaymentWithData

This method will be called with just before the payment gets created, and lets you decide whether you want to proceed
with the payment creation.

⚠️ This method will be called only when checking out using the `auto` [flow](/sdk/ios/v2.x.x/common-objects/PrimerSettings).

```swift SWIFT theme={"dark"}
func primerWillCreatePaymentWithData(_ data: PrimerCheckoutPaymentMethodData, decisionHandler: @escaping (PrimerPaymentCreationDecision) -> Void)
```

### Parameters

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="data" type="PrimerCheckoutPaymentMethodData">
    <Expandable title="Parameters" defaultOpen>
      <ResponseField name="paymentMethodType" type="PrimerCheckoutPaymentMethodType">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="type" type="String" />
        </Expandable>
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="decisionHandler" type="enum PrimerPaymentCreationDecision" required>
    <Expandable title="Cases" defaultOpen>
      <ResponseField name=".continuePaymentCreation(withIdempotencyKey:)">
        Call `.continuePaymentCreation` when you want to continue with the payment creation.
        Optionally provide a `withIdempotencyKey` to prevent duplicate payments. The SDK attaches it as `X-Idempotency-Key` header on payment creation and resume requests. The same key is reused for the entire payment lifecycle and automatically cleared on completion or failure.
      </ResponseField>

      <ResponseField name=".abortPaymentCreation(withErrorMessage:)">
        Call `.abortPaymentCreation` when you want to abort the payment. Optionally you can provide an error message to get presented on the error screen.
      </ResponseField>
    </Expandable>
  </ResponseField>
</Expandable>

### Example

```swift SWIFT theme={"dark"}
// 👇 Add this
import PrimerSDK

// 👇 Conform to PrimerDelegate
class MyViewController: UIViewController, PrimerDelegate {

	// ...

    // 👇 Add this
	func primerWillCreatePaymentWithData(_ data: PrimerCheckoutPaymentMethodData, decisionHandler: @escaping (PrimerPaymentCreationDecision) -> Void)

    }
}
```

### Example with Idempotency Key

```swift SWIFT theme={"dark"}
class MyViewController: UIViewController, PrimerDelegate {
    func primerWillCreatePaymentWithData(
        _ data: PrimerCheckoutPaymentMethodData,
        decisionHandler: @escaping (PrimerPaymentCreationDecision) -> Void
    ) {
        let idempotencyKey = UUID().uuidString
        decisionHandler(.continuePaymentCreation(withIdempotencyKey: idempotencyKey))
    }
}
```

## primerDidEnterResumePendingWithPaymentAdditionalInfo

```swift SWIFT theme={"dark"}
func primerDidEnterResumePendingWithPaymentAdditionalInfo(_ additionalInfo: PrimerCheckoutAdditionalInfo?)
```

This method will be called when the payment cannot get settled at this time, and will get settled in the future (e.g. a voucher)

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="additionalInfo" type="PrimerCheckoutAdditionalInfo">
    <Expandable title="direct subclasses" defaultOpen>
      <ResponseField name="XenditCheckoutVoucherAdditionalInfo">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="expiresAt" type="String" required />

          <ResponseField name="couponCode" type="String" required />

          <ResponseField name="retailerName" type="String" required />
        </Expandable>
      </ResponseField>

      <ResponseField name="PromptPayCheckoutAdditionalInfo">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="expiresAt" type="String" required />

          <ResponseField name="qrCodeUrl" type="String" />

          <ResponseField name="qrCodeBase64" type="String" required />
        </Expandable>
      </ResponseField>

      <ResponseField name="MultibancoCheckoutAdditionalInfo">
        <Expandable title="Parameters" defaultOpen>
          <ResponseField name="expiresAt" type="String" />

          <ResponseField name="entity" type="String" />

          <ResponseField name="reference" type="String" />
        </Expandable>
      </ResponseField>

      <ResponseField name="ACHAdditionalInfo">
        <Expandable title="Subclasses" defaultOpen>
          <ResponseField name="ACHBankAccountCollectorAdditionalInfo" type="ACHAdditionalInfo">
            <Expandable title="Properties" defaultOpen>
              <ResponseField name="collectorViewController" type="UIViewController">
                Provides the bank account collector for ACH bank account
                selection.
              </ResponseField>
            </Expandable>
          </ResponseField>

          <ResponseField name="ACHMandateAdditionalInfo" type="ACHAdditionalInfo">
            <p>
              Provides an empty <code>ACHMandateAdditionalInfo</code> object to
              prompt the merchant to display the mandate information.
            </p>
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Expandable>
  </ResponseField>
</Expandable>

## primerDidFailWithError

```swift SWIFT theme={"dark"}
func primerDidFailWithError(_ error: Error, data: PrimerCheckoutData?, decisionHandler: @escaping ((PrimerErrorDecision) -> Void))
```

This method will be called when an error occurs. It may return `PrimerCheckoutData` if the occurs after the payment creation.
Make sure you call the `decisionHandler` to finalize the flow.

### Parameters

<Expandable title="Parameters" defaultOpen>
  <ResponseField name="error" type="Error" required>
    The error that occurred during the operation.
  </ResponseField>

  <ResponseField name="data" type="PrimerCheckoutData" post={["optional"]}>
    <Expandable title="Parameters" defaultOpen>
      <ResponseField name="additionalInfo" type="PrimerCheckoutAdditionalInfo">
        <Expandable title="direct subclasses" defaultOpen>
          <ResponseField name="XenditCheckoutVoucherAdditionalInfo">
            <Expandable title="Parameters" defaultOpen>
              <ResponseField name="expiresAt" type="String" required />

              <ResponseField name="couponCode" type="String" required />

              <ResponseField name="retailerName" type="String" required />
            </Expandable>
          </ResponseField>

          <ResponseField name="PromptPayCheckoutAdditionalInfo">
            <Expandable title="Parameters" defaultOpen>
              <ResponseField name="expiresAt" type="String" required />

              <ResponseField name="qrCodeUrl" type="String" />

              <ResponseField name="qrCodeBase64" type="String" required />
            </Expandable>
          </ResponseField>

          <ResponseField name="MultibancoCheckoutAdditionalInfo">
            <Expandable title="Parameters" defaultOpen>
              <ResponseField name="expiresAt" type="String" />

              <ResponseField name="entity" type="String" />

              <ResponseField name="reference" type="String" />
            </Expandable>
          </ResponseField>

          <ResponseField name="ACHAdditionalInfo">
            <Expandable title="Subclasses" defaultOpen>
              <ResponseField name="ACHBankAccountCollectorAdditionalInfo" type="ACHAdditionalInfo">
                <Expandable title="Properties" defaultOpen>
                  <ResponseField name="collectorViewController" type="UIViewController">
                    Provides the bank account collector for ACH bank account
                    selection.
                  </ResponseField>
                </Expandable>
              </ResponseField>

              <ResponseField name="ACHMandateAdditionalInfo" type="ACHAdditionalInfo">
                <p>
                  Provides an empty <code>ACHMandateAdditionalInfo</code> object to
                  prompt the merchant to display the mandate information.
                </p>
              </ResponseField>
            </Expandable>
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="decisionHandler" type="PrimerErrorDecision" required>
    <Expandable title="enum cases" defaultOpen>
      <ResponseField name="fail(withErrorMessage:)" type="void">
        Call with your custom error message.
      </ResponseField>
    </Expandable>
  </ResponseField>
</Expandable>

### Example

```swift SWIFT theme={"dark"}
// 👇 Add this
import PrimerSDK

// 👇 Conform to PrimerDelegate
class MyViewController: UIViewController, PrimerDelegate {

	// ...

    // 👇 Add this
	func primerDidFailWithError(_ error: Error, data: PrimerCheckoutData?, decisionHandler: @escaping ((PrimerErrorDecision) -> Void)) {

    }
}
```

## primerDidDismiss

This method will be called to notify you that the Primer SDK has been dismissed.

```swift SWIFT theme={"dark"}
func primerDidDismiss()
```
