---
title: "Pay for order with points"
method: POST
path: "/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments"
tags: ["Programs"]
---

# Pay for order with points

`POST /v2/loyalties/programs/{programId}/members/{memberId}/orders/payments`

## Request

- Base URL: `https://api.voucherify.io`
- URL: `https://api.voucherify.io/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments`
- Auth: one of:
  - API key in header `X-App-Id` and API key in header `X-App-Token`
  - HTTP bearer

Pays for an order with points from the member's card. The amount and points come from the card definition's pay-with-points exchange ratio, limited by the order total, the card balance, card spending caps, and the optional `payment_limit`. The binding cap is returned as `details.spending_cap`.

The program and member must be `ACTIVE`, and the program must be inside its validity window. The card must belong to the member. The card definition must have pay-with-points enabled and an exchange-ratio formula. The order must already exist, identified by `id` or `source_id`.

Modes:
- `TRANSACTION` (default): creates a `PENDING` order transaction and a `PENDING` card transaction. Returns `202`. The same order can be paid again; each call creates a new transaction.
- `DRY_RUN`: simulates the payment and doesn't create a transaction. Returns `200` with status `SIMULATED`.

## Request body

- V2LoyaltiesProgramsMembersOrdersPaymentsCreateRequestBody: Fields for paying an order with points.
  - `card_id` string, required: Unique identifier of the member's loyalty card to spend points from (format `lcrd_...`).
  - `order` OrderPaymentOrder, required: Reference to the order being paid. The order must already exist in the Voucherify system. At least one of `id` or `source_id` must be provided.
    - `id` string, nullable: Voucherify order identifier.
    - `source_id` string, nullable: External (source) order identifier.
  - `payment_limit` union: Request body schema for **POST** `/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments`.
    - LoyaltiesProgramsMembersOrdersPaymentsCreateRequestBodyLimitCardBalance: Request body schema for **POST** `/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments`.
      - `type` 'CARD_BALANCE', required: Payment limit type.
    - LoyaltiesProgramsMembersOrdersPaymentsCreateRequestBodyLimitPointsLimit: Request body schema for **POST** `/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments`.
      - `type` 'POINTS_LIMIT', required: Payment limit type.
      - `points_limit` OrderPaymentLimitDefinition, required: Definition of a payment limit value.
        - `max` integer, required: Maximum value of the limit.
    - LoyaltiesProgramsMembersOrdersPaymentsCreateRequestBodyLimitAmountLimit: Request body schema for **POST** `/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments`.
      - `type` 'AMOUNT_LIMIT', required: Payment limit type.
      - `amount_limit` OrderPaymentLimitDefinition, required: Definition of a payment limit value.
        - `max` integer, required: Maximum value of the limit.
  - `mode` 'TRANSACTION' | 'DRY_RUN', nullable: Payment mode. `TRANSACTION` creates a `PENDING` order transaction processed asynchronously (HTTP `202`). `DRY_RUN` only simulates the payment and returns the calculation result (HTTP `200`); no transaction is created. Defaults to `TRANSACTION` when omitted or `null`.

## Response `200`

Dry run result (mode `DRY_RUN`). No transaction was created; the returned transaction has status `SIMULATED` and no `id`.

- V2LoyaltiesProgramsMembersOrdersPaymentsCreateDryRunResponseBody: Result of a pay-with-points dry-run request.
  - `transaction` object, required: An order transaction representing a pay-with-points `SIMULATED` payment.
    - `program_id` string: Unique identifier of the loyalty program (format `lprg_...`).
    - `member_id` string: Unique identifier of the program member (format `lmbr_...`).
    - `card_id` string: Unique identifier of the loyalty card the points were spent from (format `lcrd_...`).
    - `card_definition_id` string: Identifies the card definition (format `lcdef_...`).
    - `card_transaction_id` unknown
    - `order_id` string: Identifies the paid order (format `ord_...`).
    - `status` 'SIMULATED': Transaction status. `SIMULATED` - dry-run create result, not persisted.
    - `type` 'PAY_WITH_POINTS': Defines the transaction type. Always `PAY_WITH_POINTS`.
    - `details` OrderPaymentTransactionDetails: Details of a `PAY_WITH_POINTS` order transaction.
      - `reason` string: Human-readable reason: "Points spent on order payment".
      - `rejection` OrderPaymentRejection: Rejection details for a rejected order payment transaction.
        - `reason` string: Machine-readable rejection reason. Order-side: `ORDER_NOT_FOUND`, `PAYMENT_EXCEEDS_ORDER_TOTAL_AMOUNT`. Card-side (when the linked card transaction fails first): `NOT_ENOUGH_BALANCE`, `GLOBAL_SPENDING_LIMIT_EXCEEDED`, `TRANSACTION_SPENDING_LIMIT_EXCEEDED`.
        - `details` object, nullable: Structured rejection context. Omitted when the reason carries no extra data (`ORDER_NOT_FOUND`, `PAYMENT_EXCEEDS_ORDER_TOTAL_AMOUNT`, `NOT_ENOUGH_BALANCE`). For `GLOBAL_SPENDING_LIMIT_EXCEEDED`: `type`, `limit`, `spendings`. For `TRANSACTION_SPENDING_LIMIT_EXCEEDED`: `type`, `limit`.
          - `type` string: Spending cap type that was exceeded.
          - `limit` number: Configured spending limit.
          - `spendings` number: Projected total spendings that exceeded the limit. Present for `GLOBAL_SPENDING_LIMIT_EXCEEDED`.
      - `metadata` object: Transaction metadata. For pay-with-points transactions this contains the flattened payment limits used for the calculation: `amount_limit` for the `AMOUNT_LIMIT` type and/or `points_limit` for the `POINTS_LIMIT` type. Empty object when the default `CARD_BALANCE` limit was used or when not set.
        - `amount_limit` integer: Maximum amount limit applied to the payment (if any).
        - `points_limit` integer: Maximum points limit applied to the payment (if any).
      - `payment` OrderPaymentPaymentDetails: Payment calculation details.
        - `id` string: Payment identifier. Omitted when not set.
        - `amount` number: Amount of the order paid with points.
        - `points_spent` number: Number of points spent on the payment.
        - `exchange_ratio` number: Points-to-amount exchange ratio evaluated from the card definition's pay-with-points formula.
      - `spending_cap` object: The cap that limited this payment. Create always returns it. Older list rows omit it.
        - `type` 'CARD_SPENDING_GLOBAL_SPENDING_BASED_LIMIT' | 'CARD_SPENDING_GLOBAL_TIME_BASED_LIMIT' | 'CARD_SPENDING_TRANSACTIONS_LIMIT' | 'REQUEST_PAYMENT_LIMIT' | 'ORDER_TOTAL_AMOUNT' | 'CARD_BALANCE_POINTS', required: Identifies which cap limited the payment.
        - `unit` 'POINTS' | 'AMOUNT', required: Whether `value` is points or an amount.
        - `value` number, required: Cap value in `unit`.
    - `updated_at` unknown
    - `object` 'order_transaction': Object type marker. Always `order_transaction`.
  - `status` 'DRY_RUN', required: Result status. `DRY_RUN` for dry-run mode.
  - `message` string, required: Human-readable result message. `DRY_RUN` mode: "Dry run mode. No transaction was created. This is only a simulation.".

## Other responses

- `202`: Payment accepted (mode `TRANSACTION`). A `PENDING` order transaction was created and will be processed asynchronously.
- `400`: The request body failed validation (`invalid_payload`). Pay-with-points is enabled but the card definition has no exchange-ratio formula (`missing_exchange_ratio_formula`).
- `404`: Checked in order. The program doesn't exist (`resource_type` `program`). The member doesn't exist in that program (`member`). The card doesn't exist, or it isn't assigned to this member (`card`, `resource_id` is the card id). The card definition doesn't exist (`card_definition`). The order doesn't exist (`order`). Lookup by `id` says `Cannot find order with id {id}`. Lookup by `source_id` says `Cannot find order with source_id {sourceId}`.
- `423`: The payment is locked. `non_active_program` and `program_outside_validity_window` reject a program that isn't `ACTIVE` or is outside its validity window. `non_active_member` rejects a member that isn't `ACTIVE`. `pay_with_points_not_enabled` means the card definition doesn't allow pay-with-points. `invalid_exchange_ratio` means the formula result isn't a positive number. `zero_card_balance`, `zero_order_total_amount`, `exhausted_card_spending_global_spending_based_limit`, `exhausted_card_spending_global_time_based_limit`, and `exhausted_card_spending_transactions_limit` mean a cap is already zero. `zero_points_to_spent` and `zero_payment_amount` mean the calculation produced nothing to charge.
- `500`: Internal server error.

## Changes

- **2026-10-14** (v2) `d29b33490051`: 1 breaking, 13 warning, 1 info
  - the `allOf[#/components/schemas/MemberOrderPaymentTransactionResult]/transaction/oneOf[#/components/schemas/OrderPaymentTransaction]/` response's property type changed from `object` to no type for status `202`
  - removed the optional property `allOf[#/components/schemas/MemberOrderPaymentTransactionResult]/transaction/oneOf[#/components/schemas/OrderPaymentTransaction]/card_definition_id` from the response with the `202` status
  - removed the optional property `allOf[#/components/schemas/MemberOrderPaymentTransactionResult]/transaction/oneOf[#/components/schemas/OrderPaymentTransaction]/card_id` from the response with the `202` status
  - removed the optional property `allOf[#/components/schemas/MemberOrderPaymentTransactionResult]/transaction/oneOf[#/components/schemas/OrderPaymentTransaction]/card_transaction_id` from the response with the `202` status
  - …11 more
- …earlier changes not shown

[Operation history](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api/changes/v2/loyalties/programs/:programId/members/:memberId/orders/payments/post.md)

---

[API](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api.md) - [All operations](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api/llms.txt) - [OpenAPI document](https://skmtc.dev/voucherifyio/apis/voucherify-loyalty-v2-api/revisions/e0d9f2d2532f?raw)
