> 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/first-payment.md).

# Accepting Your First Payment

Create a first test payment against the current Plexo Payments API contract.

In this guide you will:

* create an HTTP Basic authorization header
* send `POST /v1/payments`
* read the returned payment or error response

**Time to complete:** 10 minutes

**What you need:**

* testing credentials
* a merchant ID enabled for payments
* an HTTP client such as cURL or Postman

{% hint style="info" %}
This guide uses the testing environment at `https://api.testing.plexo.com.uy`. Use placeholder values for sensitive fields in your own tests and source card data from the [Test Cards Reference](/rest-api/reference/test-cards.md).
{% endhint %}

## Before you start

Make sure you have `clientId`, `apiKey`, and `merchantId` for the testing environment. If not, start with [Authentication](/rest-api/getting-started/authentication.md).

## Step 1: Create the authorization header

Plexo uses HTTP Basic authentication.

Header format:

```
Authorization: Basic base64(clientId:apiKey)
```

Example:

```bash
CLIENT_ID="your-client-id"
API_KEY="your-api-key"
AUTH=$(printf '%s:%s' "$CLIENT_ID" "$API_KEY" | base64)
```

Reuse `$AUTH` in the request.

## Step 2: Send the payment request

Create your first payment with:

```
POST /v1/payments
```

The request body is a `PaymentRequestDto`. For a first direct card payment, use this minimal practical shape:

```json
{
  "merchantId": {{MERCHANT_ID}},
  "referenceId": "order-1001",
  "invoiceNumber": "1001",
  "amount": {
    "total": 100.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "source": "card",
    "card": {
      "number": "{{TEST_CARD_NUMBER}}",
      "expMonth": 12,
      "expYear": 2028,
      "cvc": "{{TEST_CARD_CVC}}",
      "cardholder": {
        "firstName": "Test",
        "lastName": "User",
        "email": "test.user@example.com"
      }
    }
  },
  "browserDetails": {
    "ipAddress": "203.0.113.10",
    "userAgent": "Mozilla/5.0"
  },
  "capture": {
    "method": "automatic"
  },
  "callbackUrl": "https://merchant.example.com/callbacks/payments",
  "metadata": {
    "orderId": "order-1001"
  }
}
```

{% hint style="warning" %}
Treat `invoiceNumber` as required for payment creation. The current backend validation rejects requests where it is blank.
{% endhint %}

Key points:

* send `amount` as an object with `total` and `currency`
* use `paymentMethod.source = card`
* include `browserDetails` for browser-based payments
* keep `referenceId` unique per payment attempt

Use the payload above with the current route:

```bash
curl --request POST \
  --url https://api.testing.plexo.com.uy/v1/payments \
  --header "Authorization: Basic $AUTH" \
  --header "Content-Type: application/json" \
  --data '{
    "merchantId": {{MERCHANT_ID}},
    "referenceId": "order-1001",
    "invoiceNumber": "1001",
    "amount": {
      "total": 100.00,
      "currency": "UYU"
    },
    "paymentMethod": {
      "source": "card",
      "card": {
        "number": "{{TEST_CARD_NUMBER}}",
        "expMonth": 12,
        "expYear": 2028,
        "cvc": "{{TEST_CARD_CVC}}",
        "cardholder": {
          "firstName": "Test",
          "lastName": "User",
          "email": "test.user@example.com"
        }
      }
    },
    "browserDetails": {
      "ipAddress": "203.0.113.10",
      "userAgent": "Mozilla/5.0"
    },
    "capture": {
      "method": "automatic"
    }
  }'
```

## Step 3: Read the payment response

On success, the API returns `200 OK` with a `PaymentDto`.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "referenceId": "order-1001",
  "invoiceNumber": "1001",
  "status": "approved",
  "flow": "direct",
  "processingMethod": "api",
  "createdAt": "2026-03-24T12:00:00Z",
  "processedAt": "2026-03-24T12:00:02Z",
  "amount": {
    "total": 100.00,
    "currency": "UYU"
  },
  "paymentMethod": {
    "id": "visa",
    "name": "Visa",
    "type": "card",
    "source": "card"
  },
  "transactions": [
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "referenceId": "order-1001",
      "type": "purchase",
      "status": "approved",
      "processedAt": "2026-03-24T12:00:02Z",
      "resultCode": "APPROVED",
      "resultMessage": "Approved",
      "authorization": "123456"
    }
  ]
}
```

Focus on these fields:

* `id`: Plexo payment identifier
* `status`: overall payment status
* `transactions`: processor result details
* `actions`: next steps if payer interaction is required

If the payment needs a redirect or 3DS step, inspect `actions`.

```json
[
  {
    "rel": "approval_url",
    "href": "https://processor.example.com/approve/...",
    "method": "REDIRECT"
  }
]
```

## Step 4: Handle errors

On client or business-rule failures, the API returns an `ErrorResponse`.

Example validation error:

```json
{
  "type": "invalid-request-error",
  "status": 400,
  "code": "request-validation-errors",
  "message": "One or more request fields are invalid.",
  "traceId": "0HMVG9K3R5T4J:00000001",
  "params": {
    "invoiceNumber": [
      "Invoice number is required."
    ]
  }
}
```

Common status codes:

* `200`: payment created successfully
* `400`: invalid request, merchant, currency, or payment method
* `401`: authentication failed
* `403`: client cannot use the merchant
* `409`: duplicate payment reference
* `422`: processor decline or business-rule rejection

## Step 5: Retrieve the payment again

After a successful response, store the payment `id` and use it to retrieve the payment later.

```bash
curl --request GET \
  --url https://api.testing.plexo.com.uy/v1/payments/{{PAYMENT_ID}} \
  --header "Authorization: Basic $AUTH"
```

This returns the same `PaymentDto` model with the latest status and transaction history.

## What you completed

You now have a working first-payment flow based on the current API models:

* authentication with HTTP Basic credentials
* payment creation with `PaymentRequestDto`
* response handling with `PaymentDto`
* error handling with `ErrorResponse`

## Next Steps

After your first successful payment, the most common next tasks are:

1. Receive asynchronous updates with the [Callbacks Guide](/rest-api/operations/callbacks.md)
2. Save cards securely with the [Tokenization Guide](/rest-api/customers-and-saved-methods/tokenization-guide.md)
3. Add payer authentication with the [3DS Integration Guide](/rest-api/payments/3ds-integration.md)
4. Review broader flows in the [Payment Processing Guide](/rest-api/payments/payment-processing.md)

## Related models and references

* [Authentication](/rest-api/getting-started/authentication.md)
* [PaymentRequestDto](/rest-api/api-reference/models.md#paymentrequestdto)
* [PaymentMethodRequestDto](/rest-api/api-reference/models.md#paymentmethodrequestdto)
* [CardRequestDto](/rest-api/api-reference/models.md#cardrequestdto)
* [PaymentDto](/rest-api/api-reference/models.md#paymentdto)
* [PaymentActions](/rest-api/api-reference/models.md#paymentactions)
* [ErrorResponse](/rest-api/api-reference/models.md#errorresponse)
* [Test Cards Reference](/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/first-payment.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.
