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

# Testing

> Use test credentials and best practices to test CardSwitcher functionality in development and production environments.

## Development

<Tabs>
  <Tab title="Bypass SDK">
    In the development environment, you can test the full flow - including webhooks and card data submission - without installing or invoking the SDK. This is useful for backend-only development & testing.

    <Steps>
      <Step title="Register a webhook" titleSize="h3">
        In your [Knot Dashboard](https://dashboard.knotapi.com/developers/webhooks), add a webhook endpoint for the development environment. This is where Knot will deliver the [`AUTHENTICATED`](/link/webhook-events/authenticated) and subsequent events.
      </Step>

      <Step title="Simulate a user authentication" titleSize="h3">
        Call the [Link Account](/api-reference/development/link-account) endpoint with `card_switcher: true`. This links a test merchant account to the Knot platform and fires an [`AUTHENTICATED`](/link/webhook-events/authenticated) webhook to your registered endpoint.

        ```bash theme={"system"}
        curl --request POST \
          --url https://development.knotapi.com/development/accounts/link \
          --header 'Authorization: Basic <encoded-value>' \
          --header 'Content-Type: application/json' \
          --data '
        {
          "external_user_id": "abc123",
          "merchant_id": 19,
          "card_switcher": true,
          "card_id": "81n9al10a0ayn13"
        }
        '
        ```
      </Step>

      <Step title="Handle the AUTHENTICATED webhook" titleSize="h3">
        When your server receives the [`AUTHENTICATED`](/link/webhook-events/authenticated) event, extract the `task_id` from the payload. You have 15 seconds to submit user & card data.
      </Step>

      <Step title="Encrypt and submit test user & card data" titleSize="h3">
        Retrieve the JWK from [Retrieve JWK](/api-reference/products/card-switcher/retrieve-jwk), encrypt the payload below, then POST to [Switch Card (JWE)](/api-reference/products/card-switcher/switch-card-jwe). See [Sending Card Data](/card-switcher/sending-card-data) for full code samples.

        <Tip>
          It is best practice to cache the JWK public key for an extended period (e.g. 1 day), rather than retrieve it on every merchant account authentication.
        </Tip>

        ```json theme={"system"}
        {
          "user": {
            "name": {
              "first_name": "Ada",
              "last_name": "Lovelace"
            },
            "address": {
              "street": "100 Main Street",
              "street2": "#100",
              "city": "NEW YORK",
              "region": "NY",
              "postal_code": "12345",
              "country": "US"
            },
            "phone_number": "+11234567890"
          },
          "card": {
            "number": "4242424242424242",
            "expiration": "08/2030",
            "cvv": "012"
          }
        }
        ```

        Knot will fire a [`CARD_UPDATED`](/card-switcher/webhook-events/card-updated) or [`CARD_FAILED`](/card-switcher/webhook-events/card-failed) webhook with the result.
      </Step>
    </Steps>
  </Tab>

  <Tab title="E2E Flow">
    <Steps>
      <Step title="Create a session" titleSize="h3">
        With your `client_id` and `secret` for the `development` environment, call [Create Session](https://docs.knotapi.com/api-reference/sessions/create-session) with `type: card_switcher` and a dummy `external_user_id`to create a session used when invoking the SDK.
      </Step>

      <Step title="Initialize the SDK" titleSize="h3">
        Use the `session_id` from the previous step to initialize the SDK.
      </Step>

      <Step title="Login to a merchant account" titleSize="h3">
        Use one of the sets of credentials below to simulate various authentication scenarios.

        | Scenario                  | Description                                                                                                 | Username             | Password    |
        | :------------------------ | :---------------------------------------------------------------------------------------------------------- | :------------------- | :---------- |
        | Successful authentication | Simulates a successful authentication to a merchant account.                                                | `user_good`          | `pass_good` |
        | One-time password (OTP)   | Simulates an authentication that requires an OTP. `1234` for a valid OTP and `0000` for an invalid OTP.     | `user_good`          | `pass_otp`  |
        | Invalid credentials       | Simulates a failed authentication due to invalid credentials.                                               | `credentials`        | `failed`    |
        | Account failure           | Simulates a failed authentication due to an issue with the user's merchant account.                         | `account`            | `failed`    |
        | Merchant failure          | Simulates a failed authentication due to an issue with the merchant.                                        | `merchant`           | `failed`    |
        | Too many attempts         | Simulates a failed authentication due to too many consecutive, failed login attempts.                       | `too many attempts`  | `failed`    |
        | Card not supported        | Simulates a failed card switch due to the card not being supported by the merchant.                         | `card not supported` | `failed`    |
        | Card expired              | Simulates a failed card switch due to the card having insufficient funds (for debit & prepaid cards).       | `insufficient funds` | `failed`    |
        | No subscription           | Simulates a failed card switch due to the user's lack of a paid subscription with the merchant.             | `subscription`       | `failed`    |
        | Subscription admin        | Simulates a failed card switch due to the user's account lacking the proper permissions to update the card. | `subscription admin` | `failed`    |
      </Step>

      <Step title="Handle the AUTHENTICATED webhook" titleSize="h3">
        When your server receives the [`AUTHENTICATED`](/link/webhook-events/authenticated) event, extract the `task_id` from the payload. You have 15 seconds to submit user & card data.
      </Step>

      <Step title="Encrypt and submit test user & card data" titleSize="h3">
        Retrieve the JWK from [Retrieve JWK](/api-reference/products/card-switcher/retrieve-jwk), encrypt the payload below, then POST to [Switch Card (JWE)](/api-reference/products/card-switcher/switch-card-jwe). See [Sending Card Data](/card-switcher/sending-card-data) for full code samples.

        <Tip>
          It is best practice to cache the JWK public key for an extended period (e.g. 1 day), rather than retrieve it on every merchant account authentication.
        </Tip>

        ```json theme={"system"}
        {
          "user": {
            "name": {
              "first_name": "Ada",
              "last_name": "Lovelace"
            },
            "address": {
              "street": "100 Main Street",
              "street2": "#100",
              "city": "NEW YORK",
              "region": "NY",
              "postal_code": "12345",
              "country": "US"
            },
            "phone_number": "+11234567890"
          },
          "card": {
            "number": "4242424242424242",
            "expiration": "08/2030",
            "cvv": "012"
          }
        }
        ```

        Knot will fire a [`CARD_UPDATED`](/card-switcher/webhook-events/card-updated) or [`CARD_FAILED`](/card-switcher/webhook-events/card-failed) webhook with the result.
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Production

Below are a set of best practices when testing Knot in production.

1. Ensure testing occurs from devices in the U.S. and with merchant accounts based in the U.S. International devices and accounts are not enabled.
2. Replicate real-life behavior:
   1. Do not attempt to provision multiple cards to the same merchant account multiple consecutive times in a short period. The merchant's fraud rules are likely to prevent this behavior.
   2. Do not attempt to provision the same card to multiple different accounts with the same merchant. Similar to the above, the merchant's fraud rule are likely to prevent this behavior.
   3. Do not attempt to log in to the same merchant multiple consecutive times in a short time frame on the same device.
   4. Do not attempt to log into the a merchant account while on a company VPN.
3. Ensure the proper personal information (beyond the card information) is being provided to Knot (typically in the call to [Switch Card](/api-reference/products/card-switcher/switch-card)). Many merchants require first name, last name, billing address, and/or phone number to update a card-on-file. The billing address may need to pass Address Verification Service (AVS) checks by the merchant. This information can come from a number of different places depending on your integration with Knot or your server's storage/retrieval of this information from other third parties (e.g. bank partner, processor, etc.).
4. Ensure the card that is being sent to Knot is active (i.e. not locked/frozen) and has sufficient funds (if a debit card). Many merchants attempt a small authorization hold of `$0.01` or `$1.00` on debit or prepaid cards.
5. If you are testing Knot's web SDK, ensure you are not logged in to the merchant in another browser tab at the same time as when logging in via the SDK.
6. If you choose to check if your card is actually provisioned to the merchant account after completing the flow in the Knot SDK:
   1. Allow a bit of time for the merchant account to update. Certain merchants can take a few minutes for the new card to be reflected in the account.
   2. Hard refresh the merchant account page and/or log out and log in again to see the newly provisioned card.
