# Make your first payout

Discover a corridor, create and review a sandbox payout, then confirm and track it.

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/quickstart

This quickstart simulates a payment funded in USD from an Axiym account, delivering PHP
to a business bank account in the Philippines. The sender can be your
organization or a client you pay for.

## Integration tools

* **[Postman collection](/payment-api/api-reference#downloads)** — Try requests in
  Sandbox. Set `clientId` and `clientSecret`, then send the Auth token request;
  the collection saves the token for subsequent requests.
* **[Integrate using AI](/payment-api/integration-guide/integrate-with-ai)** —
  Documentation formats and an optional integration prompt for your coding agent.

## Prerequisites

* Sandbox OAuth credentials with the `PAYMENT` scope.
* An allowlisted public egress address.
* A funded, active USD Axiym account enabled for payouts.
* An available `USD → PH / PHP` corridor.
* Required recipient and destination test data, sender details when paying
  on behalf of another party, and supporting documents where required.

Axiym provides a funded test account when your sandbox is configured. It must
have sufficient available balance at confirmation. Agree on test recipient
details and the lifecycle scenario with Axiym; sandbox payouts do not move
real funds.

Set `AXIYM_CLIENT_ID` and `AXIYM_CLIENT_SECRET` to your sandbox OAuth credentials
in your shell. Set the sandbox base URL:

```sh
export AXIYM_BASE_URL="https://partner-api.sandbox.axiym.io/api/v1"
```

## 1. Request an access token

```sh
curl --request POST "$AXIYM_BASE_URL/oauth/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "client_id=$AXIYM_CLIENT_ID" \
  --data-urlencode "client_secret=$AXIYM_CLIENT_SECRET" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=PAYMENT"
```

Set `AXIYM_ACCESS_TOKEN` to the returned `access_token` for the following requests.

Before creating a payout, register and test your HTTPS receiver using
[Webhook registration and management](/payment-api/webhooks/registration-and-management).
Verify the test delivery's signature and persist or queue it before returning
`2xx`. Apply the same signature verification and event-ID deduplication to
the payout notifications in this walkthrough.

## 2. Find the funding account

```sh
curl "$AXIYM_BASE_URL/accounts?currency=USD&status=ACTIVE" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Select the USD account provisioned for payouts and set `ACCOUNT_ID` to its
returned `accountId`. An `ACTIVE` status alone does not establish payout
eligibility; confirm payout enablement with Axiym.

## 3. Retrieve corridor requirements

```sh
curl "$AXIYM_BASE_URL/corridors/details?sourceCurrency=USD&destinationCountry=PH&destinationCurrency=PHP" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Confirm `availability` is `AVAILABLE`, the amount is within the returned
limits, and your payout data meets every corridor-specific requirement.

## 4. Create the payout

This quickstart uses Axiym field names and codes with `POST /payouts`.

Generate separate keys once for each new payout:

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

Save the [complete payout example](/payment-api/integration-guide/create-a-payout#complete-example)
as `payout.json` before sending the request. Set `sourceAccountId` to the value
of `ACCOUNT_ID` and supply exactly one of `destinationAmount` or `sourceAmount`.
Choose a unique `externalReference` for this new payout, such as `sandbox-`
followed by the value of `CREATE_IDEMPOTENCY_KEY`. Enter actual values in the
JSON file; curl does not expand shell variables inside it.

Replace the example parties and bank details with your agreed sandbox data.
When paying for yourself, omit `sender`; Axiym uses the account holder's
onboarded profile. Supply `sourceOfFunds`, purpose, and supporting documents where
required by the corridor, including when sender is omitted,
and a reference if needed. Replace every included document placeholder with
the base64 encoding of a complete sandbox fixture, without a data-URL prefix.

Keep the file, external reference, and keys for this attempt. After a timeout
or lost response, retry only the relevant request with its original endpoint,
body, and key. Generate fresh keys and a new external reference for another payout.

```sh
curl --request POST "$AXIYM_BASE_URL/payouts" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $CREATE_IDEMPOTENCY_KEY" \
  --data @payout.json
```

The response is `201 Created` with status `PENDING_CONFIRMATION`.
Store `paymentId` as `PAYMENT_ID`. Creation calculates the commercial terms but
does not reserve funds or start processing.

## 5. Review and confirm

Check the returned commercial terms and prepared payment details, including
the parties, bank details, purpose, reference, and accepted documents. Confirm
before `termsExpireAt` and do not confirm incorrect details.

Send a bodyless confirmation request using the separate key generated above:

```sh
curl --request POST "$AXIYM_BASE_URL/payouts/$PAYMENT_ID/confirm" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN" \
  --header "Idempotency-Key: $CONFIRM_IDEMPOTENCY_KEY"
```

The response is `200 OK` with status `PENDING`. Confirmation reserves
`sourceAmount` and starts processing. Insufficient funds return `422` and
leave the payout awaiting confirmation without a reservation.

Retry an ambiguous confirmation with the same confirmation key; do not create
another payout.

## 6. Track the payout

```sh
curl "$AXIYM_BASE_URL/payouts/$PAYMENT_ID" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Share the `paymentId` with Axiym to coordinate the agreed sandbox status
transitions and notifications. Your integration still creates and confirms
through the API; Axiym controls subsequent simulated progression.

Continue until the payout reaches the agreed terminal outcome. Verify and
de-duplicate the signed notifications received by your configured endpoint,
and use the payout read for authoritative current state.

## 7. Reconcile the account movement

Retrieve the funding account statement:

```sh
curl "$AXIYM_BASE_URL/accounts/$ACCOUNT_ID/statement" \
  --header "Authorization: Bearer $AXIYM_ACCESS_TOKEN"
```

Find entries with `relatedResourceType: PAYOUT` and `relatedResourceId` equal
to `PAYMENT_ID`. For a scenario that reaches settlement, verify the `DEBIT`
entry's `amount` and `currency` match the payout's `sourceAmount`.

When `pageInfo.hasNextPage` is true, send `pageInfo.endCursor` as `after` on
the next request, keeping the account and filters unchanged. Check every page
before concluding that an expected movement is missing.

Creation and confirmation alone do not produce a posted debit. A scenario
ending before settlement should have no settlement debit. For a returned
payout, reconcile any subsequent credits as well. See
[Reconcile payouts](/payment-api/integration-guide/reconcile-payouts).

## Success criteria

* The payout contains the expected `externalReference` and `sourceAccount`.
* The returned `sourceAmount`, `fee`, `rate`, and `destinationAmount` are correct.
* The reviewed prepared payment details match the intended instruction.
* Creation returns `PENDING_CONFIRMATION` without reserving funds.
* Confirmation returns `PENDING` and reserves `sourceAmount`.
* Webhook events are verified and de-duplicated.
* The terminal payout outcome is stored.
* A scenario that reaches settlement has the corresponding account debit;
  scenarios ending before settlement do not.
