# Centralized (Self-Managed Billing) Implementation Guide

## Overview

The **Centralized (Self-Managed Billing)** white-label option in Forge is designed for platforms and marketplaces that want to maintain complete payment and pricing control.

Under this option:

- The platform controls carrier configurations.
- All billing flows through the platform.
- Pricing strategy remains centralized.
- Sub-accounts transact under the platform’s carrier accounts.

For this option, the sub-account object type is the Child User.

  **IMPORTANT:** Before starting, review the prerequisites section of the
  Get Started with Forge guide to understand white-label
  implementations with EasyPost.

---

## Child User Setup and Management

This section outlines how Child Users are created, managed, and used for shipping operations.

### Create a Child User

**Production Only**

Child Users are created using the Users API or through the Forge Dashboard.

A Child User is a dependent account linked to a Parent User. The Child User inherits carrier configuration and billing structure while remaining under the platform’s control.

All billing, carrier configuration, and rate adjustments remain managed by the Parent User.

Child Users can only be created in **Production** mode using the platform’s API Key and the `POST /users` endpoint, or through the Forge Dashboard Sub Accounts page.

Once a Child User is created, **securely store the API keys for future use.** If API keys are lost, they can be retrieved from the Sub Account Details page.

### Example: POST /users

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/users \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "user": {
      "name": "Child Account Name"
    }
  }'
```

#### Go

```go
package example

import (
	"fmt"

	"github.com/EasyPost/easypost-go/v5"
)

func create() {
	client := easypost.New("EASYPOST_API_KEY")

	userName := "Child Account Name"
	user, _ := client.CreateUser(
		&easypost.UserOptions{
			Name: &userName,
		},
	)

	fmt.Println(user)
}
```

#### Java

```java
package users;

import com.easypost.exception.EasyPostException;
import com.easypost.model.User;
import com.easypost.service.EasyPostClient;

import java.util.HashMap;

public class Create {
    public static void main(String[] args) throws EasyPostException {
        EasyPostClient client = new EasyPostClient("EASYPOST_API_KEY");

        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("name", "Child Account Name");

        User user = client.user.create(params);

        System.out.println(user);
    }
}
```

#### C#

```csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyPost;
using Newtonsoft.Json;

namespace EasyPostExamples
{
    public class Examples
    {
        public static async Task Main()
        {
            var client = new EasyPost.Client(new EasyPost.ClientConfiguration("EASYPOST_API_KEY"));

            EasyPost.Parameters.User.CreateChild parameters = new()
            {
                Name = "Child Account Name",
            };

            EasyPost.Models.API.User user = await client.User.Create(parameters);

            Console.WriteLine(JsonConvert.SerializeObject(user, Formatting.Indented));
        }
    }
}
```

#### Node.js

```javascript
const EasyPostClient = require('@easypost/api');

const client = new EasyPostClient('EASYPOST_API_KEY');

(async () => {
  const user = await client.User.create({
    name: 'Child Account Name',
  });

  console.log(user);
})();
```

#### PHP

```php
<?php

$client = new \EasyPost\EasyPostClient('EASYPOST_API_KEY');

$child = $client->user->create([
    'name' => 'Child Account Name'
]);

echo $child;
```

#### Python

```python
import easypost

client = easypost.EasyPostClient("EASYPOST_API_KEY")

user = client.user.create(name="Child Account Name")

print(user)
```

#### Ruby

```ruby
require 'easypost'

client = EasyPost::Client.new(api_key: 'EASYPOST_API_KEY')

user = client.user.create(
  name: 'Child Account Name',
)

puts user
```

Related:

- [Child User Object](https://docs.easypost.com/docs/users/child-users)

---

## Child User Customer Portals

Customer Portals provide EasyPost-hosted, platform-branded experiences that allow Child Users to self-manage account settings.

Portal access is created using the `POST /customer_portal/account_link` endpoint.

### Onboarding Portal

A co-branded, conversion-optimized flow used to collect contact information and address details for each Child User.

### Account Management Portal

A customizable portal for managing carrier accounts and other account settings.

### Example: POST /customer_portal/account_link

#### cURL

```shell
curl -X POST https://api.easypost.com/v2/customer_portal/account_link \
  -u "EASYPOST_API_KEY": \
  -H 'Content-Type: application/json' \
  -d '{
    "session_type": "account_management",
    "user_id": "user_...",
    "refresh_url": "https://example.com/refresh",
    "return_url": "https://example.com/return",
    "metadata": {"target": "wallet"}
  }'
```

---

## Child User Carrier Account Management

Upon creation, a Child User automatically inherits:

- The Parent User’s USPS account
- Select Wallet Carrier Accounts

These accounts are billed through the platform’s wallet.

> Note: Child Users do not maintain independent carrier billing relationships in the Centralized option. Carrier
  charges flow through the Parent User’s Wallet and billing methods.

Additional carriers may be added by:

- Using the Carrier Account API with the Child User's Production API key.
- Add carriers manually through the Forge Dashboard.
- Enabling carrier account management through the Customer Portal using the `POST /customer_portal/account_link` endpoint.

For more information, visit **Carrier Management** within the Forge section of the Help Center.

Related:

- [Forge Carrier Management](https://support.easypost.com/hc/en-us/sections/34550349817869-Carrier-Management)

---

## Child User Shipment Creation

Shipment creation for Child Users follows the same process as shipment creaiton for Parent Users. **The Child User’s API Keys must be used**.

A shipment object consists of:

- A valid `to_address` and `from_address`
- A `parcel` with shipping details
- Any required `forms` for international deliveries

Once a `shipment` is created, a shipment object is used to retrieve shipping `rates` and purchase a label.

Related:

- [Shipments](https://docs.easypost.com/docs/shipments)

---

## Child User Billing Management

All postage, insurance fees, and carrier adjustment charges generated by Child Users are billed to the Parent User’s Wallet and billing methods.

This structure enables:

- Centralized pricing strategy
- Controlled margin management
- Simplified reconciliation

All activity is tracked to each individual Child User, simplifying financial reporting and reconciliation for the marketplace or platform.

Billing settings can be managed through the Forge Billing Page or via API.

Related:

- [Forge Billing](https://app.easypost.com/forge/billing)
- [Billing](https://docs.easypost.com/docs/users/billing)

---

## FlexRate (Rate Adjustments)

Forge FlexRate allows platform administrators to apply percentage-based or fixed-amount adjustments to carrier rates displayed to Child Users.
This feature supports transactional revenue generation and pricing flexibility without requiring custom code or manual rate manipulation.

When enabled, rate adjustments are returned in the `adjusted_rate` field in the API response. The underlying rate object remains unchanged
in the response. The `adjusted_rate` field is included in addition to the original carrier rate.

Adjustments can be configured:

- Globally (Standard FlexRate)
- By carrier and service level
- By shipment attributes such as weight, zone, and surcharge type

Supported evaluation models include:

- Standard (single-rule)
- Hierarchical (precedence-based)
- Cumulative (additive).

Sub Account Groups can be used in combination with FlexRate to segment pricing strategies across cohorts of Child Users.

For detailed configuration guidance, see the Forge FlexRate article in the Help Center.

Related:

- [Forge FlexRate](https://support.easypost.com/hc/en-us/articles/40687325316237-Forge-FlexRate-Rate-Adjustments)

---

## Advanced Shipping

Forge Advanced Shipping allows Child Users to access a white-labeled shipping interface for purchasing labels, viewing rates, and managing shipments.

When Advanced Shipping is used with the Centralized (Self-Managed Billing) option, displayed shipping rates reflect any pricing
adjustments configured through Forge FlexRate.

Advanced Shipping provides an EasyPost-hosted interface powered by ShipBlink while maintaining the platform’s self-managed
billing and carrier configuration.

For setup instructions and configuration details, see the Forge Advanced Shipping article in the Help Center.

Related:

- [Forge Advanced Shipping](https://support.easypost.com/hc/en-us/articles/44018208194829-Forge-Advanced-Shipping)

---

## Additional Resources

Please visit the Help Center for more information.