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

# eBay

> Connect eBay to your product through Chift's unified Payment API.

export const CoverageIframe = ({api = 'accounting', connectors}) => {
  const [theme, setTheme] = React.useState('light');
  const [isFullscreen, setIsFullscreen] = React.useState(false);
  const [currentIframeUrl, setCurrentIframeUrl] = React.useState(null);
  const iframeRef = React.useRef(null);
  React.useEffect(() => {
    const checkTheme = () => {
      const isDark = document.documentElement.classList.contains('dark');
      setTheme(isDark ? 'dark' : 'light');
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  React.useEffect(() => {
    const handleFullscreenChange = () => {
      setIsFullscreen(!!document.fullscreenElement);
    };
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    return () => document.removeEventListener('fullscreenchange', handleFullscreenChange);
  }, []);
  React.useEffect(() => {
    const handleMessage = event => {
      if (!event.origin.includes('chift-coverage-matrix.s3.eu-west-3.amazonaws.com')) return;
      if (event.data?.type === 'urlChange' && event.data?.url) {
        setCurrentIframeUrl(event.data.url);
      }
    };
    window.addEventListener('message', handleMessage);
    return () => window.removeEventListener('message', handleMessage);
  }, []);
  const queryParams = new URLSearchParams({
    api,
    theme,
    ...connectors ? {
      connectors
    } : {}
  });
  const iframeUrl = `https://chift-coverage-matrix.s3.eu-west-3.amazonaws.com/coverage.html?${queryParams.toString()}`;
  const openUrl = currentIframeUrl || iframeUrl;
  const toggleFullscreen = () => {
    if (!document.fullscreenElement) {
      iframeRef.current?.requestFullscreen();
    } else {
      document.exitFullscreen();
    }
  };
  const isDark = theme === 'dark';
  const buttonStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    gap: '8px',
    padding: '4px 12px',
    fontSize: '14px',
    fontWeight: '500',
    color: isDark ? '#d4d4d4' : '#374151',
    backgroundColor: 'transparent',
    border: `1px solid ${isDark ? '#404040' : '#e5e7eb'}`,
    borderRadius: '12px',
    cursor: 'pointer',
    textDecoration: 'none',
    transition: 'all 0.15s ease'
  };
  const hoverBg = isDark ? 'rgba(255,255,255,0.05)' : 'rgba(0,0,0,0.03)';
  const hoverBorder = isDark ? '#525252' : '#d1d5db';
  const defaultBg = 'transparent';
  const defaultBorder = isDark ? '#404040' : '#e5e7eb';
  return <>
  <div style={{
    display: 'flex',
    justifyContent: 'flex-end',
    gap: '12px',
    marginBottom: '8px'
  }}>
    <button onClick={toggleFullscreen} style={buttonStyle} onMouseEnter={e => {
    e.target.style.backgroundColor = hoverBg;
    e.target.style.borderColor = hoverBorder;
  }} onMouseLeave={e => {
    e.target.style.backgroundColor = defaultBg;
    e.target.style.borderColor = defaultBorder;
  }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        {isFullscreen ? <>
            <polyline points="4 14 10 14 10 20"></polyline>
            <polyline points="20 10 14 10 14 4"></polyline>
            <line x1="14" y1="10" x2="21" y2="3"></line>
            <line x1="3" y1="21" x2="10" y2="14"></line>
          </> : <>
            <polyline points="15 3 21 3 21 9"></polyline>
            <polyline points="9 21 3 21 3 15"></polyline>
            <line x1="21" y1="3" x2="14" y2="10"></line>
            <line x1="3" y1="21" x2="10" y2="14"></line>
          </>}
      </svg>
      {isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'}
    </button>
    <a href={iframeUrl} target="_blank" rel="noopener noreferrer" style={buttonStyle} onMouseEnter={e => {
    e.target.style.backgroundColor = hoverBg;
    e.target.style.borderColor = hoverBorder;
  }} onMouseLeave={e => {
    e.target.style.backgroundColor = defaultBg;
    e.target.style.borderColor = defaultBorder;
  }}>
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
        <polyline points="15 3 21 3 21 9"></polyline>
        <line x1="10" y1="14" x2="21" y2="3"></line>
      </svg>
      Open in new tab
    </a>
  </div>
  <iframe ref={iframeRef} src={iframeUrl} title={`Chift Coverage Matrix - ${api}`} style={{
    height: 'max(500px, 80vh)'
  }} className="w-full" allowFullScreen />
  <blockquote>
    <p>
      <strong>Matrix Legend 🧭</strong>
    </p>
    <table>
      <thead>
        <tr>
          <th>Status</th>
          <th>Meaning</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>✅ Implemented</td>
          <td>Endpoint is implemented and available.</td>
        </tr>
        <tr>
          <td>❌ Not supported</td>
          <td>
            Endpoint is not supported by the target software (connector
            limitation). Cannot be implemented.
          </td>
        </tr>
        <tr>
          <td>💬 On request</td>
          <td>
            Endpoint is not implemented but feasibility is validated. Can be
            implemented on request — contact your Chift point of contact to
            discuss scope and timing.
          </td>
        </tr>
        <tr>
          <td>🔎 To be analyzed</td>
          <td>
            Endpoint is not implemented and feasibility has not yet been fully
            assessed. Analysis is pending.
          </td>
        </tr>
      </tbody>
    </table>
  </blockquote>
</>;
};

export const OverviewLegend = ({showTitle = true}) => <blockquote>
    {showTitle && <p>
        <strong>Overview legend 🧭</strong>
      </p>}
    <table>
      <thead>
        <tr>
          <th>Column</th>
          <th>Value</th>
          <th>Meaning</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Geography</td>
          <td>🇫🇷 FR · 🇧🇪 BE · …</td>
          <td>Countries where the connector is officially supported.</td>
        </tr>
        <tr>
          <td rowSpan={3}>Software type</td>
          <td>SaaS</td>
          <td>Through API.</td>
        </tr>
        <tr>
          <td>On-premise (local agent)</td>
          <td>
            Software running locally — installation of a local agent is
            required.
          </td>
        </tr>
        <tr>
          <td>On-premise (API)</td>
          <td>Software running locally — API available.</td>
        </tr>
        <tr>
          <td rowSpan={2}>Status</td>
          <td>🔵 Live</td>
          <td>Connector is generally available and production-ready.</td>
        </tr>
        <tr>
          <td>🟣 Beta</td>
          <td>
            Connector is in beta — usable in production but may still evolve.
          </td>
        </tr>
        <tr>
          <td>Multi folder</td>
          <td>✅ Yes / ❌ No</td>
          <td>
            Connection to multiple accounting folders at the same time (see{' '}
            <a href="/unified-apis/accounting/concepts/folder">
              accounting folders guide
            </a>
            ).
          </td>
        </tr>
        <tr>
          <td>Rate limits</td>
          <td>✅ No / ❌ Yes</td>
          <td>Whether the target software sets rate limits on API calls.</td>
        </tr>
        <tr>
          <td rowSpan={3}>API keys</td>
          <td>❎ No</td>
          <td>
            No API keys required (OAuth2 client secret and client ID). No
            requirements to activate the connector — you can create a
            connection.
          </td>
        </tr>
        <tr>
          <td>🔑</td>
          <td>
            Keys are required to activate the connector. Chift cannot act as
            intermediary to obtain them; we can still assist with steps to get
            keys directly from the software provider.
          </td>
        </tr>
        <tr>
          <td>🔑 ☑️ via Chift</td>
          <td>
            Keys are required to activate the connector. You can go through
            Chift to get the keys (intermediary or partnership keys). An
            approval process may still apply, but you do not need to request
            keys from the vendor on your own.
          </td>
        </tr>
        <tr>
          <td rowSpan={3}>Approval / certification process</td>
          <td>⚡ Instant</td>
          <td>
            No keys required, or Chift can encode their keys for you when
            requested. Activation is instantaneous.
          </td>
        </tr>
        <tr>
          <td>🟢 Approval</td>
          <td>
            Approval will be granted. The vendor may require information or app
            configuration in a developer portal before issuing keys.
          </td>
        </tr>
        <tr>
          <td>🟠 Approval</td>
          <td>
            Approval is not guaranteed — often due to integration strategy; the
            vendor may do a deeper assessment (competitors, partnership
            requirements, and similar).
          </td>
        </tr>
        <tr>
          <td rowSpan={2}>Activation lead time</td>
          <td>⚡ Instant</td>
          <td>
            If no keys are required, or Chift has keys ready to share with you.
          </td>
        </tr>
        <tr>
          <td>Time</td>
          <td>
            Estimated time to get the connector activated in production as a
            result of the approval or certification process (e.g. ⏱️ 2 days, 1
            week).
          </td>
        </tr>
        <tr>
          <td rowSpan={3}>Extra fees — software editor</td>
          <td>❎ No</td>
          <td>No fees charged by the software editor.</td>
        </tr>
        <tr>
          <td>💰 🕹️</td>
          <td>Fees associated with obtaining a testing account.</td>
        </tr>
        <tr>
          <td>💰 🔑</td>
          <td>Fees charged to get API keys.</td>
        </tr>
        <tr>
          <td rowSpan={2}>Extra fees — end-user</td>
          <td>❎ No</td>
          <td>The end-user does not pay extra to get integrated.</td>
        </tr>
        <tr>
          <td>💰 Yes</td>
          <td>The end-user must pay extra to get integrated.</td>
        </tr>
        <tr>
          <td>Comments on costs</td>
          <td>—</td>
          <td>Additional notes on fees or pricing when relevant.</td>
        </tr>
        <tr>
          <td rowSpan={4}>Sandbox account</td>
          <td>✅ via Chift</td>
          <td>Chift can provide you with a sandbox.</td>
        </tr>
        <tr>
          <td>🟠 Only through integrator</td>
          <td>Only the software's integrator can provide a sandbox.</td>
        </tr>
        <tr>
          <td>✅ Self-service</td>
          <td>You can create your own sandbox.</td>
        </tr>
        <tr>
          <td>✅ Trial account</td>
          <td>It is possible to create a trial account.</td>
        </tr>
      </tbody>
    </table>
  </blockquote>;

export const ConnectorCardIframe = ({api = 'accounting', connectors}) => {
  const [theme, setTheme] = React.useState('light');
  React.useEffect(() => {
    const checkTheme = () => {
      const isDark = document.documentElement.classList.contains('dark');
      setTheme(isDark ? 'dark' : 'light');
    };
    checkTheme();
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  const queryParams = new URLSearchParams({
    api,
    theme,
    ...connectors ? {
      connectors
    } : {}
  });
  const iframeUrl = `https://chift-coverage-matrix.s3.eu-west-3.amazonaws.com/connector-card.html?${queryParams.toString()}`;
  return <iframe src={iframeUrl} title={`Chift connector information - ${api}`} style={{
    display: 'block',
    width: '100%',
    height: '480px',
    margin: 0,
    padding: 0,
    border: 'none'
  }} />;
};

<ConnectorCardIframe api="payment" connectors="eBay" />

<Accordion title="Overview Legend 🧭">
  <OverviewLegend showTitle={false} />
</Accordion>

[📊 See what this connector supports ↓](#coverage)

## Introduction

eBay is a global online marketplace where sellers are paid through eBay's managed payments. The connector reads the seller's financial data from eBay's Sell Finances API.

## Activate eBay

### Partner keys

You'll need your own OAuth2 app, registered with eBay.

No approval is needed: an eBay developer account and an application are enough. Sandbox and Production each have their own keys, RuName and signing key, so repeat the steps for each environment you use.

<Steps>
  <Step title="Create an eBay developer account">
    Sign up on the [eBay Developers Program](https://developer.ebay.com/), then create an application under **Application Keys**. eBay gives it a Sandbox and a Production keyset.
  </Step>

  <Step title="Enable the Production keyset">
    eBay keeps the Production keyset disabled until you comply with its [Marketplace Account Deletion](https://developer.ebay.com/marketplace-account-deletion) notifications: subscribe an endpoint, or apply for the exemption.
  </Step>

  <Step title="Copy the App ID and Cert ID">
    On **Application Keys**, copy the keyset's **App ID (Client ID)** and **Cert ID (Client Secret)**.
  </Step>

  <Step title="Create a RuName">
    Next to the App ID, open **User Tokens**, then **Get a Token from eBay via Your Application**, and add a redirect URL. Set its **Auth Accepted URL** to the URL below. eBay generates a RuName, a name such as `Your_Company-YourApp-PRD-…`: copy it.

    ```text theme={null}
    https://chift.app/oauth2/redirect
    ```
  </Step>

  <Step title="Create a signing key">
    eBay requires a digital signature on every Finances API call made for a seller domiciled in the EU or the UK. Chift signs every call, so the key is needed whatever your sellers' country. Create the key with eBay's [Key Management API](https://developer.ebay.com/api-docs/developer/key-management/resources/signing_key/methods/createSigningKey), cipher `ED25519`, using an application token of the same keyset.

    The response holds a `privateKey` and a `jwe`. eBay does not store the private key and returns it once: copy both values before closing the response. If it is lost, create a new signing key.

    A signing key expires 3 years after its creation. Before then, create a new one and replace both values in the connector settings.

    See eBay's [digital signatures guide](https://developer.ebay.com/develop/guides/digital-signatures-for-apis).
  </Step>
</Steps>

<Card title="Activate eBay in your Chift account" icon="bolt" href="https://chift.app/connectors?search=eBay" horizontal>
  In **Connectors**, set **Environment**, then enter the matching **App ID (Client ID)**, **Cert ID (Client Secret)**, **RuName**, **Digital signature private key** and **Digital signature key (JWE)**.
</Card>

### Connector settings

<Frame>
  <img src="https://mintcdn.com/chift/prd2VjLiEmzcRl8v/images/connectors/ebay/ebay-1.jpeg?fit=max&auto=format&n=prd2VjLiEmzcRl8v&q=85&s=f7ed887228b744e44c802b624af24e4c" alt="The Environment setting in the Chift eBay connector settings, with its options Production and Sandbox" width="1103" height="203" data-path="images/connectors/ebay/ebay-1.jpeg" />
</Frame>

**Environment** selects which eBay environment the connections of this connector talk to.

* **Production** (default): the seller's live eBay account.
* **Sandbox**: eBay's test environment.

Use **Sandbox** while you test the integration, then switch back to **Production** before your end users connect. The keys, RuName and signing key belong to one environment: enter the ones of the keyset that matches.

## Test eBay

| | |
| - | - |
| **Environment** | Sandbox |
| **How to get it** | In the [eBay Developers Program](https://developer.ebay.com/), use your application's Sandbox keyset, and create a Sandbox test user to connect with. Set the connector's **Environment** to **Sandbox**. |

## Vendor fees

<Check>No vendor fees, for you or your end users.</Check>

## Connect eBay

<Card title="eBay setup guide for end users" icon="book-open" href="/help/connectors/7113" horizontal>
  The full step-by-step, with screenshots.
</Card>

**Before they start, your end users need:**

* an eBay seller account that receives payouts through eBay's managed payments
* to sign in with the eBay account that receives the payouts: eBay does not give team members access to financial data

**To connect, they:**

* select the **eBay marketplace** they sell on
* sign in to eBay and agree to share their financial data

## Rate limits

eBay applies a daily call limit per application: 15,000 calls per day for the Finances API, shared by all the connections of your app. eBay can raise it after an Application Growth Check.

When the limit is exceeded, eBay returns HTTP `429 Too Many Requests`. Chift automatically manages these limits to optimize performance and prevent interruptions. However, once the API rate limit is reached, Chift cannot bypass these limitations.

eBay returns up to 1,000 transactions or 200 payouts per call, and Chift reads every page of a list. A large date range on a busy seller costs several calls.

See eBay's [API call limits](https://developer.ebay.com/develop/get-started/api-call-limits).

## Limitations & specificities

<AccordionGroup>
  <Accordion title="Dates">
    * Without dates, eBay returns the last 5 years.
    * eBay keeps 5 years of history: an older start date is moved to 5 years ago.
    * A date range wider than 36 months is refused. Split it into smaller ranges.
  </Accordion>

  <Accordion title="Transactions">
    * eBay reports a sale net of its fees. Chift adds the fees back, so the amount minus the fee is what the seller receives.
    * Fees eBay reports in another currency are converted with the transaction's exchange rate.
    * Transactions that moved no money (failed at eBay) are not returned.
    * Every payout is also returned as a transaction with the `payout` accounting category. A payout eBay finally gives up on is returned a second time, with the `payout_cancel` category, on the date of its last attempt.
    * eBay's withdrawal transactions are not returned: the payout transactions already cover them.
    * The `starting_from` filter is not supported and is refused.
    * The `invoice` accounting category has no equivalent at eBay and returns an empty list.
  </Accordion>

  <Accordion title="Payments & refunds">
    * A payment is an eBay order: the order's sales are grouped into one payment, identified by the order number.
    * A payment is pending until eBay pays it out, then completed. It is partially completed when only part of the order is paid out.
    * Each refund is one eBay refund transaction, linked to its order.
  </Accordion>

  <Accordion title="Payouts">
    * Status: in transit while eBay sends or retries it, paid once it succeeds, failed once eBay gives up.
    * The fee is eBay's express payout fee, when there is one.
  </Accordion>

  <Accordion title="Balances & locations">
    * One balance, in the seller's payout currency: the funds available for payout.

    - Locations do not exist at eBay: the `location_id` filter is refused on every endpoint.
  </Accordion>
</AccordionGroup>

## Coverage

<CoverageIframe api="payment" connectors="eBay" />


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.