---
title: Salesforce
description: 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>
