# Create and confirm a payout

Create a payout with complete payment details, review the prepared instruction, and confirm it to start processing.

Product: Payment API
Guides follow API reference 0.1.0 and event reference 0.1.0.
Canonical page: https://docs.axiym.io/payment-api/integration-guide/create-a-payout

Creating a payout validates the instruction, calculates the commercial terms,
and returns the payment in `PENDING_CONFIRMATION`. Review the returned details,
then confirm the payout to reserve funds and start compliance review, approval,
settlement, and execution.

## Before you submit

[Prepare the payment data](/payment-api/integration-guide/prepare-payout-data)
and retrieve the requirements for the selected corridor. Payout creation
validates the submitted data.

The funding account must be active, enabled for payouts, and able to cover
`sourceAmount` when you confirm the payout.

## Complete example

This example uses `POST /payouts` with Axiym field names and codes. For mapped
input, see the [mapped payout API reference](/payment-api/api-reference/payouts/createMappedPayout).

Supply exactly one of `sourceAmount` (fixed debit) or `destinationAmount`
(fixed delivery); Axiym calculates the other. This example fixes the amount the
recipient receives.

Replace the document placeholders with the base64 encoding of complete sandbox
fixtures. See [Supporting documents](/payment-api/integration-guide/prepare-payout-data/supporting-documents)
for encoding instructions; the placeholders are not valid document content.

```json
{
  "sourceAccountId": "5c0a9d3e-1f2b-4a6c-8e7d-9b3f5a1c2d4e",
  "destinationAmount": {
    "amount": "56500.00",
    "currency": "PHP"
  },
  "externalReference": "PAYOUT-2026-001",
  "sourceOfFunds": "BUSINESS_INCOME",
  "purpose": "GOODS_PURCHASE",
  "reference": "INV-2026-0917",
  "supportingDocuments": [
    {
      "documentType": "INVOICE",
      "name": "INV-2026-0917.pdf",
      "data": "REPLACE_WITH_BASE64_ENCODED_INVOICE"
    }
  ],
  "sender": {
    "name": "Acme Pte. Ltd.",
    "countryOfIncorporation": "SG",
    "address": {
      "streetName": "1 Raffles Place",
      "city": "Singapore",
      "postalCode": "048616",
      "country": "SG"
    },
    "contact": {
      "email": "payments@acme.example",
      "phoneNumber": "+6591234567"
    },
    "identification": {
      "type": "REGISTRATION_NUMBER",
      "number": "202612345N",
      "country": "SG",
      "documents": [
        {
          "documentType": "REGISTRY_EXTRACT",
          "name": "acme-registry-extract.pdf",
          "data": "REPLACE_WITH_BASE64_ENCODED_REGISTRY_EXTRACT"
        }
      ]
    },
    "relationships": [
      {
        "role": "UBO",
        "firstName": "Alex",
        "lastName": "Tan",
        "nationalities": ["SG"],
        "address": {
          "streetName": "10 Anson Road",
          "city": "Singapore",
          "postalCode": "079903",
          "country": "SG"
        },
        "identification": {
          "type": "PASSPORT",
          "number": "E1234567A",
          "country": "SG",
          "expiryDate": "2033-01-09"
        }
      }
    ]
  },
  "recipient": {
    "businessRelationship": "SUPPLIER",
    "name": "Manila Software Services Inc.",
    "countryOfIncorporation": "PH",
    "address": {
      "streetName": "6789 Ayala Avenue",
      "city": "Makati",
      "region": "Metro Manila",
      "postalCode": "1226",
      "country": "PH"
    },
    "contact": {
      "email": "accounts@manilasoftware.example",
      "phoneNumber": "+639171234567"
    },
    "destination": {
      "accountNumber": "123456789012",
      "currency": "PHP",
      "bank": {
        "bankName": "Example Bank Philippines",
        "address": { "country": "PH" },
        "swiftBic": "BNORPHMMXXX"
      }
    }
  }
}
```

Omit `sender` when you pay for yourself: the account holder is then the sender
and its onboarded profile is used.

## Create the payout

Generate separate keys once for each new payout and retain them for retries:

```sh
CREATE_IDEMPOTENCY_KEY="$(uuidgen)"
CONFIRM_IDEMPOTENCY_KEY="$(uuidgen)"
```

Save the adapted example as `payout.json`, using your funding account and a
unique `externalReference` for this payout. For a retry, keep the same file,
reference, endpoint, and idempotency key. For another payout, use fresh keys
and a new reference.

```sh
curl --request POST \
  "https://partner-api.sandbox.axiym.io/api/v1/payouts" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --header "X-Request-Id: $(uuidgen)" \
  --header "Idempotency-Key: $CREATE_IDEMPOTENCY_KEY" \
  --data @payout.json
```

The API returns `201 Created` with status `PENDING_CONFIRMATION`.
Store `paymentId` and `externalReference` together. For a mapped payout, also
retain the `paymentDataMapId` sent in the request and the map's `contentHash`.
The payout response does not return the map identifier. Creation returns the
commercial terms but does not reserve funds or start processing.

## Review before confirmation

Verify in the response:

* `sourceAccount` and `externalReference` are correct;
* `sourceAmount`, `fee`, `rate`, `destinationAmount`, and `termsExpireAt` are
  acceptable: `sourceAmount` is the total that will be debited, `fee` is
  included in it, and `destinationAmount = (sourceAmount − fee) × rate`;
* `sender` and `recipient` contain the expected values;
* the controlled values match the intended Axiym codes, including any saved
  translations used by a mapped request;
* the destination bank and account details are correct;
* `reference` is what the recipient should see; and
* every submitted document is listed with its `fileId`, `contentType`, and
  `size`.

The API does not echo base64 document content. Each document is returned as
metadata (`documentType`, `fileId`, `name`, `contentType`, `size`) so you can
verify that the submitted evidence was accepted.

If the prepared details need a material correction, do not confirm the payout.
Create a new payout with the corrected data; confirmation does not accept
replacement payment details.

## Confirm the payout

Set `PAYMENT_ID` to the returned `paymentId`. Both direct and mapped payouts
use the same confirmation endpoint. Send no request body and use the separate
confirmation key generated above:

```sh
curl --request POST \
  "https://partner-api.sandbox.axiym.io/api/v1/payouts/$PAYMENT_ID/confirm" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN" \
  --header "Idempotency-Key: $CONFIRM_IDEMPOTENCY_KEY"
```

A successful confirmation returns `200 OK` with status `PENDING` and
reserves `sourceAmount`. The reservation becomes a debit at settlement or is
released if the payment ends before settlement.

Confirmation is not compliance approval or proof of delivery.
[Track the payout](/payment-api/integration-guide/track-a-payout) through its
subsequent status changes.

## Handle creation failures

* the selected corridor is unavailable or the amount is outside its limits;
* both or neither of `sourceAmount` and `destinationAmount` are supplied;
* direct party data is sent to `POST /payouts` but does not match the Axiym
  schema;
* required baseline party data is missing;
* a corridor-specific bank or identification field is missing or invalid;
* a document required by the corridor is missing, or `data` is not valid base64;
* mapped data is sent to `POST /payouts/mapped` with an unknown or
  incompatible `paymentDataMapId`;
* the map is archived, or a non-canonical controlled value has no saved translation;
* a mapped sender or recipient is incomplete after mapping.

### Resolve mapping errors

An unrecognized label returns `422` with `unmapped_value` at the original
request field. For example:

```json
{
  "code": 422,
  "message": "Invalid Parameters",
  "errors": {
    "payment.instruction.reason": [
      {
        "code": "unmapped_value",
        "message": "No saved translation matches this value.",
        "params": {
          "value": "Goods purchase",
          "targetPath": "purpose",
          "paymentDataMapId": "d2a1c7e4-9b3f-4e6a-8c5d-1f0b2a3c4d5e"
        }
      }
    ]
  }
}
```

If the map contains only `goods purchase`, the differently capitalized label
above does not match. Correct it to an existing saved label or the appropriate
Axiym code. If this is a new label your integration needs, review its translation
and store a new map before using the new identifier.

For mapped fields, the error identifies the source path inside `payment`;
`params.targetPath` identifies the corresponding Axiym field. Nested array
errors identify the affected entry by index.

An archived map returns `422` with `payment_data_map_archived` at
`paymentDataMapId`. Select an active map with the appropriate rules, or store
a new map. Archiving does not change payouts already created with that map.

After correcting the body or changing `paymentDataMapId`, start a new request
with a new `Idempotency-Key`. After a timeout or ambiguous response, retry the
identical endpoint, body, and key instead.

## Handle confirmation failures and retries

Confirmation requires `PENDING_CONFIRMATION` and an active, payout-enabled
funding account with sufficient available balance. Insufficient funds return
`422`, leave the payout awaiting confirmation, and create no reservation.
Resolve the funding shortfall before starting a new confirmation attempt.

If the payout is not confirmed before `termsExpireAt`, it moves to `CANCELED`
with `reasonCode: TERMS_EXPIRED` and can no longer be confirmed. Create a new
payout to obtain new commercial terms.

After a timeout or ambiguous response, retry the same confirmation path with
the same confirmation idempotency key. A successful replay returns the original
result without another reservation. Do not repeat payout creation to recover
an ambiguous confirmation.

See [Confirm a payout](/payment-api/api-reference/payouts/confirmPayout) for the
response contract and [Idempotency](/payment-api/integration-guide/fundamentals/idempotency)
for retry rules.
