> For the complete documentation index, see [llms.txt](https://docs.alternativepayments.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.alternativepayments.io/getting-started/3rd-party-tools/chargebee-integration-guide.md).

# Chargebee Integration Guide

Alternative Payments can work alongside Chargebee without requiring an ERP or accounting platform in the middle. This guide explains how to wire the two systems together using the AP public API, which payment collection methods are available, how to keep payment status in sync via webhooks, and what the current limitations are.

***

## Overview

There is no turnkey Chargebee connector — the integration requires a small amount of custom code on your side. The pattern is straightforward:

1. **Chargebee invoice created** → your backend calls the AP API to create a matching customer and invoice.
2. **AP processes the payment** → AP fires an `invoice_paid` webhook to your endpoint.
3. **Your backend marks the invoice paid in Chargebee** → the two systems stay in sync.

All payments run on AP's rails (card or ACH into payouts). AP acts as the processor for every invoice run through it; payments from third-party processors cannot be recorded through the partner API.

***

## Authentication

The AP public API uses OAuth 2.0 `client_credentials`. Obtain a token before making any API calls:

```bash
curl -X POST https://public-api.demo.alternativepayments.io/oauth/token \
  -H "Authorization: Basic BASE64(client_id:client_secret)" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials"
```

The response includes an `access_token` valid for 3600 seconds. Pass it as a Bearer token on all subsequent requests:

```http
Authorization: Bearer <access_token>
```

Your `client_id` and `client_secret` are available in the Partner Dashboard under **API Keys**. The scopes required for a Chargebee integration are: `customers:write`, `customers:read`, `invoices:write`, `invoices:read`, `payments:write`, `payments:read`, and `webhooks:write`.

***

## Step 1 — Create Customers

Mirror each Chargebee customer into AP using `POST /customers`. Store the Chargebee customer ID in the `external_id` field so you can look up the AP customer record from a Chargebee event later.

**Required scope:** `customers:write`

```bash
curl -X POST https://public-api.demo.alternativepayments.io/customers \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Inc.",
    "email": "billing@acme.com",
    "external_id": "cb_cus_ABC123"
  }'
```

The response includes the AP-assigned `id` alongside the `external_id` you supplied:

```json
{
  "id": "170d05e3-b498-4547-af7c-985f1e85d9f7",
  "name": "Acme Inc.",
  "email": "billing@acme.com",
  "external_id": "cb_cus_ABC123"
}
```

Store the AP `id` — you will need it when creating invoices and payments.

***

## Step 2 — Create Invoices

When Chargebee generates an invoice, call `POST /invoices` to create a corresponding invoice in AP.

**Required scope:** `invoices:write`

```bash
curl -X POST https://public-api.demo.alternativepayments.io/invoices \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "170d05e3-b498-4547-af7c-985f1e85d9f7",
    "due_date": "2025-10-01",
    "line_items": [
      {
        "description": "Monthly subscription — October 2025",
        "amount": 299.00,
        "quantity": 1
      }
    ]
  }'
```

The `due_date` field accepts `YYYY-MM-DD` format and defaults to the creation date if omitted.

***

## Step 3 — Collect Payment

AP supports four payment collection methods. Choose the one that fits your workflow:

### Option A — Charge a saved card or bank account (server-side)

If the customer already has a saved payment method on file, charge it directly via `POST /payments`.

**Required scope:** `payments:write`

```bash
curl -X POST https://public-api.demo.alternativepayments.io/payments \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "170d05e3-b498-4547-af7c-985f1e85d9f7",
    "invoice_id": "5cbcf9c3-9378-4633-91f0-886fa172f360",
    "payment_method": "card",
    "payment_method_id": "pm_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "amount": "299.00"
  }'
```

The `payment_method` field accepts `card` or `standard_ach`.

### Option B — Per-invoice hosted payment link

Generate a one-click payment URL for a specific invoice and send it to the customer (for example, embed it in a Chargebee invoice email).

**Required scope:** `invoices:read`

```bash
curl -X GET https://public-api.demo.alternativepayments.io/invoices/{invoice_id}/payment-link \
  -H "Authorization: Bearer $TOKEN"
```

### Option C — Hosted payment page (checkout token)

Generate a short-lived JWT for AP's hosted checkout page. The customer lands on a fully hosted payment form without your backend handling card data.

**Required scope:** `checkout:write`

```bash
curl -X POST https://public-api.demo.alternativepayments.io/checkout-auth/init \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "170d05e3-b498-4547-af7c-985f1e85d9f7",
    "invoice_id": "5cbcf9c3-9378-4633-91f0-886fa172f360"
  }'
```

The token is valid for one hour. Redirect the customer to the AP checkout URL with the token.

### Option D — Embedded checkout

Use the `/checkout/v1` JWT-authenticated endpoints to embed the AP payment form directly inside your own UI. The checkout token from Option C is reused as the Bearer token for all `/checkout/v1` calls.

***

## Step 4 — Sync Payment Status Back to Chargebee via Webhooks

Subscribe to AP webhook topics to receive real-time payment status events. When AP fires `invoice_paid`, call the Chargebee API to mark the corresponding invoice paid.

**Required scope:** `webhooks:write`

```bash
curl -X POST https://public-api.demo.alternativepayments.io/webhooks \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint_url": "https://your-server.example.com/ap-webhooks",
    "secret_key": "your_secret_key",
    "topic": "invoice_paid"
  }'
```

Repeat for each topic you want to monitor. The topics most relevant to a Chargebee sync are:

| Topic                | When it fires                                                       |
| -------------------- | ------------------------------------------------------------------- |
| `invoice_paid`       | Invoice fully paid — use this to mark the invoice paid in Chargebee |
| `payment_succeeded`  | Individual payment captured successfully                            |
| `payment_failed`     | Payment attempt failed                                              |
| `payment_refunded`   | Refund issued                                                       |
| `payment_chargeback` | Dispute opened — may require intervention                           |
| `payout_paid`        | Funds settled to your bank account                                  |

All webhook payloads share the same envelope structure:

```json
{
  "entity_id": "5cbcf9c3-9378-4633-91f0-886fa172f360",
  "idempotency_key": "066a3fd0-b849-494f-87ba-d186a6e4b2cc",
  "timestamp": "2025-10-01T14:22:00Z",
  "topic": "invoice_paid",
  "data": {
    "customer_id": "170d05e3-b498-4547-af7c-985f1e85d9f7",
    "invoice_id": "5cbcf9c3-9378-4633-91f0-886fa172f360",
    "status": "paid"
  }
}
```

For `invoice_paid`, `entity_id` is the AP invoice ID. Use `data.customer_id` to look up the corresponding Chargebee customer via the `external_id` you stored in Step 1.

{% hint style="info" %}
Always check the `idempotency_key` before processing a webhook event. AP may retry delivery on transient failures, so storing processed keys prevents double-processing.
{% endhint %}

***

## Integration Flow Summary

```
Chargebee invoice created
        │
        ▼
POST /customers  (if customer not yet in AP)
POST /invoices
        │
        ▼
Collect payment via one of:
  • POST /payments              (saved card / ACH)
  • GET  /invoices/{id}/payment-link
  • POST /checkout-auth/init    (hosted page)
  • /checkout/v1/*              (embedded)
        │
        ▼
AP fires invoice_paid webhook
        │
        ▼
Your backend marks invoice paid in Chargebee
```

***

## Caveats

### No turnkey Chargebee connector

AP does not provide a pre-built Chargebee integration. You write the glue code: listen for Chargebee invoice events, call the AP API, and handle AP webhooks to write status back to Chargebee. The integration is lightweight — typically two webhook handlers and a few API calls — but it is custom code.

### AP must be the processor

AP processes every payment that flows through it on its own rails (card and ACH into payouts). Recording payments that were originally processed by a third-party processor — for example, keeping an existing processor for some invoices and only logging those transactions in AP — is not supported through the partner API. If you are migrating from another processor, AP replaces it entirely for the invoices you run through AP.

***

For questions about scopes, webhook delivery, and retry behavior, see the [FAQ](/getting-started/faq.md) and [Webhooks](/getting-started/webhooks.md) reference pages.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.alternativepayments.io/getting-started/3rd-party-tools/chargebee-integration-guide.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
