npm package: @progus/connector
Description: Progus partner/affiliate connector helpers
Latest version: 0.7.5

# @progus/connector

Headless connector for Progus partner/affiliate tracking and partner ID assignment.

## Installation

```bash
npm install @progus/connector
```

## Minimal Integration

Integrate the partner program in 4 steps:

### 1. Server connector setup

```ts
// utils/progus-connector.server.ts
import { createProgusConnector } from "@progus/connector";

export function isPartnersConnectorConfigured(): boolean {
  return Boolean(process.env.PARTNERS_API_URL && process.env.PARTNERS_SECRET_KEY);
}

export function getPartnersConnector() {
  return createProgusConnector({
    appKey: "your-app-name",
    apiBaseUrl: process.env.PARTNERS_API_URL || "",
    signingSecret: process.env.PARTNERS_SECRET_KEY || "",
    apiKey: process.env.PARTNERS_API_KEY,
  });
}
```

### 2. Cookie-based install tracking (client-side)

```ts
// On app load (e.g. in root route useEffect)
const cookieMatch = document.cookie.match(/(?:^|; )progus_partner_id=([^;]*)/);
const partnerId = cookieMatch ? decodeURIComponent(cookieMatch[1]) : null;

if (partnerId) {
  await connector.trackInstall({ shopDomain: session.shop, partnerId });
  document.cookie = "progus_partner_id=; Path=/; Max-Age=0"; // clear after tracking
}
```

### 3. Partner ID assignment (Save Partner ID button)

```ts
// On "Save Partner ID" action
const result = await connector.assignPartnerIdWithSubscription({
  shopDomain: session.shop,
  partnerId: inputValue,
  admin, // Shopify Admin GraphQL client
});

if (result.success) {
  // Lock the input field, show success
}
```

### 4. Required webhooks

**APP_SUBSCRIPTIONS_UPDATE** - track subscription changes:
```ts
await connector.trackSubscriptionUpdated({
  shopDomain: shop,
  data: {
    subscriptionId,        // numeric ID (required)
    subscriptionPrice,     // number (required)
    subscriptionPeriod,    // "EVERY_30_DAYS" or "ANNUAL" (required)
    subscriptionStatus,    // e.g. "ACTIVE", "CANCELLED"
    subscriptionName,      // plan name
  },
});
```

**APP_UNINSTALLED** - track uninstalls:
```ts
await connector.trackUninstall({ shopDomain: shop });
```

## AI Prompt: Partner program implementation

Copy/paste for AI assistants:

```
You are integrating Progus Partner Program using @progus/connector in a Shopify app.

Required files to create/modify:

1) Server connector (utils/progus-connector.server.ts):
   - createProgusConnector({ appKey, apiBaseUrl, signingSecret, apiKey })
   - export getPartnersConnector() and isPartnersConnectorConfigured()

2) Cookie-based install tracking (client-side, on app load):
   - read cookie "progus_partner_id" (HttpOnly=false, SameSite=None, Secure)
   - if exists: call connector.trackInstall({ shopDomain, partnerId })
   - clear cookie after successful tracking
   - if no cookie, skip tracking

3) Partner ID assignment UI (on "Save Partner ID" button):
   - call connector.assignPartnerIdWithSubscription({ shopDomain, partnerId, admin })
   - admin = Shopify Admin GraphQL client
   - connector normalizes partnerId and fetches active subscription automatically
   - subscription event sent ONLY if price + period are available
   - lock the Partner ID field after success
   - optionally: check existing partnerId on load with connector.checkPartnerId({ shopDomain })

4) APP_SUBSCRIPTIONS_UPDATE webhook (required):
   - call connector.trackSubscriptionUpdated({ shopDomain, data })
   - data must include: subscriptionId (number), subscriptionPrice (number), subscriptionPeriod ("EVERY_30_DAYS" | "ANNUAL")
   - if webhook payload missing price/interval, query: node(id) -> AppSubscription -> lineItems.plan.pricingDetails
   - connector validates; event skipped if price/period missing

5) APP_UNINSTALLED webhook (required):
   - call connector.trackUninstall({ shopDomain })

Error handling: catch and log errors; never break webhooks on partner tracking failure.
```

## Validation

The connector handles all validation internally:
- `trackInstall` normalizes partnerId (trims, checks format)
- `trackSubscriptionUpdated` validates price/period; skips if missing
- Apps do not need to validate before calling connector methods

## Optional signing helper

```ts
import { signPayload } from "@progus/connector";

const signature = signPayload(JSON.stringify({ test: true }), process.env.PARTNERS_SECRET_KEY!);
```

## Cross-sell recommendations (server-side)

Use the connector to fetch and filter the Progus apps catalog on the backend,
then pass the list to your frontend UI.

```ts
import { getCrossSellOffersFromApi } from "@progus/connector";

const recommendations = await getCrossSellOffersFromApi({
  appName: "progus-store-locator",
  limit: 3,
  fetch, // pass your server-side fetch
});
```

## UI components

Use `@progus/connector-ui` for UI components. It re-exports cross-sell helpers
from `@progus/connector`.

## Environment variables

- `PARTNERS_API_URL` - base URL for partner API (e.g. `https://partners.example.com`)
- `PARTNERS_SECRET_KEY` - signing secret for HMAC (required for tracking)
- `PARTNERS_API_KEY` - optional API key header

## Publishing

```bash
npm run build
npm publish --access public
```

## Smoke script

```bash
npm run smoke
```