> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ecomm365.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Hosted Payment Page Quickstart

> Create a Sandbox payment, redirect the customer, and confirm the final Payment status

Hosted Payment Page (HPP) is the shortest integration path. Flowlix renders
the card form; your server creates a Payment, redirects the customer's browser,
and retrieves the Payment for the authoritative result.

## When to use HPP

Choose HPP when raw card numbers and CVC values must not enter your checkout or
backend. Your merchant server does not send card data in an HPP request.
Your server still owns order fulfilment, idempotency, and final-status handling.

HPP supports card payments. Apple Pay and Google Pay are not available on HPP.
Do not send `payment_method_data` or a selected method in the HPP create request.

Use the [Direct API](/guides/direct-api) for wallet integrations. Apple Pay and
Google Pay are Experimental: their support and this guidance are still being
refined and are not final.

## Prerequisites

Complete the shared setup in [Authentication](/guides/authentication).

## 1. Create a Payment

```bash theme={null}
curl -X POST "$FLOWLIX_BASE_URL/v1/payments/hpp" \
  -H "Authorization: Bearer $FLOWLIX_API_KEY" \
  -H "Idempotency-Key: order-2345678901-hpp-1" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 2500,
    "currency": "EUR",
    "merchant_reference": 2345678901,
    "customer_ip_address": "203.0.113.7",
    "merchant_customer_id": "cust_opaque_42",
    "return_url": "https://shop.example/checkout/complete"
  }'
```

| Field | Requirement |
| - | - |
| `amount` | Positive integer in the currency's minor units. |
| `currency` | A [supported payment currency](/introduction#amounts-and-currencies) for a new Payment. Other well-formed codes return `422 currency_not_supported` with `param: currency`; no Payment is created. |
| `customer_ip_address` | The shopper's literal IPv4 or IPv6 address, without a hostname, port, or proxy chain. |
| `merchant_customer_id` | Your stable opaque, non-PII identifier for this logical customer or recognized guest. |
| `return_url` | Your absolute HTTPS page URL with a valid hostname or IP address for the browser return. It is not a payment-result callback. |
| `merchant_reference` | Optional 10-digit integer for reconciliation; it does not deduplicate requests. |

Reuse the exact `merchant_customer_id` for the same customer. Never use an
email, phone, login, name, order/payment/attempt ID, or fresh per-payment UUID.
Case and whitespace are significant; the value must be nonblank, contain
1–255 Unicode scalar values, and contain no U+0000.

Use an HTTPS `return_url`. A parsed URI using HTTP, `javascript:`, or another
scheme, or without a valid host, returns `400 parameter_invalid` with
`param: return_url` before a Payment is created. Malformed URI text returns
`400 request_body_invalid`. Host validation checks URL syntax; your domain
does not need to be on a Flowlix allowlist, and no DNS lookup is performed.
Integrations that previously sent HTTP or custom-scheme return URLs must
switch to HTTPS.

You can supply optional `billing_details` when creating the Payment.
These details are forwarded for the payment; shoppers cannot edit them on
the hosted card-entry page. The editable cardholder-name field is separate
from the billing profile. The
[API reference](/payments-api/payments/create-a-hosted-payment-page-payment)
contains the complete request schema.

## 2. Store the response and redirect

A create returns `201 Created` with the current Payment state. Store its `id`
before taking further action. The initial state is one of:

| Status | What to do now |
| - | - |
| `PENDING` | Do not redirect or resubmit. Retrieve this Payment for its latest recorded state. |
| `REQUIRES_ACTION` | Redirect the browser to the returned `next_action.redirect_url`. |
| `FAILED` | Do not redirect. Read `failure_code`; a new customer attempt creates a new Payment. |

For example, a Payment ready for the hosted browser flow is:

```json theme={null}
{
  "id": "pay_q7Mk2Np8Vr4Xt6Yz9Ab3Cd5E",
  "amount": 2500,
  "currency": "EUR",
  "status": "REQUIRES_ACTION",
  "integration_type": "HOSTED_PAYMENT_PAGE",
  "payment_method": null,
  "next_action": {
    "type": "redirect",
    "reason": "hosted_payment_page",
    "redirect_url": "https://hosted-payment.example/redirect-token"
  },
  "amount_refunded": 0,
  "amount_refundable": 0,
  "livemode": false,
  "created_at": 1719792000
}
```

Redirect only when the response has `status: REQUIRES_ACTION`, and use the
exact opaque `next_action.redirect_url`. Flowlix collects the card details on
the hosted page. 3D Secure may be presented during that hosted flow when
required by the payment provider. A `PENDING` or `FAILED` response has no
immediate shopper redirect.

`payment_method: null` means the shopper's actual method is unknown, not card.
Read any later masked card details from `payment_method.card`, as explained in
[Payment method and card details](/guides/payment-lifecycle#payment-method-and-card-details).

For Sandbox card entry and the amounts that select each outcome, see
[Sandbox testing](/guides/testing#choose-the-outcome-with-the-amount).

While the Payment is `REQUIRES_ACTION`, retrieve it periodically. If its latest
`next_action.redirect_url` changes, send the browser to the new URL. Do not
repeatedly redirect the same browser to an unchanged URL.

## 3. Handle the browser return

Flowlix sends the customer to `return_url` after the hosted browser flow.

<Warning>
  Reaching `return_url` does not confirm payment. Never fulfil an order from a
  query parameter or browser state. Retrieve the Payment from your server.
</Warning>

## 4. Confirm the final status

```bash theme={null}
export PAYMENT_ID="pay_q7Mk2Np8Vr4Xt6Yz9Ab3Cd5E"

curl "$FLOWLIX_BASE_URL/v1/payments/$PAYMENT_ID" \
  -H "Authorization: Bearer $FLOWLIX_API_KEY"
```

Repeat the retrieval while the Payment is `PENDING`, `REQUIRES_ACTION`, or
`PROCESSING`. Stop when it reaches:

| Status | Action |
| - | - |
| `SUCCEEDED` | Fulfil the order and retain the Payment ID for reconciliation. |
| `FAILED` | Read `failure_code`; offer a new Payment attempt when appropriate. |
| `EXPIRED` | Create a new Payment if the customer restarts checkout. |

For polling intervals and every status, see
[Payment lifecycle](/guides/payment-lifecycle).

The optional `payment_method.card` block may be omitted or null even after a
successful HPP payment. Confirm the result from `status`; do not wait for card
details before fulfilment. See
[optional card details](/guides/payment-lifecycle#optional-card-details).

## Safe retries

Flowlix retries eligible hosted-order creation failures in a bounded burst.
An uncertain creation is not treated like a safe failure before direct-payment
execution: an executable hosted page may already exist. A returned `PENDING`
Payment stays unresolved; retrieve it rather than creating a replacement.
If an earlier creation attempt was uncertain, a later provider rejection does
not prove that no hosted order exists. Flowlix preserves that uncertainty rather
than turning it into a failed Payment solely from the later rejection.

If the create request times out or returns a transient HTTP error, retry with
the same `Idempotency-Key` and an equivalent effective request identity. A
changed business attempt uses a new key. See [Idempotency](/guides/idempotency).

## Next steps

* [Create a Refund](/guides/refunds) after a test Payment succeeds.
* [Submit and retrieve a Payout](/guides/payouts).
* [Receive Payment and Refund events](/guides/webhooks).
* Add complete [API error handling](/guides/errors).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.