Files
Swarm/README_GIFT_SUBSCRIPTIONS.md
2025-10-03 14:36:27 +08:00

9.0 KiB

Gift Subscriptions API Documentation

Overview

The Gift Subscriptions feature allows users to purchase subscription gifts that can be redeemed by other users, enabling social gifting and subscription sharing within the DysonNetwork platform.

If you use it through the gateway, the /api should be replaced with the /id

Key Features

  • Purchase Gifts: Users can buy subscriptions as gifts for specific recipients or as open gifts
  • Gift Codes: Each gift has a unique redemption code
  • Flexible Redemption: Open gifts can be redeemed by anyone, while targeted gifts are recipient-specific
  • Security: Prevents duplicate subscriptions and enforces account level requirements
  • Integration: Full integration with existing subscription, coupon, and pricing systems
  • Clean User Experience: Unpaid gifts are hidden from users and automatically cleaned up
  • Automatic Maintenance: Old unpaid gifts are removed after 24 hours

API Endpoints

All endpoints are authenticated and require a valid user session. The base path for gift endpoints is /api/gifts.

1. List Sent Gifts

Retrieve gifts you have purchased.

GET /api/gifts/sent?offset=0&take=20
Authorization: Bearer <token>

Response: Array of SnWalletGift objects

2. List Received Gifts

Retrieve gifts sent to you or redeemed by you (for open gifts).

GET /api/gifts/received?offset=0&take=20
Authorization: Bearer <token>

Response: Array of SnWalletGift objects

3. Get Specific Gift

Retrieve details for a specific gift.

GET /api/gifts/{giftId}
Authorization: Bearer <token>

Parameters:

  • giftId: GUID of the gift

Response: SnWalletGift object

4. Check Gift Code

Validate if a gift code can be redeemed by the current user.

GET /api/gifts/check/{giftCode}
Authorization: Bearer <token>

Response:

{
  "gift_code": "ABCD1234EFGH",
  "subscription_identifier": "basic",
  "can_redeem": true,
  "error": null,
  "message": "Happy birthday!"
}

5. Purchase a Gift

Create and purchase a gift subscription.

POST /api/gifts/purchase
Authorization: Bearer <token>
Content-Type: application/json

{
  "subscription_identifier": "premium",
  "recipient_id": "550e8400-e29b-41d4-a716-446655440000",  // Optional: null for open gifts
  "payment_method": "in_app_wallet",
  "payment_details": {
    "currency": "irl"
  },
  "message": "Enjoy your premium subscription!",  // Optional
  "coupon": "SAVE20",  // Optional
  "gift_duration_days": 30,  // Optional: defaults to 30
  "subscription_duration_days": 30  // Optional: defaults to 30
}

Response: SnWalletGift object

6. Redeem a Gift

Redeem a gift code to create a subscription for yourself.

POST /api/gifts/redeem
Authorization: Bearer <token>
Content-Type: application/json

{
  "gift_code": "ABCD1234EFGH"
}

Response:

{
  "gift": { ... },
  "subscription": { ... }
}

7. Mark Gift as Sent

Mark a gift as sent (ready for redemption).

POST /api/gifts/{giftId}/send
Authorization: Bearer <token>

Parameters:

  • giftId: GUID of the gift to mark as sent

8. Cancel a Gift

Cancel a gift before it has been redeemed.

POST /api/gifts/{giftId}/cancel
Authorization: Bearer <token>

Parameters:

  • giftId: GUID of the gift to cancel

Usage Examples

Client Implementation

Here are examples showing how to integrate gift subscriptions into your client application.

Example 1: Purchase a Gift for a Specific User

async function purchaseGiftForFriend(subscriptionId, friendId, message) {
  const response = await fetch('/api/gifts/purchase', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscription_identifier: subscriptionId,
      recipient_id: friendId,
      payment_method: 'in_app_wallet',
      payment_details: { currency: 'irl' },
      message: message
    })
  });

  const gift = await response.json();
  return gift.gift_code; // Share this code with the friend
}

Example 2: Create an Open Gift

async function createOpenGift(subscriptionId) {
  const response = await fetch('/api/gifts/purchase', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      subscription_identifier: subscriptionId,
      payment_method: 'in_app_wallet',
      payment_details: { currency: 'irl' },
      message: 'Redeem this anywhere!'
      // No recipient_id makes it an open gift
    })
  });

  const gift = await response.json();
  // Mark as sent to make it redeemable
  await markGiftAsSent(gift.id);
  return gift;
}

Example 3: Redeem a Gift Code

async function redeemGiftCode(giftCode) {
  // First, check if the gift can be redeemed
  const checkResponse = await fetch(`/api/gifts/check/${giftCode}`, {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  const checkResult = await checkResponse.json();

  if (!checkResult.canRedeem) {
    throw new Error(checkResult.error);
  }

  // If valid, redeem it
  const redeemResponse = await fetch('/api/gifts/redeem', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      gift_code: giftCode
    })
  });

  const result = await redeemResponse.json();
  return result.subscription; // The newly created subscription
}

Example 4: Display User's Gift History

async function getGiftHistory() {
  // Get gifts I sent
  const sentResponse = await fetch('/api/gifts/sent', {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  const sentGifts = await sentResponse.json();

  // Get gifts I received
  const receivedResponse = await fetch('/api/gifts/received', {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  const receivedGifts = await receivedResponse.json();

  return { sent: sentGifts, received: receivedGifts };
}

Gift Status Lifecycle

Gifts follow this status lifecycle:

  1. Created: Initially purchased, can be cancelled or marked as sent
    • Note: Gifts in "Created" status are not visible to users and are automatically cleaned up after 24 hours if unpaid
  2. Sent: Made available for redemption, can be cancelled
  3. Redeemed: Successfully redeemed, creates a subscription
  4. Cancelled: Permanently cancelled, refund may be processed
  5. Expired: Expired without redemption

Automatic Maintenance

The system includes automatic cleanup to maintain data integrity:

  • Unpaid Gift Cleanup: Gifts that remain in "Created" status (unpaid) for more than 24 hours are automatically removed from the database
  • User Visibility: Only gifts that have been successfully paid and sent are visible in user gift lists
  • Background Processing: Cleanup runs hourly via scheduled jobs

This ensures a clean user experience while preventing accumulation of abandoned gift purchases.

Validation Rules

Purchase Validation

  • Subscription must exist and be valid
  • If coupon provided, it must be valid and applicable
  • Recipient account must exist (if specified)
  • User must meet level requirements for the subscription

Redemption Validation

  • Gift code must exist
  • Gift must be in "Sent" status
  • Gift must not be expired
  • User must meet level requirements
  • User must not already have an active subscription of the same type
  • For targeted gifts, user must be the specified recipient

Pricing & Payments

Gifts use the same pricing system as regular subscriptions:

  • Base price from subscription template
  • Coupon discounts applied
  • Currency conversion as needed
  • Payment processing through existing payment methods

Notification Events

The system sends push notifications for:

  • gifts.redeemed: When someone redeems your gift
  • gifts.claimed: When the recipient redeems your targeted gift

Notifications include gift and subscription details for rich UI updates.

Error Handling

Common error responses:

  • 400 Bad Request: Invalid parameters, validation failures
  • 401 Unauthorized: Missing or invalid authentication
  • 403 Forbidden: Insufficient permissions
  • 404 Not Found: Gift or subscription not found
  • 409 Conflict: Business logic violations (duplicate subscriptions, etc.)

Integration Notes

Database Schema

The feature adds a wallet_gifts table with relationships to:

  • accounts (gifter, recipient, redeemer)
  • wallet_subscriptions (created subscription)
  • wallet_coupons (applied discounts)

Backwards Compatibility

  • No changes to existing subscription endpoints
  • New gift-related endpoints are additive
  • Existing payment flows remain unchanged

Performance Considerations

  • Gift codes are indexed for fast lookups
  • Status filters optimize database queries
  • Caching integrated with existing subscription caching

Support

For implementation questions or issues, refer to the DysonNetwork API documentation or contact the development team.