# 

## What you will build

A four-step automated onboarding flow that takes a merchant from signup to payment-ready.

![image](https://files.modern-mermaid.live/images/1776277501753-mermaid-diagram-1776277501772.png)

## Prerequisites

* A valid API key for your parent (reseller) account — see [Obtain API credentials](/docs/how-tos/setup/obtain-credentials)
* The `parent_id` of your reseller account


## Step 1: Create the client

Create a new merchant account under your reseller.

curl
```shell
curl -X POST \
  https://api.dev.paradisegateway.net/v1/clients \
  -H "Content-Type: application/json" \
  -H "APIKEY: YOUR-RESELLER-API-KEY" \
  -d '{
    "dba": "Acme Jewelry",
    "parent_id": "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
    "type": "merchant",
    "admin_contact_details": {
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane.smith@example.com",
      "phone": "+15551234567",
      "time_zone": "America/New_York"
    }
  }'
```

Python
```python
import os, requests

API_KEY = os.environ["PARADISE_API_KEY"]
BASE = os.environ.get("PARADISE_BASE_URL", "https://api.dev.paradisegateway.net")
HEADERS = {"Content-Type": "application/json", "APIKEY": API_KEY}

client_resp = requests.post(f"{BASE}/v1/clients", headers=HEADERS, json={
    "dba": "Acme Jewelry",
    "parent_id": "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
    "type": "merchant",
    "admin_contact_details": {
        "first_name": "Jane",
        "last_name": "Smith",
        "email": "jane.smith@example.com",
        "phone": "+15551234567",
        "time_zone": "America/New_York",
    },
})
client = client_resp.json()
client_id = client["id"]
print(f"Client created: {client_id}")
```

JavaScript
```javascript
const API_KEY = process.env.PARADISE_API_KEY;
const BASE = process.env.PARADISE_BASE_URL || "https://api.dev.paradisegateway.net";
const headers = { "Content-Type": "application/json", "APIKEY": API_KEY };

const clientResp = await fetch(`${BASE}/v1/clients`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    dba: "Acme Jewelry",
    parent_id: "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
    type: "merchant",
    admin_contact_details: {
      first_name: "Jane",
      last_name: "Smith",
      email: "jane.smith@example.com",
      phone: "+15551234567",
      time_zone: "America/New_York",
    },
  }),
});
const client = await clientResp.json();
console.log(`Client created: ${client.id}`);
```

C#
```csharp
using var httpClient = new HttpClient();
var baseUrl = Environment.GetEnvironmentVariable("PARADISE_BASE_URL") ?? "https://api.dev.paradisegateway.net";
httpClient.DefaultRequestHeaders.Add("APIKEY", Environment.GetEnvironmentVariable("PARADISE_API_KEY"));

var clientResp = await httpClient.PostAsJsonAsync($"{baseUrl}/v1/clients", new {
    dba = "Acme Jewelry",
    parent_id = "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
    type = "merchant",
    admin_contact_details = new {
        first_name = "Jane", last_name = "Smith",
        email = "jane.smith@example.com",
        phone = "+15551234567", time_zone = "America/New_York",
    },
});
var clientJson = await clientResp.Content.ReadAsStringAsync();
Console.WriteLine(clientJson);
```

Java
```java
HttpClient client = HttpClient.newHttpClient();
String baseUrl = System.getenv().getOrDefault("PARADISE_BASE_URL", "https://api.dev.paradisegateway.net");

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(baseUrl + "/v1/clients"))
    .header("Content-Type", "application/json")
    .header("APIKEY", System.getenv("PARADISE_API_KEY"))
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "dba": "Acme Jewelry",
          "parent_id": "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
          "type": "merchant",
          "admin_contact_details": {
            "first_name": "Jane",
            "last_name": "Smith",
            "email": "jane.smith@example.com",
            "phone": "+15551234567",
            "time_zone": "America/New_York"
          }
        }"""))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```

Go
```go
payload := `{
  "dba": "Acme Jewelry",
  "parent_id": "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
  "type": "merchant",
  "admin_contact_details": {
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane.smith@example.com",
    "phone": "+15551234567",
    "time_zone": "America/New_York"
  }
}`
req, _ := http.NewRequest("POST", base+"/v1/clients", strings.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("APIKEY", apiKey)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
```

PHP
```php
$payload = json_encode([
    "dba" => "Acme Jewelry",
    "parent_id" => "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y",
    "type" => "merchant",
    "admin_contact_details" => [
        "first_name" => "Jane", "last_name" => "Smith",
        "email" => "jane.smith@example.com",
        "phone" => "+15551234567", "time_zone" => "America/New_York",
    ],
]);
$ch = curl_init("{$base}/v1/clients");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ["Content-Type: application/json", "APIKEY: {$apiKey}"],
    CURLOPT_POSTFIELDS => $payload,
]);
echo curl_exec($ch);
```

Ruby
```ruby
uri = URI("#{base}/v1/clients")
req = Net::HTTP::Post.new(uri)
req["Content-Type"] = "application/json"
req["APIKEY"] = api_key
req.body = { dba: "Acme Jewelry",
  parent_id: "CLIENT-01JMRSPCK7XVNP3KS8F2W4T6Y", type: "merchant",
  admin_contact_details: {
    first_name: "Jane", last_name: "Smith",
    email: "jane.smith@example.com",
    phone: "+15551234567", time_zone: "America/New_York"
  } }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.body
```

Client types
Set `type` to `merchant` for businesses that process payments, or `reseller` for ISOs and agents that manage merchants. See [Clients and resellers](/docs/concepts/account-hierarchy/clients-and-resellers).

Save the `id` from the response — you need it for all subsequent steps.

## Step 2: Create the first user

Add an admin user to the new client account.

curl
```shell
curl -X POST \
  https://api.dev.paradisegateway.net/v1/users \
  -H "Content-Type: application/json" \
  -H "APIKEY: YOUR-RESELLER-API-KEY" \
  -d '{
    "client_id": "CLIENT-01KEWXXXXXXXXXXXXXXXXXXXXXXX",
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane.smith@example.com",
    "password": "SecureP@ssw0rd!2026",
    "time_zone": "America/New_York"
  }'
```

Python
```python
user_resp = requests.post(f"{BASE}/v1/users", headers=HEADERS, json={
    "client_id": client_id,
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane.smith@example.com",
    "password": "SecureP@ssw0rd!2026",
    "time_zone": "America/New_York",
})
user = user_resp.json()
print(f"User created: {user['id']}")
```

JavaScript
```javascript
const userResp = await fetch(`${BASE}/v1/users`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    client_id: client.id,
    first_name: "Jane",
    last_name: "Smith",
    email: "jane.smith@example.com",
    password: "SecureP@ssw0rd!2026",
    time_zone: "America/New_York",
  }),
});
const user = await userResp.json();
console.log(`User created: ${user.id}`);
```

Secure the password
Transmit the initial password to the client through a secure channel (encrypted email, secure portal). Instruct them to change it on first login.

## Step 3: Configure a processor integration

Add a TSYS integration so the client can process card transactions. Use the **client's** API key for this call.

curl
```shell
curl -X POST \
  https://api.dev.paradisegateway.net/v1/integrations \
  -H "Content-Type: application/json" \
  -H "APIKEY: CLIENT-API-KEY" \
  -d '{
    "name": "tsys",
    "is_active": true,
    "configuration": {
      "mid": "999000000011",
      "tid": "00000001",
      "industry_type": "e_commerce",
      "settlement_time": "23:59:00"
    }
  }'
```

Python
```python
merchant_headers = {"Content-Type": "application/json", "APIKEY": api_key}
int_resp = requests.post(f"{BASE}/v1/integrations", headers=merchant_headers, json={
    "name": "tsys",
    "is_active": True,
    "configuration": {
        "mid": "999000000011",
        "tid": "00000001",
        "industry_type": "e_commerce",
        "settlement_time": "23:59:00",
    },
})
integration = int_resp.json()
print(f"Integration: {integration['id']} — active: {integration['is_active']}")
```

JavaScript
```javascript
const merchantHeaders = { "Content-Type": "application/json", "APIKEY": apiKey };
const intResp = await fetch(`${BASE}/v1/integrations`, {
  method: "POST",
  headers: merchantHeaders,
  body: JSON.stringify({
    name: "tsys",
    is_active: true,
    configuration: {
      mid: "999000000011",
      tid: "00000001",
      industry_type: "e_commerce",
      settlement_time: "23:59:00",
    },
  }),
});
const integration = await intResp.json();
console.log(`Integration: ${integration.id} — active: ${integration.is_active}`);
```

## Verification checklist

After completing all four steps, verify the onboarding succeeded:

| Check | How |
|  --- | --- |
| Client exists | `GET /v1/clients/{client_id}` returns `200` |
| User can authenticate | `POST /v1/auth/keys` with Basic Auth succeeds |
| API key works | Any authenticated request returns `200` |
| Integration is active | `GET /v1/integrations` shows the integration with `is_active: true` |
| Test payment works | `POST /v1/transactions` with a test card returns `approved` |


## Complete automation example

```python
def onboard_merchant(dba: str, parent_id: str, contact: dict, tsys_config: dict) -> dict:
    client = requests.post(f"{BASE}/v1/clients", headers=HEADERS, json={
        "dba": dba, "parent_id": parent_id, "type": "merchant",
        "admin_contact_details": contact,
    }).json()

    user = requests.post(f"{BASE}/v1/users", headers=HEADERS, json={
        "client_id": client["id"],
        "first_name": contact["first_name"],
        "last_name": contact["last_name"],
        "email": contact["email"],
        "password": contact["initial_password"],
        "time_zone": contact.get("time_zone", "America/New_York"),
    }).json()

    creds = base64.b64encode(
        f"{contact['email']}:{contact['initial_password']}".encode()
    ).decode()
    api_key = requests.post(f"{BASE}/v1/auth/keys", headers={
        "Content-Type": "application/json",
        "Authorization": f"Basic {creds}",
    }).json()["key"]

    merchant_headers = {"Content-Type": "application/json", "APIKEY": api_key}
    integration = requests.post(
        f"{BASE}/v1/integrations", headers=merchant_headers, json={
            "name": "tsys", "is_active": True, "configuration": tsys_config,
        }
    ).json()

    return {
        "client_id": client["id"],
        "user_id": user["id"],
        "integration_id": integration["id"],
    }
```

## Further reading

* [Onboard a new client (how-to)](/docs/how-tos/clients-users/onboard-client)
* [Add an integration](/docs/how-tos/integrations/add-integration)
* [Clients and resellers](/docs/concepts/account-hierarchy/clients-and-resellers)
* [Users and roles](/docs/concepts/account-hierarchy/users-and-roles)