> 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/operations/testing/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": "550e8400e29b41d4a716446655440000",
  "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": "2",
      "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 requires 3DS authentication, inspect `actions` for `threeds_redirect_url`.

```json
[
  {
    "rel": "threeds_redirect_url",
    "href": "https://threeds.example.com/v3/...",
    "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 [Payment Processing](/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/operations/testing/test-cards.md)
