Skip to content
Last updated

Rewards let you turn part of a payment into credits that a customer can spend on a later one. The credits sit on a reward account tied to your marketplace and follow the customer who earned them only that customer can redeem them, and the credits expire after a set period (12 months by default).

The flow has two sides. You generate rewards by attaching a reward block to one or more splits inside a capture. You redeem them later by sending a reward_redemption block on the next capture. In between, you can read what each customer has on hand through the Customer endpoints.

How rewards work

The reward account is marketplace-scoped. It's provisioned during onboarding there's no API to create one and you reference it by its UUID inside every reward generation and redemption.

Each entry on a reward account is tied to one customer. When a payment includes a split with a reward block, the customer named at the top of the request is credited for the amount in reward.value. That credit becomes part of the customer's available balance until it's redeemed or expires.

Redemption works the other way around: on a later capture for the same customer, send a reward_redemption block and the matching value is debited from the balance and applied against the payment.

Generating rewards on a capture

Attach a reward block to any split inside the capture.splits[] array. The customer at the top of the request is the one credited.

curl -X POST 'https://api.test.easypay.pt/2.0/single' \
  -H 'AccountId: YOUR_ACCOUNT_ID' \
  -H 'ApiKey: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "sale",
    "method": "cc",
    "value": 50.00,
    "currency": "EUR",
    "customer": {
      "id": "649e88cf-0b78-4c36-8f99-33f5ebb812a1",
      "name": "John Doe",
      "email": "john.doe@example.com"
    },
    "capture": {
      "descriptive": "Order #1029",
      "splits": [
        {
          "split_descriptive": "Marketplace seller",
          "account": {
            "id": "7e697e0c-c2bf-422a-9535-ab0b750bb832"
          },
          "value": 50.00,
          "reward": {
            "account": {
              "id": "458b2fc4-3092-4de3-abd4-fe1600c09420"
            },
            "value": 2.50,
            "expiration_date": "2027-04-02"
          }
        }
      ]
    }
  }'

What each reward field does:

  • reward.account.id: the marketplace's reward account that holds the credit. Use the same UUID across every reward you want pooled on the same balance.
  • reward.value: how much of that split becomes a credit. It doesn't change what the customer pays at the till; it's an amount the marketplace contributes off the split's value.
  • reward.expiration_date: optional. Defaults to 12 months from the transaction date. Past this date the credit can no longer be redeemed.

Reading a customer's balance

Two endpoints expose what a customer has.

GET /customer/{id} returns the customer plus a reward_balances array with one entry per reward account they hold credits on. Use this when you want a quick total before showing a "Use your rewards" option at checkout.

{
    "id": "649e88cf-0b78-4c36-8f99-33f5ebb812a1",
    "name": "John Doe",
    "email": "john.doe@example.com",
    "reward_balances": [
        {
            "account_id": "458b2fc4-3092-4de3-abd4-fe1600c09420",
            "available_balance": 12.5
        }
    ]
}

GET /customer/{id}/rewards lists every individual movement on the ledger each REWARD earned and each REDEMPTION spent newest first. It supports filtering by account, type, expiry, and creation date.

curl 'https://api.test.easypay.pt/2.0/customer/649e88cf-0b78-4c36-8f99-33f5ebb812a1/rewards?type[]=REWARD&account_id[]=458b2fc4-3092-4de3-abd4-fe1600c09420' \
  -H 'AccountId: YOUR_ACCOUNT_ID' \
  -H 'ApiKey: YOUR_API_KEY'
{
    "metadata": { "next_cursor": null, "count": 2 },
    "data": [
        {
            "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
            "account_id": "458b2fc4-3092-4de3-abd4-fe1600c09420",
            "type": "REWARD",
            "amount": 10.0,
            "expiration_date": "2027-01-15",
            "capture": { "id": "c6056234-a3f9-42de-b944-3ed793fcb6bb" },
            "created_at": "2026-01-15T10:30:00Z"
        },
        {
            "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
            "account_id": "458b2fc4-3092-4de3-abd4-fe1600c09420",
            "type": "REWARD",
            "amount": 2.5,
            "expiration_date": "2027-04-02",
            "capture": { "id": "b6f53027-0478-4728-9269-8bcc0f8088ea" },
            "created_at": "2026-04-02T09:12:00Z"
        }
    ]
}

Use the ledger when you need a per-movement audit trail for example, when a customer asks where a particular credit came from, or when you want to warn about credits about to expire.

Redeeming rewards on a capture

To spend credits, add a top-level reward_redemption block to either POST /single (when paying in a single step) or POST /capture/{id} (when capturing an earlier authorisation).

Redemption is per reward account: one reward_redemption block targets one account UUID. The redeemed value must not exceed the available balance on that account, nor the value of the payment itself.

Full redemption apply the entire available balance:

{
    "type": "sale",
    "method": "CC",
    "value": 50.0,
    "customer": {
        "id": "649e88cf-0b78-4c36-8f99-33f5ebb812a1"
    },
    "reward_redemption": {
        "account": {
            "id": "458b2fc4-3092-4de3-abd4-fe1600c09420"
        },
        "value": 50.0
    }
}

Partial redemption apply only some of the balance:

{
    "type": "sale",
    "method": "CC",
    "value": 50.0,
    "customer": {
        "id": "649e88cf-0b78-4c36-8f99-33f5ebb812a1"
    },
    "reward_redemption": {
        "account": {
            "id": "458b2fc4-3092-4de3-abd4-fe1600c09420"
        },
        "value": 5.0
    }
}

In both cases the customer is charged value − reward_redemption.value through the chosen payment method. The redeemed amount is debited from the balance immediately and shows up as a REDEMPTION entry on the ledger.

Earning and spending in the same request

A single payment can do both. The reward_redemption block sits at the top of the request and reduces the amount the customer pays; the capture.splits[].reward blocks credit the customer based on the splits. They don't interact you can redeem €10 from a previous balance and earn €5 of fresh credits in the same capture.

The Sale with Splits and Reward Redemption example on POST /single shows the combined shape end-to-end.

Next Steps