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

# Refund reward purchase

> Refunds an `APPROVED` reward purchase made by a program member. The purchase transaction is marked `REFUNDED`, a new `REFUND` reward transaction is created with status `APPROVED`, and the points spent on the purchase are returned to the member's card.

The request body is optional and an empty payload is allowed. Policies default to `refund: DEFAULT` and `stock: DEFAULT`.

The endpoint responds with `202` before the card balance changes. A `POINTS_RETURNED` card transaction is created for the member's card and processed shortly after the response. Returned points receive a new expiration date, resolved from the member's tier or card definition points expiration settings. They do not inherit the expiration of the originally spent points.

For a `LOYALTY_CARD_POINTS` reward, the points credited to the target card are also reversed, with a `POINTS_PURCHASE_REVERSED` card transaction on that card.

Only rewards whose `refunds.type` is `REFUNDABLE` can be refunded. Any other reward is rejected with `423` and key `reward_refund_policy_does_not_allow_refunds`. Send `policies.refund: ALLOW` to force the refund.

The program and the reward transaction must exist within the project, otherwise the request fails with `404`. The request is rejected with `423` when:
- The program is not `ACTIVE` (`non_active_program`) or is outside its validity hours (`program_outside_validity_window`),
- The transaction is not a purchase (`non_purchase_reward_transaction`) or is not `APPROVED` (`non_approved_reward_transaction`); refunding the same purchase twice fails here,
- The reward, its program assignment, the member's card, or the card definition no longer exists,
- For `LOYALTY_CARD_POINTS` rewards, the target card no longer holds the purchased points, or returning the cost would exceed the source card earning limits.



## OpenAPI

````yaml /openapi/loyalties-v2.json post /v2/loyalties/programs/{programId}/rewards/purchases/{rewardTransactionId}/refund
openapi: 3.1.0
info:
  title: Voucherify Loyalty v2 API
  version: 2.0.0
  description: >-
    Complete OpenAPI specification for the Voucherify Loyalty v2 API.

    All endpoints require the LOYALTY_V2 feature flag.


    Combined from per-domain specs: programs.yaml, members.yaml,
    program-operations.yaml, card-definitions.yaml, earning-rules.yaml,
    tier-structures.yaml, benefits.yaml, rewards.yaml, examine.yaml
servers:
  - url: '{protocol}://{host}'
    variables:
      protocol:
        default: https
        enum:
          - https
          - http
      host:
        default: api.voucherify.io
security:
  - X-App-Id: []
    X-App-Token: []
  - bearerAuth: []
tags:
  - name: Programs
    description: >-
      Loyalty program CRUD, lifecycle management, program-scoped resource
      assignments (card definitions, earning rules, rewards, tier structures),
      member management (create, list, get, update, activate, deactivate,
      delete), membership retrieval (member + program + cards with tier
      progress, by customer ID, customer source ID, or member ID), card
      operations (points adjustment, pending points, expiring points,
      transactions), reward purchases, and activity history.
  - name: Card definitions
    description: >-
      CRUD operations, lifecycle management, and activity history for card
      definitions. Card definitions describe the configuration for loyalty
      cards, including code generation, points expiration, earning/spending
      limits, pending points, refunds, and balance settings.
  - name: Earning rules
    description: >-
      Manage earning rules that define how customers earn points or receive
      incentives based on triggers (events, segments, custom events). Includes
      CRUD, lifecycle, and activity history.
  - name: Tier structures
    description: >-
      CRUD operations, lifecycle management, and activity history for tier
      structures. Includes nested tier definitions (create, list, update,
      delete) within tier structures. Tier structures define the tiering model
      for loyalty programs — how members qualify for and move between tiers.
  - name: Benefits
    description: >-
      Manage benefit definitions (fixed points, proportional points, material,
      digital). Includes CRUD, lifecycle transitions, and activity history.
  - name: Rewards
    description: >-
      CRUD, lifecycle operations, and activity history for reward definitions.
      Rewards can be material (product/SKU) or digital (discount coupons, gift
      vouchers).
  - name: Examine
    description: >-
      Evaluation endpoints that estimate earning opportunities and reward
      availability for a customer across their loyalty program memberships,
      without side effects.
paths:
  /v2/loyalties/programs/{programId}/rewards/purchases/{rewardTransactionId}/refund:
    parameters:
      - name: programId
        in: path
        required: true
        description: >-
          Unique loyalty program identifier (format: `lprg_` followed by
          hexadecimal characters).
        schema:
          type: string
          pattern: ^lprg_[a-f0-9]+$
      - name: rewardTransactionId
        in: path
        required: true
        description: >-
          Unique reward transaction identifier of the purchase to refund
          (format: `lrtx_` followed by hexadecimal characters).
        schema:
          type: string
          pattern: ^lrtx_[a-f0-9]+$
    post:
      tags:
        - Programs
      summary: Refund reward purchase
      description: >-
        Refunds an `APPROVED` reward purchase made by a program member. The
        purchase transaction is marked `REFUNDED`, a new `REFUND` reward
        transaction is created with status `APPROVED`, and the points spent on
        the purchase are returned to the member's card.


        The request body is optional and an empty payload is allowed. Policies
        default to `refund: DEFAULT` and `stock: DEFAULT`.


        The endpoint responds with `202` before the card balance changes. A
        `POINTS_RETURNED` card transaction is created for the member's card and
        processed shortly after the response. Returned points receive a new
        expiration date, resolved from the member's tier or card definition
        points expiration settings. They do not inherit the expiration of the
        originally spent points.


        For a `LOYALTY_CARD_POINTS` reward, the points credited to the target
        card are also reversed, with a `POINTS_PURCHASE_REVERSED` card
        transaction on that card.


        Only rewards whose `refunds.type` is `REFUNDABLE` can be refunded. Any
        other reward is rejected with `423` and key
        `reward_refund_policy_does_not_allow_refunds`. Send `policies.refund:
        ALLOW` to force the refund.


        The program and the reward transaction must exist within the project,
        otherwise the request fails with `404`. The request is rejected with
        `423` when:

        - The program is not `ACTIVE` (`non_active_program`) or is outside its
        validity hours (`program_outside_validity_window`),

        - The transaction is not a purchase (`non_purchase_reward_transaction`)
        or is not `APPROVED` (`non_approved_reward_transaction`); refunding the
        same purchase twice fails here,

        - The reward, its program assignment, the member's card, or the card
        definition no longer exists,

        - For `LOYALTY_CARD_POINTS` rewards, the target card no longer holds the
        purchased points, or returning the cost would exceed the source card
        earning limits.
      operationId: refundRewardPurchase
      parameters: []
      requestBody:
        required: false
        description: Optional refund policies. An empty payload is allowed.
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/LoyaltiesProgramsRewardsPurchasesRefundRequestBody
      responses:
        '202':
          description: >-
            Refund accepted. The refund reward transaction has been created with
            status APPROVED and points will be returned to the member's card
            asynchronously.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/LoyaltiesProgramsRewardsPurchasesRefundResponseBody
              examples:
                Refund accepted:
                  value:
                    transaction:
                      id: lrtx_12fa3c01696025a386
                      card_id: lcrd_128f962dbd8c4ba5e1
                      card_transaction_id: lctx_12fa3c0169a025a387
                      program_id: lprg_128f58429f4c4bf7b2
                      member_id: lmbr_128f962dbc8c4ba5dc
                      reward_id: lrew_1294cebb458e4904a0
                      status: APPROVED
                      type: REFUND
                      details:
                        reason: Manual reward refund
                        rejection: null
                        metadata: {}
                        points:
                          total: 500
                        result:
                          reward:
                            id: lrew_1294cebb458e4904a0
                            type: MATERIAL
                          quantity: 1
                          material:
                            type: PRODUCT
                            product:
                              id: prod_1294ce96f66d469498
                          digital: null
                        purchase:
                          card_transaction:
                            id: lctx_12cad1abefa2311e02
                          reward_transaction:
                            id: lrtx_12cad1abefa2311e03
                      created_at: '2026-09-02T12:03:11.401Z'
                      updated_at: null
                      object: reward_transaction
                    status: APPROVED
                    message: >-
                      Reward refund transaction created. Points will be returned
                      to the member's card shortly.
        '400':
          description: >-
            Invalid payload. `policies.refund` or `policies.stock` is not one of
            the allowed values.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Invalid refund policy:
                  value:
                    code: 400
                    key: invalid_payload
                    message: Invalid payload
                    details: >-
                      Property .policies.refund must be equal to one of the
                      allowed values [ DEFAULT, ALLOW ]
                    request_id: v-12fa3c853ac1a815fa
                Invalid stock policy:
                  value:
                    code: 400
                    key: invalid_payload
                    message: Invalid payload
                    details: >-
                      Property .policies.stock must be equal to one of the
                      allowed values [ DEFAULT, WRITE_OFF ]
                    request_id: v-12fa3c853ac1a815fb
        '404':
          description: Program or reward transaction not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Program not found:
                  value:
                    code: 404
                    key: not_found
                    message: Resource not found
                    details: Cannot find program with id lprg_128f5849f4c4bf7b2
                    request_id: v-12fa42985001a82218
                    resource_id: lprg_128f5849f4c4bf7b2
                    resource_type: program
                Transaction not found:
                  value:
                    code: 404
                    key: not_found
                    message: Resource not found
                    details: >-
                      Cannot find reward_transaction with id
                      lrtx_12cadabefa2311e03
                    request_id: v-12fa42b2a281a82254
                    resource_id: lrtx_12cadabefa2311e03
                    resource_type: reward_transaction
        '423':
          description: >-
            Locked. The program is not `ACTIVE` or is outside its validity
            window (`non_active_program`, `program_outside_validity_window`),
            the transaction is not an `APPROVED` `PURCHASE`
            (`non_purchase_reward_transaction`,
            `non_approved_reward_transaction`), or the reward refund policy does
            not allow refunds (`reward_refund_policy_does_not_allow_refunds`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Refund not allowed:
                  value:
                    code: 423
                    key: reward_refund_policy_does_not_allow_refunds
                    message: Cannot refund reward
                    details: >-
                      Reward lrew_1294cebb458e4904a0 refund policy does not
                      allow refunds. To refund reward, set the refund policy to
                      'ALLOW' in the request body
                    request_id: v-12fa3c853ac1a815fa
                Transaction not approved:
                  value:
                    code: 423
                    key: non_approved_reward_transaction
                    message: >-
                      Cannot refund reward when transaction status is not
                      APPROVED
                    details: Invalid reward_transaction status
                    request_id: v-12fa3cdc7fa4066775
        '500':
          description: Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    LoyaltiesProgramsRewardsPurchasesRefundRequestBody:
      type: object
      title: Loyalties Programs Rewards Purchases Refund Request Body
      description: >-
        Request body schema for **POST**
        `/v2/loyalties/programs/{programId}/rewards/purchases/{rewardTransactionId}/refund`.
      properties:
        policies:
          description: Refund policies. When omitted or `null`, defaults are applied.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseRefundPolicies'
            - type: 'null'
      additionalProperties: false
    LoyaltiesProgramsRewardsPurchasesRefundResponseBody:
      type: object
      title: Loyalties Programs Rewards Purchases Refund Response Body
      description: >-
        Response body schema for **POST**
        `/v2/loyalties/programs/{programId}/rewards/purchases/{rewardTransactionId}/refund`.
      properties:
        transaction:
          description: The created REFUND-type reward transaction.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseTransaction'
            - type: 'null'
        status:
          type: string
          enum:
            - APPROVED
          description: Result status. Always `APPROVED` on success.
        message:
          type: string
          description: >-
            Returns the result message: "Reward refund transaction created.
            Points will be returned to the member's card shortly.".
      required:
        - transaction
        - status
        - message
    ErrorResponse:
      type: object
      description: Standard error response returned by all Loyalty v2 endpoints.
      properties:
        code:
          type: integer
          description: HTTP status code of the error.
        key:
          type: string
          description: Machine-readable error key.
        message:
          type: string
          description: Human-readable error message.
        details:
          type: string
          description: Additional details about the error.
        request_id:
          type: string
          description: Unique identifier of the request that produced the error.
        resource_id:
          type: string
          description: Unique identifier of the resource that produced the error.
        resource_type:
          type: string
          description: Type of the resource that produced the error.
    RewardPurchaseRefundPolicies:
      type: object
      description: Refund policies for a reward purchase refund.
      properties:
        refund:
          description: >-
            Applies the refund override. `DEFAULT` follows the reward's refunds
            setting. `ALLOW` refunds even when the reward is not refundable.
            Defaults to `DEFAULT`.
          oneOf:
            - type: string
              enum:
                - DEFAULT
                - ALLOW
            - type: 'null'
        stock:
          description: >-
            Controls assignment stock. `DEFAULT` restores one unit when stock is
            limited. `WRITE_OFF` does not restore stock. Unlimited (`null`)
            stock is unchanged. Defaults to `DEFAULT`.
          oneOf:
            - type: string
              enum:
                - DEFAULT
                - WRITE_OFF
            - type: 'null'
      additionalProperties: false
    RewardPurchaseTransaction:
      type: object
      description: A reward transaction. Represents a reward purchase or a reward refund.
      properties:
        id:
          type: string
          description: >-
            Unique reward transaction identifier (format `lrtx_...`). Absent for
            `DRY_RUN` (SIMULATED) transactions, which are never persisted.
        card_id:
          type: string
          description: >-
            Unique identifier of the loyalty card the points were spent from
            (format `lcrd_...`).
        card_transaction_id:
          type:
            - string
            - 'null'
          description: >-
            Unique identifier of the underlying card transaction (format
            `lctx_...`). `null` for `DRY_RUN` (SIMULATED) transactions.
        program_id:
          type: string
          description: Unique identifier of the loyalty program (format `lprg_...`).
        member_id:
          type: string
          description: Unique identifier of the program member (format `lmbr_...`).
        reward_id:
          type: string
          description: Unique identifier of the purchased reward (format `lrew_...`).
        status:
          type: string
          enum:
            - PENDING
            - PROCESSING
            - APPROVED
            - REJECTED
            - SIMULATED
            - REFUNDED
          description: |-
            Transaction status:

            - `PENDING`: Created and awaiting processing.

            - `PROCESSING`: Being processed.

            - `APPROVED`: Completed successfully.

            - `REJECTED`: Rejected (see `details.rejection`).

            - `SIMULATED`: Dry-run result that is not persisted.

            - `REFUNDED`: Purchase has been refunded.
        type:
          type: string
          enum:
            - PURCHASE
            - REFUND
          description: Transaction type.
        details:
          description: >-
            Transaction details. Shape depends on `type` — purchase details for
            `PURCHASE`, refund details for `REFUND`.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseTransactionDetailsPurchase'
            - $ref: '#/components/schemas/RewardPurchaseTransactionDetailsRefund'
            - type: 'null'
        created_at:
          type: string
          format: date-time
          description: Timestamp when the transaction was created (ISO 8601).
        updated_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            Timestamp when the transaction was last updated (ISO 8601), or
            `null`.
        object:
          type: string
          const: reward_transaction
          description: Object type marker. Always `reward_transaction`.
    RewardPurchaseTransactionDetailsPurchase:
      type: object
      title: Purchase details
      description: Details of a `PURCHASE` reward transaction.
      properties:
        reason:
          type: string
          description: 'Human-readable reason. For purchases: "Points spent on reward".'
        rejection:
          description: >-
            Rejection details, present when the transaction was rejected. `null`
            otherwise.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseRejection'
            - type: 'null'
        metadata:
          type: object
          description: Transaction metadata. Empty object when not set.
          additionalProperties: true
        points:
          description: Points spent on the purchase.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchasePoints'
            - type: 'null'
        result:
          description: >-
            Fulfillment result, populated once the purchase is processed
            (APPROVED). `null` for `PENDING`/`SIMULATED` transactions.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseResult'
            - type: 'null'
      required:
        - reason
        - rejection
        - metadata
        - points
        - result
    RewardPurchaseTransactionDetailsRefund:
      type: object
      title: Refund details
      description: Details of a REFUND reward transaction.
      properties:
        reason:
          type: string
          description: >-
            Sets the refund reason. Always `Manual reward refund` for this
            endpoint.
        rejection:
          description: Rejection details, present when the transaction was rejected.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseRejection'
            - type: 'null'
        metadata:
          type: object
          description: Transaction metadata. Empty object when not set.
          additionalProperties: true
        points:
          description: Points returned by the refund.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchasePoints'
            - type: 'null'
        result:
          description: Refunded reward result (what was reverted).
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseResult'
            - type: 'null'
        purchase:
          description: References to the refunded purchase transactions.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseRefundPurchaseReference'
            - type: 'null'
      required:
        - reason
        - rejection
        - metadata
        - points
        - result
        - purchase
    RewardPurchaseRejection:
      type: object
      description: Details about a rejected reward purchase transaction.
      properties:
        reason:
          type: string
          description: Machine-readable rejection reason.
        details:
          type: object
          description: >-
            Additional structured context about the rejection. Fields depend on
            the rejection reason.
          additionalProperties: true
      required:
        - reason
    RewardPurchasePoints:
      type: object
      description: Points involved in the transaction.
      properties:
        total:
          type: number
          description: Total number of points.
      required:
        - total
    RewardPurchaseResult:
      type: object
      description: >-
        Reward fulfillment result. Contains the fulfilled reward reference,
        quantity and the material or digital fulfillment payload.
      properties:
        reward:
          description: Reference to the fulfilled reward.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseResultReward'
            - type: 'null'
        quantity:
          type:
            - number
            - 'null'
          description: Fulfilled quantity.
        material:
          description: Material reward fulfillment payload. Present for `MATERIAL` rewards.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseResultMaterial'
            - type: 'null'
        digital:
          description: Digital reward fulfillment payload. Present for `DIGITAL` rewards.
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseResultDigital'
            - type: 'null'
    RewardPurchaseRefundPurchaseReference:
      type: object
      description: References to the original purchase transactions being refunded.
      properties:
        card_transaction:
          description: Reference to the original card transaction.
          oneOf:
            - type: object
              properties:
                id:
                  type: string
                  description: Card transaction identifier (format `lctx_...`).
            - type: 'null'
        reward_transaction:
          description: Reference to the original reward transaction.
          oneOf:
            - type: object
              properties:
                id:
                  type: string
                  description: Reward transaction identifier (format `lrtx_...`).
            - type: 'null'
    RewardPurchaseResultReward:
      type: object
      description: Reference to the fulfilled reward.
      properties:
        id:
          type: string
          description: Reward identifier (format `lrew_...`).
        type:
          type: string
          enum:
            - MATERIAL
            - DIGITAL
          description: Reward type.
    RewardPurchaseResultMaterial:
      type: object
      description: Material reward fulfillment.
      properties:
        type:
          type: string
          enum:
            - PRODUCT
            - SKU
          description: Material reward type.
        product:
          type: object
          description: Product payload (present when `type` is `PRODUCT`).
          additionalProperties: true
        sku:
          type: object
          description: SKU payload (present when `type` is `SKU`).
          additionalProperties: true
    RewardPurchaseResultDigital:
      type: object
      description: Digital reward fulfillment.
      properties:
        type:
          type: string
          enum:
            - DISCOUNT_COUPONS
            - GIFT_VOUCHERS
            - LOYALTY_CARD_POINTS
          description: Digital reward type.
        discount_coupons:
          type: array
          description: >-
            Fulfilled discount coupons (present when `type` is
            `DISCOUNT_COUPONS`).
          items:
            $ref: '#/components/schemas/RewardPurchaseDigitalCoupon'
        gift_vouchers:
          type: array
          description: Fulfilled gift vouchers (present when `type` is `GIFT_VOUCHERS`).
          items:
            $ref: '#/components/schemas/RewardPurchaseDigitalGiftVoucher'
        loyalty_card_points:
          description: >-
            Fulfilled loyalty card points (present when `type` is
            `LOYALTY_CARD_POINTS`).
          oneOf:
            - $ref: '#/components/schemas/RewardPurchaseDigitalLoyaltyCardPoints'
            - type: 'null'
    RewardPurchaseDigitalCoupon:
      type: object
      description: Discount coupon fulfillment entry.
      properties:
        id:
          type: string
          description: Voucher identifier of the coupon.
        code:
          type: string
          description: Coupon code.
        result:
          type: string
          enum:
            - SKIPPED
            - DELETED
          description: |-
            Refund handling result for this coupon (present in refund results):

            - `DELETED`: The coupon was deleted.

            - `SKIPPED`: The coupon was left intact.
    RewardPurchaseDigitalGiftVoucher:
      type: object
      description: Gift voucher fulfillment entry.
      properties:
        id:
          type: string
          description: Voucher identifier of the gift voucher.
        code:
          type: string
          description: Gift voucher code.
        amount:
          type: number
          description: >-
            Amount added to (or, for refunds, subtracted from) the gift voucher
            balance.
        balance:
          type: number
          description: Gift voucher balance after the operation.
        result:
          type: string
          enum:
            - SKIPPED
            - CREDITS_SUBTRACTED
          description: >-
            Refund handling result for this gift voucher (present in refund
            results):


            - `CREDITS_SUBTRACTED`: The credited balance was subtracted.


            - `SKIPPED`: The voucher was left intact.
    RewardPurchaseDigitalLoyaltyCardPoints:
      type: object
      description: Loyalty card points fulfillment entry.
      properties:
        points:
          type: number
          description: Number of points credited to the target loyalty card.
        card_definition_id:
          type: string
          description: Target card definition identifier (format `lcdef_...`).
        card_id:
          type: string
          description: Target loyalty card identifier (format `lcrd_...`).
  securitySchemes:
    X-App-Id:
      type: apiKey
      name: X-App-Id
      in: header
    X-App-Token:
      type: apiKey
      name: X-App-Token
      in: header
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````