# Source: https://www.better-auth.com/llms.txt/docs/authentication/salesforce.md

# Salesforce

Salesforce provider setup and usage.



<Steps>
  <Step>
    ### Get your Salesforce Credentials

    1. Log into your Salesforce org (Production or Developer Edition)
    2. Navigate to **Setup > App Manager**
    3. Click **New Connected App**
    4. Fill in the basic information:
       * Connected App Name: Your app name
       * API Name: Auto-generated from app name
       * Contact Email: Your email address
    5. Enable OAuth Settings:
       * Check **Enable OAuth Settings**
       * Set **Callback URL** to your redirect URI (e.g., `http://localhost:3000/api/auth/callback/salesforce` for development)
       * Select Required OAuth Scopes:
         * Access your basic information (id)
         * Access your identity URL service (openid)
         * Access your email address (email)
         * Perform requests on your behalf at any time (refresh\_token, offline\_access)
    6. Enable **Require Proof Key for Code Exchange (PKCE)** (required)
    7. Save and note your **Consumer Key** (Client ID) and **Consumer Secret** (Client Secret)

    <Callout type="info">
      * For development, you can use `http://localhost:3000` URLs, but production requires HTTPS
      * The callback URL must exactly match what's configured in Better Auth
      * PKCE (Proof Key for Code Exchange) is required by Salesforce and is automatically handled by the provider
    </Callout>

    <Callout type="warning">
      For sandbox testing, you can create the Connected App in your sandbox org, or use the same Connected App but specify `environment: "sandbox"` in the provider configuration.
    </Callout>
  </Step>

  <Step>
    ### Configure the provider

    To configure the provider, you need to import the provider and pass it to the `socialProviders` option of the auth instance.

    ```ts title="auth.ts"
    import { betterAuth } from "better-auth"

    export const auth = betterAuth({
        socialProviders: {
            salesforce: { // [!code highlight]
                clientId: process.env.SALESFORCE_CLIENT_ID as string, // [!code highlight]
                clientSecret: process.env.SALESFORCE_CLIENT_SECRET as string, // [!code highlight]
                environment: "production", // or "sandbox" // [!code highlight]
            }, // [!code highlight]
        },
    })
    ```

    #### Configuration Options

    * `clientId`: Your Connected App's Consumer Key
    * `clientSecret`: Your Connected App's Consumer Secret
    * `environment`: `"production"` (default) or `"sandbox"`
    * `loginUrl`: Custom My Domain URL (without `https://`) - overrides environment setting
    * `redirectURI`: Override the auto-generated redirect URI if needed

    #### Advanced Configuration

    ```ts title="auth.ts"
    export const auth = betterAuth({
        socialProviders: {
            salesforce: {
                clientId: process.env.SALESFORCE_CLIENT_ID as string,
                clientSecret: process.env.SALESFORCE_CLIENT_SECRET as string,
                environment: "sandbox", // [!code highlight]
                loginUrl: "my-company.my.salesforce.com", // Custom My Domain // [!code highlight]
                redirectURI: "http://localhost:3000/api/auth/callback/salesforce", // Override if needed // [!code highlight]
            },
        },
    })
    ```

    <Callout type="info">
      * Use `environment: "sandbox"` for testing with Salesforce sandbox orgs
      * The `loginUrl` option is useful for organizations with My Domain enabled
      * The `redirectURI` option helps resolve redirect URI mismatch errors
    </Callout>
  </Step>

  <Step>
    ### Environment Variables

    Add the following environment variables to your `.env.local` file:

    ```bash title=".env.local"
    SALESFORCE_CLIENT_ID=your_consumer_key_here
    SALESFORCE_CLIENT_SECRET=your_consumer_secret_here
    BETTER_AUTH_URL=http://localhost:3000 # Important for redirect URI generation
    ```

    For production:

    ```bash title=".env"
    SALESFORCE_CLIENT_ID=your_consumer_key_here
    SALESFORCE_CLIENT_SECRET=your_consumer_secret_here
    BETTER_AUTH_URL=https://yourdomain.com
    ```
  </Step>

  <Step>
    ### Sign In with Salesforce

    To sign in with Salesforce, you can use the `signIn.social` function provided by the client. The `signIn` function takes an object with the following properties:

    * `provider`: The provider to use. It should be set to `salesforce`.

    ```ts title="auth-client.ts"
    import { createAuthClient } from "better-auth/client"
    const authClient = createAuthClient()

    const signIn = async () => {
        const data = await authClient.signIn.social({
            provider: "salesforce"
        })
    }
    ```
  </Step>

  <Step>
    ### Troubleshooting

    #### Redirect URI Mismatch Error

    If you encounter a `redirect_uri_mismatch` error:

    1. **Check Callback URL**: Ensure the Callback URL in your Salesforce Connected App exactly matches your Better Auth callback URL
    2. **Protocol**: Make sure you're using the same protocol (`http://` vs `https://`)
    3. **Port**: Verify the port number matches (e.g., `:3000`)
    4. **Override if needed**: Use the `redirectURI` option to explicitly set the redirect URI

    ```ts
    salesforce: {
        clientId: process.env.SALESFORCE_CLIENT_ID as string,
        clientSecret: process.env.SALESFORCE_CLIENT_SECRET as string,
        redirectURI: "http://localhost:3000/api/auth/callback/salesforce", // [!code highlight]
    }
    ```

    #### Environment Issues

    * **Production**: Use `environment: "production"` (default) with `login.salesforce.com`
    * **Sandbox**: Use `environment: "sandbox"` with `test.salesforce.com`
    * **My Domain**: Use `loginUrl: "yourcompany.my.salesforce.com"` for custom domains

    #### PKCE Requirements

    Salesforce requires PKCE (Proof Key for Code Exchange) which is automatically handled by this provider. Make sure PKCE is enabled in your Connected App settings.

    <Callout type="info">
      The default scopes requested are `openid`, `email`, and `profile`. The provider will automatically include the `id` scope for accessing basic user information.
    </Callout>
  </Step>
</Steps>