# Server integration examples

Use the public HTTPS origin and a private server key in environment variables. Never put keys in front-end JavaScript or public image URLs. These examples use the synthetic sandbox, not real wallet funds. Switch to real `/orders` only when you intend to spend real wallet funds.

The full Python adapter is [examples/reseller_client.py](reseller-client.py). It retries with the same body/key/reference and prints only safe order metadata. It never logs credentials. Your downstream bot should collect its own customer's payment, persist that customer's order ID, submit the API order once, poll the same ID, and send retrieved delivery only to that customer in a private channel. A downstream refund does not automatically refund the TrustedTools order.

## Python

```sh
export TRUSTEDTOOLS_API_KEY='your-private-server-key'
python examples/reseller_client.py --origin https://trustedtools.hassan-tariq771.workers.dev --reference your-persisted-demo-order-001
```

Default product ID 1, quantity 1 and total 100 are synthetic. `--live` is explicit and can spend actual funds; provide the approved product ID and maximum total when using it.

## Node.js (server only)

```js
import {createHash} from 'node:crypto';
const origin = process.env.TRUSTEDTOOLS_ORIGIN;
const key = process.env.TRUSTEDTOOLS_API_KEY;
const reference = process.env.CUSTOMER_ORDER_ID; // saved in your database before sending
if (!origin?.startsWith('https://') || !key || !reference) throw Error('Missing HTTPS origin/key/persistent order reference');
const identity = 'node-order-' + createHash('sha256').update(reference).digest('hex');
const body = JSON.stringify({product_id:1,quantity:1,client_order_id:reference,max_total_minor:100});
const response = await fetch(origin + '/reseller/v1/sandbox/orders', {
  method:'POST',
  headers:{Authorization:'Bearer '+key,'Content-Type':'application/json','Idempotency-Key':identity},
  body,
  signal:AbortSignal.timeout(20000)
});
if (!response.ok) throw Error('API HTTP '+response.status+'; request '+response.headers.get('X-Request-ID'));
const order = await response.json();
console.log({id:order.id,state:order.state});
// On timeout/429/503, retry exactly body + identity. Do not invent a new reference.
// Poll /sandbox/orders/ID; retrieve /sandbox/orders/ID/delivery privately.
```

## Go

```go
package main

import (
    "bytes"
    "crypto/sha256"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "strings"
    "time"
)

func main() {
    origin, key, reference := os.Getenv("TRUSTEDTOOLS_ORIGIN"), os.Getenv("TRUSTEDTOOLS_API_KEY"), os.Getenv("CUSTOMER_ORDER_ID")
    if !strings.HasPrefix(origin, "https://") || key == "" || reference == "" { panic("Missing origin/key/persistent reference") }
    payload, _ := json.Marshal(map[string]any{"product_id":1,"quantity":1,"client_order_id":reference,"max_total_minor":100})
    hash := sha256.Sum256([]byte(reference))
    identity := "go-order-" + hex.EncodeToString(hash[:])
    request, err := http.NewRequest("POST", strings.TrimRight(origin,"/")+"/reseller/v1/sandbox/orders", bytes.NewReader(payload))
    if err != nil { panic("Invalid API URL") }
    request.Header.Set("Authorization", "Bearer "+key)
    request.Header.Set("Content-Type", "application/json")
    request.Header.Set("Idempotency-Key", identity)
    response, err := (&http.Client{Timeout:20*time.Second}).Do(request)
    if err != nil { panic("Unknown transport result: retry same identity/body") }
    defer response.Body.Close()
    if response.StatusCode < 200 || response.StatusCode >= 300 { panic(fmt.Sprintf("API HTTP %d; request %s",response.StatusCode,response.Header.Get("X-Request-ID"))) }
    var order struct { ID string `json:"id"`; State string `json:"state"` }
    if err := json.NewDecoder(response.Body).Decode(&order); err != nil { panic("Invalid API response: recover same order") }
    fmt.Println(order.ID, order.State)
}
```

## Webhook receiver check

```python
import hashlib, hmac, time

def valid_signature(secret, header, raw_body):
    try:
        parts = dict(item.split("=", 1) for item in header.split(","))
        timestamp = int(parts["t"])
        if abs(time.time() - timestamp) > 300:
            return False
        expected = hmac.new(secret.encode(), (str(timestamp) + ".").encode() + raw_body, hashlib.sha256).hexdigest()
        return hmac.compare_digest(expected, parts["v1"])
    except (ValueError, KeyError):
        return False
```

Validate raw bytes before JSON parsing, deduplicate event IDs durably, acknowledge quickly, then fetch the authoritative order. No credentials are contained in event payloads.

## Postman and API reference

Import `TrustedTools.postman_collection.json`; set `origin` and `api_key` privately. The collection contains only reads and synthetic sandbox creation, avoiding accidental live spending. Do not share an exported environment containing your key. Use the downloadable OpenAPI to generate additional clients or import the complete production contract. The web Swagger viewer is local/read-only and does not save or execute authorization requests.
