Metadata-Version: 2.5
Name: hatang
Version: 0.1.0
Summary: Official Python SDK for Ha Tang (hatang.dev): support CRM, plans and purchases, AI knowledge, email, payments, webhooks.
Project-URL: Homepage, https://hatang.dev
Project-URL: Documentation, https://hatang.dev/docs/guides/sdks/python
Project-URL: Source, https://github.com/sota-labs/hatang/tree/main/sdks/python
Project-URL: Changelog, https://github.com/sota-labs/hatang/blob/main/sdks/python/CHANGELOG.md
Author-email: Sota Labs <hello@hatang.dev>
License-Expression: MIT
License-File: LICENSE
Keywords: chat,crm,email,hatang,in-app purchases,support,vietqr,webhooks
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.25
Description-Content-Type: text/markdown

# hatang

The official Python SDK for [Ha Tang](https://hatang.dev): support CRM, plans and purchases on the customer's profile,
the AI assistant's knowledge, email, VietQR payments and webhooks.

```bash
pip install hatang
```

Python 3.9+. Sync (`Hatang`) and asyncio (`AsyncHatang`) clients, typed request bodies.

## Quick start

```python
from hatang import Hatang

hatang = Hatang()  # reads HATANG_API_KEY; or Hatang("ht_…")

# What a customer pays for, from your backend (web sales included).
hatang.chat.subscriptions.upsert("web", "sub_123", {
    "status": "active",
    "sku": "PRO-1M",                    # finds the product in your catalog
    "external_user_id": "user-42",      # the id you pass to identify() in the chat
    "current_period_end": "2026-12-01T00:00:00Z",
    "amount": 99000, "currency": "VND",
})
hatang.chat.purchases.upsert("web", "order_981", {
    "store_product_id": "credits.300", "sku": "XU-300", "kind": "consumable",
    "external_user_id": "user-42", "amount": 29000, "currency": "VND",
})
```

asyncio (FastAPI, aiohttp…):

```python
from hatang import AsyncHatang

async with AsyncHatang() as hatang:
    hits = await hatang.knowledge.search("hoàn tiền", limit=3)
```

Every method returns the API's JSON as a `dict`. A call that does not succeed raises `HatangError` with `status_code`
(0 when Ha Tang was not reached), `name` (`validation_error`, `not_found`…), `message`, and `retryable` (unreachable,
429 or 5xx).

## What is in it

| Namespace | Methods |
|---|---|
| `chat.subscriptions` | `upsert`, `list`, `for_customer`, `purchase_token` |
| `chat.purchases` | `upsert`, `list`, `for_customer` |
| `chat.customers` | `list`, `get`, `update`, `conversations`, `export_csv` |
| `chat.conversations` | `list`, `get`, `update`, `messages`, `send`, `send_products` |
| `chat.products` | `list`, `search`, `get`, `create`, `update`, `remove` |
| `chat.orders` | `list`, `get`, `create`, `update`, `payment_link` |
| `knowledge` | `upsert`, `batch`, `sync`, `get`, `list`, `remove`, `search` |
| `emails`, `batch` | `send`, `get`, `list`, `update`, `cancel`; `batch.send` |
| `payments` | `create`, `get`, `list`, `cancel` |
| `events` | `send` |

## Helpers

```python
from hatang import identity_hash, purchase_token, construct_webhook_event, construct_ipn_event

# Signed chat identity: send this as `hash` with userId to identify() in the widget or the app SDKs.
identity_hash("user-42", IDENTITY_SECRET)

# StoreKit appAccountToken / Google Play obfuscatedAccountId for one of your users.
purchase_token("site_…", "user-42")

# Webhooks (whsec_… secret) and payment IPN calls: pass the raw body, before JSON parsing.
event = construct_webhook_event(request.body, request.headers, WEBHOOK_SECRET)
ipn = construct_ipn_event(request.body, request.headers, SECRET_KEY)
```

Both raise `HatangSignatureError` when the signature does not match; `verify_webhook` / `verify_ipn` return a bool.

## Configuration

| Argument | Environment | Default |
|---|---|---|
| `api_key` | `HATANG_API_KEY` | required |
| `base_url` | `HATANG_BASE_URL` | `https://api.hatang.dev` |
| `environment` | `HATANG_ENVIRONMENT` | the key's own |
| `timeout` | | 30 s |
| `http_client` | | an `httpx.Client` / `httpx.AsyncClient` of your own (proxies, retries, tests) |

Docs: [hatang.dev/docs](https://hatang.dev/docs/guides/sdks/python) · License: MIT
