Online Payments Quickstart
Create a sandbox Hosted Checkout, complete a test payment, and verify the result through the SumUp API.
Complete your first online payment with Hosted Checkout, SumUp’s hosted payment page. This path requires one server-side API call and no payment UI code.
Expected time: 10–15 minutes after you can access the SumUp Dashboard.
You are finished when the Hosted Checkout shows a successful payment and a server-side Retrieve Checkout request returns PAID.
What runs where
Section titled “What runs where”| Surface | Responsibility |
|---|---|
| Your backend or terminal | Creates the checkout, stores its ID and reference, and verifies the final status. The API key stays here. |
| Customer’s browser | Opens the returned hosted_checkout_url and displays SumUp’s payment form. |
| SumUp | Hosts the payment UI, handles card data and authentication, processes the payment, and records the checkout status. |
Prerequisites
Section titled “Prerequisites”- A SumUp developer account and sandbox merchant account.
- The sandbox merchant’s merchant code, currency, and API key.
- A terminal with
curlandjq. - A browser in which to open the hosted payment page.
Getting a sandbox merchant account
Section titled “Getting a sandbox merchant account”- Log in to the SumUp Dashboard(Opens in a new tab).
- Open Developer Settings(Opens in a new tab).
- Create a sandbox merchant account, then select it in the Dashboard account switcher.
- With the sandbox merchant selected, go to Settings > For Developers > Toolkit > API Keys.
- Create and copy an API key. Do not use the SumUp Public Key.
- Copy the sandbox merchant code and note its account currency.
If you do not have a SumUp account, create a developer account(Opens in a new tab). New developer accounts start with a sandbox merchant account.
Sandbox payments are simulations and do not move real funds.
1. Configure your terminal
Section titled “1. Configure your terminal”Replace the values below with the sandbox credentials you just collected. The checkout currency must match the sandbox merchant account currency.
export SUMUP_API_KEY="sk_test_replace_me"export SUMUP_MERCHANT_CODE="replace_me"export SUMUP_CURRENCY="EUR"Keep the API key on your server or local development machine. Never put it in browser code, a mobile application, source control, screenshots, or support messages.
2. Create a Hosted Checkout
Section titled “2. Create a Hosted Checkout”Set a successful test amount and a unique reference, then create the checkout:
export SUMUP_AMOUNT="12.00"export SUMUP_CHECKOUT_REFERENCE="quickstart-$(date +%s)"
SUMUP_CHECKOUT_RESPONSE="$( curl --fail-with-body --silent --show-error \ --request POST "https://api.sumup.com/v0.1/checkouts" \ --header "Authorization: Bearer $SUMUP_API_KEY" \ --header "Content-Type: application/json" \ --data @- <<JSON{ "checkout_reference": "$SUMUP_CHECKOUT_REFERENCE", "amount": $SUMUP_AMOUNT, "currency": "$SUMUP_CURRENCY", "merchant_code": "$SUMUP_MERCHANT_CODE", "description": "Quickstart order", "hosted_checkout": { "enabled": true }}JSON)"
echo "$SUMUP_CHECKOUT_RESPONSE" | jqThe response should contain these fields:
{ "id": "64553e20-3f0e-49e4-8af3-fd0eca86ce91", "checkout_reference": "quickstart-1785686400", "status": "PENDING", "hosted_checkout": { "enabled": true }, "hosted_checkout_url": "https://checkout.sumup.com/pay/8f9316a3-cda9-42a9-9771-54d534315676"}Store the values needed for the next steps:
export SUMUP_CHECKOUT_ID="$(echo "$SUMUP_CHECKOUT_RESPONSE" | jq -r '.id')"export SUMUP_HOSTED_CHECKOUT_URL="$(echo "$SUMUP_CHECKOUT_RESPONSE" | jq -r '.hosted_checkout_url')"
echo "$SUMUP_HOSTED_CHECKOUT_URL"If either value is empty or null, stop and inspect the API response before continuing.
3. Complete the payment
Section titled “3. Complete the payment”- Copy the printed
SUMUP_HOSTED_CHECKOUT_URLinto your browser. - Enter the following sandbox card details.
- Submit the payment and wait for the Hosted Checkout success page.
| Field | Test value |
|---|---|
| Card number | 4200 0000 0000 0091 |
| Expiry date | Any future date, such as 12/30 |
| CVV | Any three digits, such as 123 |
| Cardholder name | Any name |
The browser result is useful customer feedback, but it is not the state your backend should use to fulfill an order.
4. Verify the payment
Section titled “4. Verify the payment”Retrieve the checkout from your backend or terminal:
SUMUP_VERIFICATION_RESPONSE="$( curl --fail-with-body --silent --show-error \ "https://api.sumup.com/v0.1/checkouts/$SUMUP_CHECKOUT_ID" \ --header "Authorization: Bearer $SUMUP_API_KEY")"
echo "$SUMUP_VERIFICATION_RESPONSE" | jqAfter the successful sandbox payment, the relevant fields look like this:
{ "id": "64553e20-3f0e-49e4-8af3-fd0eca86ce91", "checkout_reference": "quickstart-1785686400", "status": "PAID", "transactions": [ { "status": "SUCCESSFUL", "transaction_code": "TEENSK4W2K" } ]}PAID: mark the order as paid exactly once.PENDING: wait and retrieve the checkout again.FAILED: keep the order unpaid and let the customer start a new attempt.EXPIRED: create a new checkout with a new reference.
Fulfill the order only after your backend retrieves the checkout and confirms PAID. A browser redirect, hosted success page, frontend callback, or webhook delivery is not payment proof on its own.
5. Test a failed payment
Section titled “5. Test a failed payment”Set the deliberate failure amount and a new reference:
export SUMUP_AMOUNT="11.00"export SUMUP_CHECKOUT_REFERENCE="quickstart-failure-$(date +%s)"Repeat steps 2–4 with the same test card. The hosted page should show a failed payment and Retrieve Checkout should return FAILED. Never reuse the successful checkout ID or reference for this attempt.
Troubleshooting
Section titled “Troubleshooting”| Symptom | What to check |
|---|---|
401 Unauthorized |
The value is a sandbox secret API key, and the header uses Bearer. |
403 Forbidden |
The sandbox merchant can accept online payments and the credential can create checkouts. |
409 Conflict |
Generate a new checkout_reference; do not reuse a previous attempt’s reference. |
Missing hosted_checkout_url |
Confirm that hosted_checkout.enabled is true and inspect the complete error response. |
| Hosted page is expired | Hosted Checkout sessions expire after 30 minutes. Create a new checkout and URL. |
Browser says success but the API is PENDING |
Keep the order pending and retrieve the checkout again. |
Move to production
Section titled “Move to production”Before accepting real payments:
- Switch to the live merchant account and create separate production credentials.
- Store
checkout.id,checkout_reference, merchant code, amount, currency, and transaction identifiers with your order. - Add a real HTTPS
redirect_urlfor customer navigation and a webhook for status-change notifications. - Make checkout creation and order fulfillment safe against retries and duplicates.
- Test success, failure, expiry, and abandoned-payment scenarios.
- Process a small live payment and reconcile it in the SumUp Dashboard before launch.
For an embedded payment form, continue with the Payment Widget. For mobile applications or other checkout experiences, compare the checkout integrations.