Skip to main content
POST
/
loyalty
/
transactions
Record Loyalty Transaction
curl --request POST \
  --url https://api.example.com/loyalty/transactions \
  --header 'Authorization: <authorization>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "member_id": "<string>",
  "company_id": "<string>",
  "transaction_type": "<string>",
  "order": {
    "order_id": "<string>",
    "total_value": 123,
    "currency": "<string>",
    "items": [
      {
        "name": "<string>",
        "price": 123,
        "category": "<string>",
        "quantity": 123
      }
    ],
    "payment_method": "<string>",
    "platform": "<string>"
  },
  "context": {
    "timestamp": "<string>",
    "day_of_week": "<string>",
    "hour": 123,
    "active_campaigns": [
      {}
    ],
    "location": "<string>"
  }
}
'
{
  "transaction_id": "<string>",
  "member_id": "<string>",
  "points": {
    "base_points": 123,
    "final_points": 123,
    "modifiers_applied": [
      {}
    ],
    "previous_balance": 123,
    "new_balance": 123
  },
  "new_tier_achieved": "<string>",
  "next_reward_progress": {
    "reward_name": "<string>",
    "points_needed": 123,
    "progress_percentage": 123
  },
  "rfm_update": {
    "previous": "<string>",
    "current": "<string>",
    "upgrade": true
  },
  "coupons_generated": [
    {}
  ]
}

Overview

This endpoint processes customer transactions and awards loyalty points based on the company’s configured conversion rules. The system automatically calculates points using the base conversion rate, applies rounding rules, and includes any active modifiers (item bonuses, time-based multipliers, RFM segments, campaigns).
Automatic Calculation: Points are calculated using: base_points = transaction_value × points_per_currency_unit, then rounding is applied according to company configuration, followed by modifier multipliers.

Authentication

Authorization
string
required
Bearer token for API authentication
Authorization: Bearer {your_api_key}

Request Body

member_id
string
required
Zupy customer identifier
ZP-4F95FB0A
company_id
string
required
Company identifier for points calculation
comp_bella_vista
transaction_type
string
required
Type of transaction being recorded
purchase | return | adjustment | bonus
order
object
required
Order details for points calculation
context
object
Transaction context for modifier calculation

Response

transaction_id
string
Unique transaction identifier
member_id
string
Customer identifier
points
object
Points calculation details
new_tier_achieved
string
New loyalty tier if customer was promoted (null if no change)
next_reward_progress
object
Progress towards next available reward
rfm_update
object
RFM classification changes
coupons_generated
array
List of coupons automatically generated from this transaction

Example Request

curl -X POST "https://api.zupy.com/v1/loyalty/transactions" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "member_id": "ZP-4F95FB0A",
    "company_id": "comp_bella_vista",
    "transaction_type": "purchase",
    "order": {
      "order_id": "ord_12345",
      "total_value": 35.00,
      "currency": "BRL",
      "items": [
        {
          "name": "Pizza Margherita",
          "price": 35.00,
          "category": "pizza",
          "quantity": 1
        }
      ],
      "payment_method": "credit_card",
      "platform": "goomer"
    },
    "context": {
      "timestamp": "2025-08-26T15:30:00Z",
      "day_of_week": "monday",
      "hour": 15,
      "active_campaigns": ["semana_italiana"],
      "location": "delivery"
    }
  }'

Example Response

{
  "transaction_id": "tx_789ABC123",
  "member_id": "ZP-4F95FB0A",
  "points": {
    "base_points": 35,
    "final_points": 35,
    "modifiers_applied": [],
    "previous_balance": 847,
    "new_balance": 882
  },
  "new_tier_achieved": null,
  "next_reward_progress": {
    "reward_name": "Refrigerante Grátis",
    "points_needed": 118,
    "progress_percentage": 79.3
  },
  "rfm_update": {
    "previous": "Loyal Customer",
    "current": "Champion",
    "upgrade": true
  },
  "coupons_generated": []
}

Points Calculation Examples

Based on company configuration, here’s how points are calculated:

Example A: Simple Calculation

Company Config: 10 points/real, round_down, minimum R$ 1.00
Transaction: R$ 35.00
Calculation: 35.00 × 10 = 350.0 → 350 points (round_down)
Final: 350 points awarded

Example B: With Category Bonus

Company Config: 10 points/real, round_down
Transaction: R$ 35.00 pizza
Category Bonus: pizza = 1.5× multiplier
Calculation: (35.00 × 10) × 1.5 = 350 × 1.5 = 525 points
Final: 525 points awarded

Example C: Multiple Modifiers

Company Config: 10 points/real, round_down
Transaction: R$ 35.00 pizza on Monday during "semana_italiana"
Modifiers: pizza (1.5×) + campaign (1.3×)
Calculation: (35.00 × 10) × 1.5 × 1.3 = 682.5 → 682 points
Final: 682 points awarded

Example D: RFM Multiplier

Company Config: 10 points/real + RFM tiers
Customer: Champion tier (1.2× RFM multiplier)
Transaction: R$ 35.00
Calculation: (35.00 × 10) × 1.2 = 420 points
Final: 420 points awarded

Available Modifiers

category_bonus
Category Bonus: Multiplier based on item category (pizza, beverage, dessert)
campaign_bonus
Campaign Bonus: Active promotional campaign multipliers
time_bonus
Time Bonus: Day of week or hour-based bonuses (happy hour, weekend)
rfm_multiplier
RFM Multiplier: Customer segment-based bonus (Champion, Loyal, etc.)
payment_bonus
Payment Bonus: Payment method incentives (PIX, digital wallet)
platform_bonus
Platform Bonus: Channel-specific bonuses (online, app, delivery)

Business Rules

Transaction Processing

  • Minimum Value: Transactions below company’s minimum_transaction earn 0 points
  • Rounding: Applied after base calculation but before modifiers
  • Modifiers: Applied sequentially (multiplicative, not additive)
  • Currency: Only BRL supported currently

Automatic Actions

  • Tier Upgrades: Calculated based on total points or RFM changes
  • RFM Updates: Recalculated after each transaction
  • Coupon Generation: Triggered by tier changes, milestones, or campaigns
  • Reward Progress: Updated to show next achievable reward

Data Validation

  • Member ID: Must exist and be active
  • Company ID: Must match customer’s associated company
  • Order Total: Must match sum of item prices × quantities
  • Currency: Must be “BRL”

Error Codes

CodeDescription
customer_not_foundCustomer doesn’t exist or is inactive
company_not_foundInvalid company_id provided
company_mismatchCustomer not associated with this company
transaction_below_minimumTransaction value below minimum threshold
invalid_currencyCurrency other than BRL provided
duplicate_transactionTransaction with same order_id already processed
calculation_errorError in points calculation engine

Rate Limits

  • Production: 1000 transactions per minute per company
  • Staging: 200 transactions per minute per company
Idempotency: Use unique order_id values to prevent duplicate transactions. The system will reject transactions with duplicate order IDs within the same company.
Performance Tip: Include all available context data for more accurate modifier calculations and better customer segmentation.