> For the complete documentation index, see [llms.txt](https://plexo.gitbook.io/rest-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://plexo.gitbook.io/rest-api/payments/payment-processing.md).

# Payment Processing Guide

This guide shows the current Payments API contract for creating payments and, when needed, capturing, cancelling, querying, and interpreting payment results.

## Overview

Use the Payments API when you want to:

* create a direct payment with card, token, or wallet data
* authorize now and capture later
* cancel an uncaptured authorization
* query existing payment records
* receive asynchronous status updates through `callbackUrl`
* support browser-based 3DS or redirect flows through the returned `actions`

Use this guide for the payment resource itself. For saved-card setup, merchant configuration, and wallet-specific onboarding, use the domain guides linked at the end of the page.

The main routes are:

* `POST /v1/payments` to create a purchase or authorization
* `POST /v1/payments/{paymentId}/captures` to capture an authorized payment
* `POST /v1/payments/{paymentId}/cancellations` to cancel a purchase or an authorization before capture
* `GET /v1/payments/query` to search existing payments with filters

Use [Verifying a Payment Method](/rest-api/payments/payment-method-verification.md) when you need a verification-only flow.

## Payment Flow Overview

### Purchase

```
Create payment
    ↓
Plexo authorizes and captures funds
    ↓
Payment is returned as approved, pending, or denied
    ↓
Handle async updates through callbackUrl when needed
```

### Authorization (Manual capture)

Use `capture.method = manual` when you want to authorize first and capture later.

```
Create payment
    ↓
Payment is authorized
    ↓
Capture later with `POST /v1/payments/{paymentId}/captures`
    ↓
Captured funds settle through the normal processor flow
```

## Create a Payment

**Endpoint:** `POST /v1/payments`

### Current request shape

```json
{
  "merchantId": 12345,
  "referenceId": "order-123",
  "invoiceNumber": "INV-123",
  "amount": {
    "total": 100.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "source": "card",
    "card": {
      "number": "4111111111111111",
      "expMonth": 12,
      "expYear": 2026,
      "cvc": "123",
      "cardholder": {
        "firstName": "Juan",
        "lastName": "Perez",
        "email": "juan@example.com"
      }
    }
  },
  "browserDetails": {
    "ipAddress": "203.0.113.10",
    "userAgent": "Mozilla/5.0"
  },
  "capture": {
    "method": "automatic"
  },
  "callbackUrl": "https://merchant.example.com/callbacks/payments"
}
```

### Key request fields

| Field                      | Required                      | Description                                                                 |
| -------------------------- | ----------------------------- | --------------------------------------------------------------------------- |
| `merchantId`               | Yes                           | Merchant that receives the payment                                          |
| `referenceId`              | Yes                           | Your unique payment reference                                               |
| `invoiceNumber`            | Yes                           | Your internal invoice reference. Treat it as required for payment creation. |
| `amount.total`             | Yes                           | Decimal payment amount                                                      |
| `amount.currency`          | Yes                           | ISO alpha currency code such as `UYU` or `USD`                              |
| `amount.tip`               | No                            | Tip amount                                                                  |
| `amount.tax`               | Recommended for tax reporting | Optional tax amount for reporting purposes                                  |
| `amount.taxedAmount`       | Recommended for tax reporting | Optional taxed amount for reporting purposes                                |
| `paymentMethod.source`     | Yes                           | Payment source to use                                                       |
| `browserDetails.ipAddress` | Recommended for browser flows | Browser IP used for fraud and 3DS context                                   |
| `browserDetails.userAgent` | Recommended for browser flows | Browser user agent used for fraud and 3DS context                           |
| `capture.method`           | No                            | `automatic` or `manual`                                                     |
| `capture.delay`            | No                            | Optional delayed automatic capture in seconds                               |
| `redirectUrl`              | Conditional                   | Return URL for redirect flows                                               |
| `callbackUrl`              | No                            | Merchant endpoint for asynchronous payment updates                          |
| `metadata`                 | No                            | Custom key-value pairs for your reference                                   |

### Response shape

The API returns a `PaymentDto`. Depending on the flow and processor response, the payment can be returned in states such as `approved`, `authorized`, `pending`, or `denied`.

If the payment requires customer action, such as a redirect or 3DS step, the response can also include an `actions` array with the next step to present to the payer.

## Payment Method Sources

Set `paymentMethod.source` and populate the matching object.

| Source             | Populate                                            | Use case                               |
| ------------------ | --------------------------------------------------- | -------------------------------------- |
| `card`             | `paymentMethod.card`                                | Direct card payments                   |
| `token`            | `paymentMethod.paymentInstrument`                   | Stored cards or recurring use          |
| `network-token`    | `paymentMethod.id` and `paymentMethod.networkToken` | Network tokenized card plus cryptogram |
| `google-pay-token` | `paymentMethod.googlePayToken`                      | Google Pay API integrations            |
| `apple-pay-token`  | `paymentMethod.applePayToken`                       | Apple Pay integrations                 |

### Token payment example

```json
{
  "merchantId": 12345,
  "referenceId": "order-124",
  "invoiceNumber": "INV-124",
  "amount": {
    "total": 100.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "source": "token",
    "paymentInstrument": {
      "token": "tok_1234567890abcdef",
      "cvc": "123"
    }
  },
  "capture": {
    "method": "automatic"
  }
}
```

### Google Pay example

```json
{
  "merchantId": 12345,
  "referenceId": "order-125",
  "invoiceNumber": "INV-125",
  "amount": {
    "total": 100.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "source": "google-pay-token",
    "googlePayToken": {
      "token": "eyJzaWduYXR1cmUiOiJNRVVDSVFEd...",
      "cardholder": {
        "firstName": "John",
        "lastName": "Doe",
        "email": "john@example.com"
      }
    }
  },
  "capture": {
    "method": "automatic"
  }
}
```

### Apple Pay example

```json
{
  "merchantId": 12345,
  "referenceId": "order-126",
  "invoiceNumber": "INV-126",
  "amount": {
    "total": 100.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "source": "apple-pay-token",
    "applePayToken": {
      "token": "{\"data\":\"...\",\"header\":{\"ephemeralPublicKey\":\"...\",\"publicKeyHash\":\"...\",\"transactionId\":\"...\"},\"signature\":\"...\",\"version\":\"EC_v1\"}",
      "cardholder": {
        "firstName": "John",
        "lastName": "Doe",
        "email": "john@example.com"
      }
    }
  },
  "capture": {
    "method": "automatic"
  }
}
```

For wallet-specific setup, see the [Google Pay Integration Guide](/rest-api/wallets/google-pay.md) and the [Apple Pay Integration Guide](/rest-api/wallets/apple-pay.md).

## Authorize Now, Capture Later

Use manual capture when you need to reserve funds first and settle them later.

### Step 1: create an authorized payment

```json
{
  "merchantId": 12345,
  "referenceId": "order-200",
  "invoiceNumber": "INV-200",
  "amount": {
    "total": 250.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "source": "card",
    "card": {
      "number": "4111111111111111",
      "expMonth": 12,
      "expYear": 2026,
      "cvc": "123",
      "cardholder": {
        "firstName": "Maria",
        "lastName": "Gomez"
      }
    }
  },
  "capture": {
    "method": "manual"
  }
}
```

### Step 2: capture the authorized payment

**Endpoint:** `POST /v1/payments/{paymentId}/captures`

Full capture:

```json
{
  "referenceId": "capture-order-200"
}
```

Partial capture:

```json
{
  "referenceId": "capture-order-200-partial",
  "amount": 200.00
}
```

Use partial capture only when the final amount is less than or equal to the authorized amount.

## Cancel an Authorized Payment

Use cancellation when a payment is still in `authorized` status and you want to release the hold instead of capturing it.

**Endpoint:** `POST /v1/payments/{paymentId}/cancellations`

Example request:

```json
{
  "referenceId": "cancel-order-200",
  "reason": "customer-request",
  "description": "Customer cancelled before fulfillment"
}
```

Use cancellation only before capture. If funds were already captured, use `POST /v1/payments/{paymentId}/refunds` instead.

Common public reasons include `card-verification`, `customer-request`, `duplicate-transaction`, `fraud-detected`, `inventory-unavailable`, `order-cancelled`, and `system-error`.

## Search Existing Payments

Use `GET /v1/payments/query` when you need to list or filter payments instead of fetching a single payment by ID.

Example query:

```http
GET /v1/payments/query?referenceId=order-200&status=authorized&size=20
Authorization: Basic {credentials}
```

Common filters include `id`, `referenceId`, `minAmount`, `maxAmount`, `currency`, `minDate`, `maxDate`, `merchantId`, `paymentMethodId`, `status`, `metadataKey`, and `metadataValue`.

This route uses cursor pagination. When the response includes a next cursor, send it back as the `cursor` query parameter to fetch the next page.

## Redirects, 3DS, and Callbacks

* Set `redirectUrl` when you use a redirect payment flow and need the payer returned to your site.
* Include `browserDetails` for browser-based card-not-present payments so processor risk checks and 3DS can use the request context.
* If customer interaction is required, inspect the returned `actions` array and present the next step.
* Set `callbackUrl` when you want Plexo to send asynchronous updates to your system.

For callback handling details, see the [Callbacks Guide](/rest-api/operations/callbacks.md).

## Common Responses and Failures

| Status code | Meaning                                                                              |
| ----------- | ------------------------------------------------------------------------------------ |
| `200`       | Payment created successfully                                                         |
| `400`       | Invalid request, merchant not found, unsupported currency, or invalid payment method |
| `401`       | Authentication required                                                              |
| `403`       | Authenticated client cannot use the merchant                                         |
| `409`       | Duplicate payment or incompatible payment state                                      |
| `422`       | Processor-side decline or validation failure during processing                       |

Examples of client-visible validation errors include:

* `invalid-cardholder` when required cardholder details are missing or invalid
* `payment-not-found` when a later operation targets a payment that is not available to your credentials

For the broader error catalog, see the [Error Codes Reference](/rest-api/reference/error-codes.md).

## Testing

* Use the testing API environment before going live.
* Validate both your success path and your failure handling.
* If you use manual capture, test both full and partial captures.
* If you use browser flows, verify how your integration handles returned `actions` and asynchronous callbacks.

See the [Test Cards Reference](/rest-api/reference/test-cards.md) for the current card matrix.

## Related Resources

* [Accepting Your First Payment](/rest-api/payments/first-payment.md)
* [Verifying a Payment Method](/rest-api/payments/payment-method-verification.md)
* [Recurring Payments Guide](/rest-api/customers-and-saved-methods/recurring-payments.md)
* [Google Pay Integration Guide](/rest-api/wallets/google-pay.md)
* [Apple Pay Integration Guide](/rest-api/wallets/apple-pay.md)
* [Callbacks Guide](/rest-api/operations/callbacks.md)
* [PaymentRequestDto](/rest-api/api-reference/models.md#paymentrequestdto)
* [PaymentDto](/rest-api/api-reference/models.md#paymentdto)
* [PaymentCaptureDto](/rest-api/api-reference/models.md#paymentcapturedto)
* [Payment and Transaction Lifecycle](/rest-api/core-concepts/transaction-lifecycle.md)
* [3DS Integration](/rest-api/payments/3ds-integration.md)
* [Callbacks Guide](/rest-api/operations/callbacks.md)
* [Error Codes Reference](/rest-api/reference/error-codes.md)
* [Test Cards](/rest-api/reference/test-cards.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://plexo.gitbook.io/rest-api/payments/payment-processing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
