# Hosted Checkout

import { Aside, Tabs, TabItem } from "@astrojs/starlight/components";
import Image from "@components/content/Image.astro";

Hosted Checkout lets you accept online payments with a payment page hosted by SumUp. Your integration creates a checkout through the SumUp API, receives a `hosted_checkout_url`, and sends the customer to that page to complete the payment.

This is the lowest-effort way to launch an online checkout while keeping payment collection, status pages, and wallet support inside a SumUp-hosted flow.

<Image
  alt="A screenshot of the Hosted Checkout form showing available payment options, including Google Pay, Apple Pay, and card payment"
  src="/img/guides/hosted_checkout_landing_page.png"
  width="80%"
/>

## Prerequisites

- Ability to [create a checkout](/api/checkouts/create) through the SumUp API.
- Authentication via API key or access token. See the [Authorization Guide](/tools/authorization/).
- A server-side integration to create the checkout and keep credentials secret.

## How Hosted Checkout Works

1. Create a checkout and set `hosted_checkout.enabled` to `true`.
2. Store the returned checkout `id` and `hosted_checkout_url`.
3. Redirect the customer to `hosted_checkout_url`, or share that URL in the flow you are building.
4. After the customer completes the payment, verify the final result through the API or with [webhooks](/online-payments/webhooks/).

<Aside type="note">
  A Hosted Checkout session is available for 30 minutes. After that, unpaid sessions show an expired or not found page.
</Aside>

## Create a Hosted Checkout

Send a request to the [Create a checkout endpoint](/api/checkouts/create) with `hosted_checkout.enabled` set to `true`. If you want the success page to link back to your website, include `redirect_url` at the same time.

<Tabs syncKey="backend_lang">
  <TabItem label="cURL" icon="seti:powershell">
    ```bash
    curl -X POST https://api.sumup.com/v0.1/checkouts \
      -H "Content-Type: application/json" \
      -H "Authorization: Bearer $SUMUP_API_KEY" \
      -d '{
        "amount": 12.00,
        "checkout_reference": "b50pr914-6k0e-3091-a592-890010285b3d",
        "currency": "EUR",
        "description": "A sample checkout",
        "merchant_code": "MCXXXXXX",
        "redirect_url": "https://example.com/orders/123/complete",
        "hosted_checkout": { "enabled": true }
      }'
    ```
  </TabItem>
  <TabItem label="Node.js" icon="seti:javascript">
    ```ts
    const checkout = await client.checkouts.create({
      merchant_code: merchantCode,
      amount: 12.0,
      currency: "EUR",
      checkout_reference: "b50pr914-6k0e-3091-a592-890010285b3d",
      description: "A sample checkout",
      redirect_url: "https://example.com/orders/123/complete",
      hosted_checkout: { enabled: true },
    });
    ```
  </TabItem>
  <TabItem label=".NET" icon="seti:c-sharp">
    ```csharp
    var checkout = await client.Checkouts.CreateAsync(new CheckoutCreateRequest
    {
        MerchantCode = merchantCode,
        Amount = 12.0f,
        Currency = Currency.Eur,
        CheckoutReference = "b50pr914-6k0e-3091-a592-890010285b3d",
        Description = "A sample checkout",
        RedirectUrl = "https://example.com/orders/123/complete",
        HostedCheckout = new CheckoutCreateRequestHostedCheckout
        {
            Enabled = true,
        },
    });
    ```
  </TabItem>
  <TabItem label="Java" icon="seti:java">
    ```java
    var checkout = client.checkouts().createCheckout(
        CheckoutCreateRequest.builder()
            .merchantCode(merchantCode)
            .amount(12.0f)
            .currency(Currency.EUR)
            .checkoutReference("b50pr914-6k0e-3091-a592-890010285b3d")
            .description("A sample checkout")
            .redirectUrl("https://example.com/orders/123/complete")
            .hostedCheckout(
                CheckoutCreateRequestHostedCheckout.builder()
                    .enabled(true)
                    .build()
            )
            .build()
    );
    ```
  </TabItem>
  <TabItem label="Go" icon="seti:go">
    ```go
    checkout, err := client.Checkouts.Create(ctx, sumup.CheckoutsCreateParams{
    	MerchantCode:      merchantCode,
    	Amount:            12.0,
    	Currency:          sumup.CurrencyEUR,
    	CheckoutReference: "b50pr914-6k0e-3091-a592-890010285b3d",
    	Description:       "A sample checkout",
    	RedirectURL:       "https://example.com/orders/123/complete",
    	HostedCheckout: &sumup.CheckoutHostedCheckout{
    		Enabled: true,
    	},
    })
    ```
  </TabItem>
  <TabItem label="Python" icon="seti:python">
    ```py
    checkout = client.checkouts.create(
        CreateCheckoutBody(
            merchant_code=merchant_code,
            amount=12.00,
            currency="EUR",
            checkout_reference="b50pr914-6k0e-3091-a592-890010285b3d",
            description="A sample checkout",
            redirect_url="https://example.com/orders/123/complete",
            hosted_checkout={"enabled": True},
        )
    )
    ```
  </TabItem>
  <TabItem label="Rust" icon="seti:rust">
    ```rust
    let checkout = client.checkouts().create(Some(CheckoutCreateRequest {
        merchant_code,
        amount: 12.,
        currency: Currency::EUR,
        checkout_reference: "b50pr914-6k0e-3091-a592-890010285b3d".into(),
        description: Some("A sample checkout".into()),
        redirect_url: Some("https://example.com/orders/123/complete".into()),
        hosted_checkout: Some(CheckoutCreateRequestHostedCheckout {
            enabled: true,
        }),
        return_url: None,
        customer_id: None,
        purpose: None,
        id: None,
        status: None,
        date: None,
        valid_until: None,
        transactions: None,
    })).await?;
    ```
  </TabItem>
  <TabItem label="PHP" icon="seti:php">
    ```php
    $checkout = $sumup->checkouts->create([
        'merchant_code' => $merchantCode,
        'amount' => 12.00,
        'currency' => 'EUR',
        'checkout_reference' => 'b50pr914-6k0e-3091-a592-890010285b3d',
        'description' => 'A sample checkout',
        'redirect_url' => 'https://example.com/orders/123/complete',
        'hosted_checkout' => [
            'enabled' => true,
        ],
    ]);
    ```
  </TabItem>
</Tabs>

The response includes the hosted checkout configuration and the URL you send the customer to:

```json
{
  "amount": 12,
  "checkout_reference": "b50pr914-6k0e-3091-a592-890010285b3d",
  "checkout_type": "checkout",
  "currency": "EUR",
  "date": "2000-01-01T12:49:24.899+00:00",
  "description": "A sample checkout",
  "hosted_checkout": { "enabled": true },
  "hosted_checkout_url": "https://checkout.sumup.com/pay/8f9316a3-cda9-42a9-9771-54d534315676",
  "id": "64553e20-3f0e-49e4-8af3-fd0eca86ce91",
  "merchant_code": "MCXXXXXX",
  "merchant_country": "DE",
  "merchant_name": "Sample Shop",
  "purpose": "CHECKOUT",
  "status": "PENDING",
  "transactions": []
}
```

## Redirect Customers to the Hosted Page

Use the `hosted_checkout_url` returned by the API as the payment page URL in your application.

- Redirect the customer there immediately after checkout creation.
- Or store the URL and present it later in your own flow, for example in an order confirmation page or email.

When the customer opens the Hosted Checkout page, SumUp handles the payment UI and payment confirmation flow.

The business branding shown on Hosted Checkout, such as your business logo and icon, can be configured from the [Branding page](https://me.sumup.com/settings/branding) in SumUp Dashboard. The business name and other customer-facing information can be configured from the [Business profile page](https://me.sumup.com/settings/business-profile/information).

## Configure the Return Flow

If you want the success page to include a button back to your website, set `redirect_url` when you create the checkout, as shown in the examples above.

If `redirect_url` is present, the success page shows a button that sends the customer back to your website.

## Handle Payment Outcomes

Hosted Checkout covers the customer-facing flow from payment page to final status page. Depending on the outcome, customers see different pages:

- Success page after a successful payment.
- Failure page when payment authorization or processing fails.
- Expired page when the checkout session is no longer valid.
- Not found page when the URL does not match an active hosted checkout session.

<Aside type="tip">
  Treat the hosted page as the customer interface, but use the checkout status and webhook events as the source of truth for your backend order state.
</Aside>

### Success

<Image
  alt="A screenshot of the Hosted Checkout payment success page"
  src="/img/guides/hosted checkout_payment_success.png"
  width="50%"
/>

### Failure

<Image
  alt="A screenshot of the Hosted Checkout payment failure page"
  src="/img/guides/hosted checkout_payment_declined.png"
  width="50%"
/>

### Expired Session

<Image
  alt="A screenshot of the Hosted Checkout session expired page"
  src="/img/guides/hosted checkout_session_timed_out.png"
  width="50%"
/>

### Not Found

<Image
  alt="A screenshot of the Hosted Checkout page not found state"
  src="/img/guides/hosted checkout_not_found.png"
  width="50%"
/>