> ## Documentation Index
> Fetch the complete documentation index at: https://playcamp.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Coupon Redemption

> Validating and redeeming creator coupon codes

Redeem coupon codes distributed by creators.

## Flow

```
1. Enter coupon code  →  2. Validate  →  3. Redeem coupon  →  4. Grant rewards
```

## Validate Coupon

Check if the coupon is valid before use.

**Request**

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://sandbox-sdk-api.playcamp.io/v1/server/coupons/validate" \
      -H "Authorization: Bearer ak_server_xxx:secret" \
      -H "Content-Type: application/json" \
      -d '{
        "couponCode": "CREATOR-ABC12-001",
        "userId": "user_12345"
      }'
    ```
  </Tab>

  <Tab title="Node SDK">
    ```typescript theme={null}
    // Server SDK
    const validation = await server.coupons.validate({
      couponCode: 'CREATOR-ABC12-001',
      userId: 'user_12345',
    });

    // Client SDK (also available)
    const validation = await client.coupons.validate({
      couponCode: 'CREATOR-ABC12-001',
    });
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    // Server SDK
    validation, err := server.Coupons.Validate(ctx, playcamp.ValidateCouponServerParams{
        CouponCode: "CREATOR-ABC12-001",
        UserID:     "user_12345",
    })

    // Client SDK (also available)
    validation, err := client.Coupons.Validate(ctx, playcamp.ValidateCouponParams{
        CouponCode: "CREATOR-ABC12-001",
    })
    ```
  </Tab>
</Tabs>

**Response (Valid)**

```json theme={null}
{
  "data": {
    "valid": true,
    "couponCode": "CREATOR-ABC12-001",
    "reward": [
      { "itemId": "gem", "itemQuantity": 100, "itemImageUrl": "https://cdn.example.com/gem.png" }
    ],
    "packageName": { "ko": "Welcome Package", "en": "Welcome Package" },
    "creatorKey": "ABC12",
    "campaignId": "campaign_001"
  }
}
```

**Response (Invalid)**

```json theme={null}
{
  "data": {
    "valid": false,
    "couponCode": "INVALID-CODE",
    "errorCode": "COUPON_NOT_FOUND",
    "errorMessage": "Coupon not found"
  }
}
```

## Redeem Coupon

Actually use the coupon after validation.

**Request**

<Tabs>
  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://sandbox-sdk-api.playcamp.io/v1/server/coupons/redeem" \
      -H "Authorization: Bearer ak_server_xxx:secret" \
      -H "Content-Type: application/json" \
      -d '{
        "couponCode": "CREATOR-ABC12-001",
        "userId": "user_12345",
        "callbackId": "game-session-abc123"
      }'
    ```
  </Tab>

  <Tab title="Node SDK">
    ```typescript theme={null}
    const result = await server.coupons.redeem({
      couponCode: 'CREATOR-ABC12-001',
      userId: 'user_12345',
      callbackId: 'game-session-abc123', // optional
    });
    ```
  </Tab>

  <Tab title="Go SDK">
    ```go theme={null}
    result, err := server.Coupons.Redeem(ctx, playcamp.RedeemCouponParams{
        CouponCode: "CREATOR-ABC12-001",
        UserID:     "user_12345",
        CallbackID: "game-session-abc123", // optional
    })
    ```
  </Tab>
</Tabs>

**Response (200 OK)**

```json theme={null}
{
  "data": {
    "success": true,
    "usageId": 5678,
    "couponCode": "CREATOR-ABC12-001",
    "reward": [
      { "itemId": "gem", "itemQuantity": 100, "itemImageUrl": "https://cdn.example.com/gem.png" }
    ],
    "packageName": { "ko": "Welcome Package" },
    "creatorKey": "ABC12",
    "campaignId": "campaign_001",
    "redeemedAt": "2024-01-15T10:30:00.000Z"
  }
}
```

## Error Codes

| Code                   | Description                       |
| ---------------------- | --------------------------------- |
| `COUPON_NOT_FOUND`     | Non-existent coupon               |
| `COUPON_INACTIVE`      | Deactivated coupon                |
| `COUPON_NOT_YET_VALID` | Before valid period               |
| `COUPON_EXPIRED`       | Expired                           |
| `USER_CODE_LIMIT`      | User code usage limit exceeded    |
| `USER_PACKAGE_LIMIT`   | User package usage limit exceeded |
| `TOTAL_USAGE_LIMIT`    | Total usage limit exceeded        |

## Complete Flow Example (Node SDK)

```typescript theme={null}
import { PlayCampServer } from '@playcamp/node-sdk';

const server = new PlayCampServer('your_server_key:your_secret');

async function redeemCoupon(userId: string, couponCode: string) {
  // 1. Validate
  const validation = await server.coupons.validate({ couponCode, userId });

  if (!validation.valid) {
    return {
      success: false,
      error: validation.errorCode,
      message: validation.errorMessage,
    };
  }

  // 2. Redeem
  const result = await server.coupons.redeem({ couponCode, userId });

  // 3. Grant in-game rewards
  for (const reward of result.reward) {
    await giveItemToUser(userId, reward.itemId, reward.itemQuantity);
  }

  return { success: true, reward: result.reward };
}
```
