EventsLocationsSpacesSolutionsPricingIntegrationsAPIBlogHelp
EventsLocationsSpacesSolutionsPricingIntegrationsAPIBlogHelp
© 2026 AOA
Getting startedArtistsFor artistsOrganizersVenuesPast eventsCareersPartnersBubble avatarBento pageGitHub
AboutWhat is AOAPrivacySecurityTermsMerchantCookies
Pricing
UAEN
PricingSupport
FOR PEOPLE
People nearbyHow it worksAOA ConnectSuspended coffee
FOR BUSINESS
VenuesOrganizersFor space ownersFor artists and bands
Solutions
Event check-inEvent networkingTelegram botBento pageLoyalty programSuspended coffeeNFC tags for venues
Extend AOA
IntegrationsAPI & SDK
Help centerDocumentationBlogAbout AOAContact

API reference

  • Introduction
  • Authentication
  • Sandbox
  • Rate limits
  • Errors
  • Versioning
  • Events
  • Reservations
  • Checkout

Webhooks

  • Introduction
  • Event types
  • Verifying signatures
  • Make, Zapier, n8n

API reference

Checkout

POST /checkout creates a ticket payment and returns a payment link: the required Idempotency-Key, order status via GET /orders and common errors.

POST/checkout · scope checkout:write

Creates a payment and returns a payment link. Send the buyer to that link, then watch the order status. After a successful payment we send the ticket to the email address given.

Request

cURL
curl -X POST https://aoa.com.ua/api/v1/checkout \
  -H "Authorization: Bearer aoa_live_…" \
  -H "Idempotency-Key: order-2026-07-30-a1b2c3-0042" \
  -H "Content-Type: application/json" \
  -d '{
    "eventId": "a1b2c3",
    "tickets": [
      { "ticketTypeId": "clx9ticket001", "quantity": 2 }
    ],
    "buyer": {
      "email": "ivan@example.com",
      "name": "Іван Петренко",
      "phone": "+380671234567"
    },
    "reservationId": "rsv_Xk3mQp7vR2nT8wL5yB1zC4dA"
  }'
FieldRequiredDescription
eventIdYesEvent identifier.
ticketsYesItems with ticketTypeId and quantity (1–20 per type).
buyer.emailYesThe ticket goes here. Validate the address on your side.
buyer.nameYesBuyer’s name.
buyer.phoneNoBuyer’s phone number.
couponCodeNoPromo code. A code that doesn’t exist or has expired returns an error, not the full price.
reservationIdNoA reservation from /reservations. Its seats move into the payment.

Idempotency-Key is required

The Idempotency-Key header (at least 8 characters) protects against double charges if the network drops and you don’t know whether the request got through. A repeat request with the same key returns the same response instead of a second payment:

JSON
{
  "data": {
    "paymentId": "d3f1a2b4-7c8e-4f10-9a2b-5c6d7e8f9012",
    "paymentUrl": "https://pay.mbnk.biz/240730a1b2c3"
  },
  "meta": { "idempotent": true }
}

Keys are remembered for 24 hours and kept separate per partner, so your key can’t collide with anyone else’s. Use a value unique to the order, for example the cart identifier in your system.

The key wins over the request body

A repeat with the same Idempotency-Key but a different cart returns the old response, without warning. A new order always needs a new key.

Response

JSON
{
  "data": {
    "paymentId": "d3f1a2b4-7c8e-4f10-9a2b-5c6d7e8f9012",
    "paymentUrl": "https://pay.mbnk.biz/240730a1b2c3"
  }
}

paymentUrl is the payment page to redirect the buyer to. Keep paymentId: you check the status with it.

This request is noticeably slower than the others: we create the invoice with the bank synchronously so we can return a ready link. Set a timeout of at least 15 seconds.

Order status

GET/orders/{paymentId} · scope checkout:write

JSON
{
  "data": {
    "paymentId": "d3f1a2b4-7c8e-4f10-9a2b-5c6d7e8f9012",
    "eventId": "a1b2c3",
    "status": "SUCCESS",
    "amountMinor": 90000,
    "amountDecimal": "900.00",
    "currency": "UAH",
    "attendeeId": "clx9attendee01",
    "failureReason": null,
    "createdAt": "2026-07-30T12:00:00.000Z",
    "paidAt": "2026-07-30T12:02:31.000Z"
  }
}
statusMeaning
PENDINGCreated, the buyer hasn’t paid yet
PROCESSINGThe bank is processing the payment
SUCCESSPaid, the ticket has been sent to the buyer
FAILEDThe payment didn’t go through
EXPIREDThe buyer didn’t pay in time, the seats were released
REFUNDEDThe money was refunded

The attendeeId field is only filled in after a successful payment; until then it’s null.

Poll the status every 5–10 seconds and stop at any status other than PENDING and PROCESSING. Instead of polling, you can subscribe to the webhooks order.paid, order.failed and order.refunded: AOA will tell you the result itself.

You only see your own orders

The API only gives access to payments created with your key. Someone else’s or a non-existent paymentId returns 404.

Common errors

SituationWhat to do
409 “Payments are not configured for this event”The organizer hasn’t connected payments. Mark the event as unavailable for sale: retrying makes no sense.
409 about tickets leftThe seats have been taken. Refresh the numbers and offer a smaller quantity.
400 about a free eventThe event has no paid tickets: people register for it on the website, not through payment.
400 without Idempotency-KeyAdd the header, at least 8 characters long.

The full list of codes is on the Errors page.

PreviousReservationsNextIntroduction