npm package: @hashcase/merchant-sdk
Description: Official SDK for the Hashcase Merchant API
Latest version: 0.1.1

# @hashcase/merchant-sdk

Official JavaScript/TypeScript SDK for the **Hashcase Merchant API**. Manage loyalty programs, users, rewards, tiers, and orders with a fully typed client.

---

## Installation

```bash
npm install @hashcase/merchant-sdk
```

> **Requirements:** Node.js 18+ (uses the native `fetch` API)

---

## Quick Start

```typescript
import { HashcaseMerchantClient } from '@hashcase/merchant-sdk';

const client = new HashcaseMerchantClient(
  'your-api-key',           // required — x-api-key header value
  'https://api.hashcase.co', // optional — defaults to https://api.hashcase.co
  10000                      // optional — timeout in ms, defaults to 10000
);
```

The client exposes six resource namespaces:

| Namespace | Description |
|-----------|-------------|
| `client.users` | Register users, award/redeem points |
| `client.loyalty` | Manage loyalty codes |
| `client.tiers` | Manage membership tiers |
| `client.rewards` | Manage redeemable rewards |
| `client.orders` | Create and process orders |
| `client.transactions` | View point transaction history |

---

## Resources

### Users — `client.users`

#### Register a user

```typescript
const user = await client.users.add({
  name: 'Jane Doe',
  email: 'jane@example.com',
  phone: '+1234567890',
  password: 'securepassword',
});
// => User { id, name, email, phone, balance, enrolled_at }
```

#### List all enrolled users

```typescript
const users = await client.users.list();
// => User[]
```

#### Get a user with tier info

```typescript
const detail = await client.users.get(userId);
// => UserDetail { ...User, total_points_earned, current_tier, next_tier, points_to_next_tier }
```

#### Award points via a loyalty code

```typescript
const result = await client.users.addPoints({
  user_id: 42,           // or use email / phone instead
  code_id: 1,
  amount: 500,           // transaction amount (used for point calculation)
  payment_method: {
    type: 'upi',
    upi_id: 'jane@okaxis',
  },
});
// => PointsResult { user_id, points_added, balance_before, balance_after }
```

#### Redeem points

```typescript
const result = await client.users.redeemPoints({
  user_id: 42,
  code_id: 2,
  amount: 200,
  payment_method: {
    type: 'card',
    card_number: '4111111111111111',
    card_type: 'credit',
    network: 'Visa',
    expiry: '12/27',
  },
});
// => PointsResult { user_id, points_redeemed, balance_before, balance_after }
```

#### Get a user's order history

```typescript
const orders = await client.users.getOrders(userId);
// => OrderWithDetails[]
```

#### Get a user's rewards status

```typescript
const rewards = await client.users.getRewards(userId);
// => UserRewards { claimed_rewards, pending_rewards, balance, current_tier }
```

---

### Loyalty Codes — `client.loyalty`

#### List all loyalty codes

```typescript
const codes = await client.loyalty.list();
// => Loyalty[]
```

#### Create a loyalty code

```typescript
const code = await client.loyalty.create({
  loyalty: {
    code: 'WELCOME10',
    value: 10,
    type: 'percentage',
    // Optional: restrict availability to a date window
    availability_rule: {
      name: 'Holiday window',
      rule_type: 'availability_window',
      timezone: 'Asia/Kolkata',
      start_date: '2025-12-01',
      end_date: '2025-12-31',
    },
    // Optional: reset usage count daily
    reset_rule: {
      name: 'Daily reset',
      rule_type: 'recurring_reset',
      timezone: 'Asia/Kolkata',
      reset_unit: 'days',
      reset_value: 1,
      reset_time: '00:00',
    },
  },
});
// => Loyalty
```

#### Update a loyalty code

```typescript
const updated = await client.loyalty.update({
  loyalty: {
    id: 5,
    value: 15,
    is_active: false,
  },
});
```

#### Delete a loyalty code

```typescript
await client.loyalty.delete(codeId);
```

---

### Membership Tiers — `client.tiers`

#### List all tiers

```typescript
const tiers = await client.tiers.list();
// => Tier[]
```

#### Get a single tier

```typescript
const tier = await client.tiers.get(tierId);
// => Tier { id, level, minValue, name, createdAt, updatedAt }
```

#### Create a tier

```typescript
const tier = await client.tiers.create({
  tier: {
    level: 1,
    minValue: 0,
    name: 'Silver',
  },
});
```

#### Update a tier

```typescript
const tier = await client.tiers.update(tierId, {
  tier: {
    level: 2,
    minValue: 500,
    name: 'Gold',
  },
});
```

#### Delete a tier

```typescript
await client.tiers.delete(tierId);
```

---

### Rewards — `client.rewards`

Rewards are redeemable by users using loyalty points.

#### List all rewards

```typescript
const rewards = await client.rewards.list();
// => Reward[]
```

#### Get a single reward

```typescript
const reward = await client.rewards.get(rewardId);
```

#### Create a reward

```typescript
// 10% discount on total bill
const reward = await client.rewards.create({
  reward: {
    point_cost: 200,
    type: 'DISCOUNT_ON_TOTAL',
    discountType: 'PERCENTAGE',
    discountValue: 10,
  },
});

// Fixed ₹50 off a specific item
const reward2 = await client.rewards.create({
  reward: {
    point_cost: 100,
    type: 'DISCOUNT_ON_ITEM',
    discountType: 'FIXED_AMOUNT',
    discountValue: 50,
    productName: 'Cappuccino',
    requiredTierId: 2, // optional — restrict to Gold tier+
  },
});

// Free product
const reward3 = await client.rewards.create({
  reward: {
    point_cost: 500,
    type: 'GENERIC_FREE_PRODUCT',
    productName: 'Croissant',
  },
});
```

#### Update a reward

```typescript
const updated = await client.rewards.update(rewardId, {
  reward: { point_cost: 150 },
});
```

#### Delete a reward

```typescript
await client.rewards.delete(rewardId);
```

---

### Orders — `client.orders`

Orders represent a customer transaction that may apply a loyalty code and/or redeem a reward.

#### Create an order (pending)

```typescript
const order = await client.orders.create({
  user_id: 42,
  bill_amount: 1200,
  selected_loyalty_id: 1,   // optional
  selected_reward_id: 3,    // optional
  payment_method: {
    type: 'upi',
    upi_id: 'jane@okaxis',
  },
});
// => MerchantOrder { id, status: 'pending', ... }
```

#### List all orders

```typescript
const orders = await client.orders.list();
// => OrderWithDetails[]
```

#### Accept or reject a pending order

```typescript
// Accept — applies loyalty points and redeems reward
const processed = await client.orders.process({
  id: order.id,
  user_id: 42,
  merchant_id: order.merchant_id,
  bill_price: 1200,
  status: 'accepted',
  selected_loyalty_id: 1,
  selected_reward_id: 3,
});

// Reject
await client.orders.process({
  id: order.id,
  user_id: 42,
  merchant_id: order.merchant_id,
  bill_price: 1200,
  status: 'rejected',
});
```

---

### Transactions — `client.transactions`

#### List all point transactions

```typescript
const txns = await client.transactions.list();
// => Transaction[]
// Each transaction: { id, action, amount, balance_before, balance_after, note, user, payment_method }
```

---

## Error Handling

All methods throw a `HashcaseError` on API or network failure.

```typescript
import { HashcaseError } from '@hashcase/merchant-sdk';

try {
  const user = await client.users.get(9999);
} catch (err) {
  if (err instanceof HashcaseError) {
    console.error(err.message);  // human-readable message from the API
    console.error(err.status);   // HTTP status code (e.g. 404, 401, 408)
    console.error(err.details);  // optional extra details from the API
  }
}
```

Common status codes:

| Status | Meaning |
|--------|---------|
| `401` | Invalid or missing API key |
| `404` | Resource not found |
| `408` | Request timed out |
| `422` | Validation error — check `err.details` |
| `500` | Server error |

---

## TypeScript Types

All request and response types are exported from the package:

```typescript
import type {
  // Users
  AddUserRequest, User, UserDetail, UserRewards,
  // Points
  AddPointsRequest, RedeemPointsRequest, PointsResult,
  // Loyalty
  Loyalty, CreateLoyaltyRequest, UpdateLoyaltyRequest,
  // Tiers
  Tier, CreateTierRequest, UpdateTierRequest,
  // Rewards
  Reward, CreateRewardRequest, UpdateRewardRequest,
  // Orders
  MerchantOrder, OrderWithDetails, CreateOrderRequest, ProcessOrderRequest,
  // Transactions
  Transaction,
  // Payment methods
  PaymentMethod, CardPayment, UPIPayment,
  // Time rules
  TimeRule,
} from '@hashcase/merchant-sdk';
```

---

## API Reference

Full API reference generated from source is available in the [`docs/`](./docs/index.html) folder.

To regenerate locally:

```bash
cd sdk
npm install
npm run docs
# open docs/index.html in a browser
```