# API Integration Guide

import Callout from "@components/content/Callout";

Alternative payment methods (APMs) can require the customer to approve a payment on another page or use payment instructions returned by the API. This guide covers an API-orchestrated integration. For an embedded checkout that presents supported methods for you, use the [Payment Widget](/online-payments/checkouts/card-widget/).

## Prerequisites

- A SumUp merchant account with the required payment methods enabled. Availability varies by merchant, amount, and currency.
- An API key or access token. See the [Authorization Guide](/tools/authorization/).
- A server-side integration that keeps credentials secret.
- An HTTPS page to which the customer can return after an external payment flow.

<Callout type="caution">

Call the SumUp API from your backend. Never expose an API key or access token in browser or mobile application code.

</Callout>

## 1. List available payment methods

Before you show payment options, call [Get available payment methods](/api/checkouts/list-available-payment-methods/) for the merchant. Pass the checkout amount and currency so the result reflects the payment you are about to create. If you include `amount`, you must also include `currency`.

Set `SUMUP_API_KEY` and `SUMUP_MERCHANT_CODE` in your server environment, then run:

```bash
curl --get "https://api.sumup.com/v0.1/merchants/$SUMUP_MERCHANT_CODE/payment-methods" \
  --header "Authorization: Bearer $SUMUP_API_KEY" \
  --data-urlencode "amount=25.00" \
  --data-urlencode "currency=EUR"
```

The response contains method IDs:

```json
{
  "available_payment_methods": [
    {
      "id": "apple_pay"
    },
    {
      "id": "blik"
    }
  ]
}
```

Treat the result as an allowlist, then offer only the methods your integration knows how to handle. Do not maintain an exhaustive list in your application: SumUp can add methods, and availability can change between payments.

## 2. Create a checkout

Use your backend to [create a checkout](/api/checkouts/create/) with a unique `checkout_reference`. Always include `redirect_url` for an APM checkout so the external flow can return the customer to your application.

```json
{
  "checkout_reference": "order-6f918b8d",
  "amount": 25,
  "currency": "EUR",
  "merchant_code": "MH4H92C7",
  "description": "Order 6f918b8d",
  "redirect_url": "https://merchant.example/payments/complete"
}
```

Store the returned checkout `id` with your order. You will need it to process the checkout and verify the result.

## 3. Process the checkout

After the customer selects one of the returned methods, call [Process a checkout](/api/checkouts/process/) with that method's ID as `payment_type`. The required personal details depend on the method and customer market.

For example, an iDEAL request uses the following shape:

```json
{
  "payment_type": "ideal",
  "personal_details": {
    "email": "buyer@example.com",
    "first_name": "Sam",
    "last_name": "Buyer",
    "address": {
      "country": "NL"
    }
  }
}
```

For a Boleto payment on a BRL checkout, the request includes the buyer's Brazilian tax ID and billing address:

```json
{
  "payment_type": "boleto",
  "personal_details": {
    "email": "buyer@example.com",
    "first_name": "Sam",
    "last_name": "Buyer",
    "tax_id": "423.378.593-47",
    "address": {
      "country": "BR",
      "city": "São Paulo",
      "line1": "Rua Gilberto Sabino, 215",
      "state": "SP",
      "postal_code": "05425-020"
    }
  }
}
```

Use the [Process a checkout request schema](/api/checkouts/process/) as the source of truth for supported fields. Do not send placeholder values or collect fields that the selected method does not need.

### Handle redirect instructions

A redirect-based method returns `next_step` instructions when the customer must continue on an external page. For example:

```json
{
  "next_step": {
    "url": "https://payments.example/authorize",
    "method": "POST",
    "redirect_url": "https://merchant.example/payments/complete",
    "mechanism": ["browser"],
    "payload": {
      "token": "opaque-provider-value"
    }
  }
}
```

Follow the response exactly:

1. Read `url`, `method`, `payload`, and the supported `mechanism` values from `next_step`.
2. For `GET`, send the payload as query parameters. For `POST`, submit the payload as form fields.
3. Do not construct the provider URL, rename payload fields, or assume that every method uses the same HTTP method.
4. Let the customer complete the external flow and return to the checkout's `redirect_url`.

The URL and opaque payload can contain sensitive, short-lived data. Avoid logging them or retaining them after the payment flow finishes.

### Handle payment instructions and artifacts

Some methods return payment instructions instead of redirect instructions. For example, Boleto can return a barcode and a URL, while PIX-family methods can return a text code or QR-code image.

Response fields are method-specific. If the response contains an `artefacts` array, use each entry's `content_type` to decide how to present it. Prefer inline `content` when provided; otherwise fetch the exact `location` returned by SumUp. Do not construct artifact URLs or replace their host.

Artifact-based payments are asynchronous. Present the instructions and expiry time to the customer, keep the order pending, and verify the checkout until it reaches a final status.

## 4. Verify the final status

Reaching `redirect_url`, receiving an artifact, or returning from a payment provider does not prove that the payment succeeded. After the customer action, [retrieve the checkout](/api/checkouts/get/) from your backend and use its status as the source of truth:

- `PAID`: complete the order.
- `PENDING`: keep the order pending and check again later.
- `FAILED`: show a failure state and let the customer choose another available method.
- `EXPIRED`: create a new checkout before retrying.

Use [webhooks](/online-payments/webhooks/) to learn that a checkout changed, then retrieve the checkout before fulfilling the order. Make order fulfillment idempotent because browser returns, webhook deliveries, and status checks can occur more than once.

<Callout type="caution">

Never fulfill an order based only on a browser return, frontend callback, or provider page. Fulfill it only after your backend retrieves the checkout and confirms `PAID`.

</Callout>

## Failure and retry handling

- If processing fails because a method is unavailable, list the available methods again and let the customer choose another one.
- If the amount or currency changes, repeat the availability request before processing the checkout.
- After a timeout or unknown response, retrieve the checkout before retrying. A successful request might have completed even if your application did not receive the response.
- Use a new, unique `checkout_reference` only when you intentionally create a new checkout.
- Preserve the order state while the checkout is `PENDING`; redirect and artifact methods might not complete immediately.

## Test checklist

Before going live, verify that your integration:

- Shows only methods returned for the merchant, amount, and currency.
- Supports both `GET` and `POST` redirect instructions without changing the returned payload.
- Returns the customer to the configured `redirect_url`.
- Presents text, image, and document artifacts according to `content_type` when the selected method returns them.
- Keeps `PENDING` orders open and completes them only after the API returns `PAID`.
- Handles `FAILED`, `EXPIRED`, abandoned, and duplicate callback scenarios.
- Does not expose credentials or log redirect payloads and artifact contents.