Hosted payment page quickstart

This guide walks you through generating a Hosted payment page (HPP) link, redirecting your customer to it, and handling the payment result. By the end, you'll have a working end-to-end HPP integration.

The HPP handles all card input, 3DS authentication, and payment processing on Centrobill's side. Card data never touches your servers.

Before you begin

Make sure you have the following:

  • A Centrobill merchant account. Contact [email protected] to request access.
  • Your API key (the Authorization header value), available in the Merchant Portal.
  • A site ID or SKU name (product identifier): created in the Merchant Portal or via the Site API and SKU API respectively. You need only one of these to initiate a payment.

Note: All examples in this guide use the Stage environment at https://stage.api.centrobill.com. Replace with https://api.centrobill.com when you're ready to go live.


How the flow works

  1. Your server sends a POST /paymentPage request to the Gateway API with the SKU, consumer, and URL details
  2. The gateway returns a unique one-time payment page URL
  3. You redirect the customer's browser to that URL
  4. The customer enters payment details on the Centrobill-hosted page
  5. If required, the customer completes 3DS authentication with their bank
  6. Centrobill sends the final payment status to your ipnUrl via IPN callback and redirects the customer to your redirectUrl

Step 1: Generate the payment page URL

Send a POST request to /paymentPage from your server. This call requires your API key in the Authorization header.

curl --request POST \
  --url https://stage.api.centrobill.com/paymentPage \
  --header 'Authorization: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "sku": [
      {
        "title": "Premium Monthly",
        "siteId": "983759353",
        "price": [
          {
            "offset": "0d",
            "amount": 29.99,
            "currency": "USD",
            "repeat": false
          }
        ],
        "url": {
          "ipnUrl": "https://your-server.example.com/webhooks/centrobill",
          "redirectUrl": "https://your-server.example.com/payment/success"
        }
      }
    ],
    "consumer": {
      "id": "user-00123",
      "email": "[email protected]",
      "firstName": "Jonny",
      "lastName": "Sonny"
    },
    "payment": {
      "method": ["card", "sepa"],
      "selected": "card",
      "secure": true
    },
    "ttl": 1200,
    "metadata": {
      "orderId": "ord_9182"
    },
    "emailOptions": {
      "send": true
    }
  }'

Request fields

sku (required)

The sku field is an array. Each SKU object can be defined in one of three ways:

ApproachRequired fieldsWhen to use
SKU with SKU namename, urlYou have a pre-configured SKU in the Merchant Portal
SKU with SKU name and custom pricesname, price, urlYou want to override a SKU's prices at runtime
SKU with site IDsiteId, price, urlYou don't have a named SKU and want to define everything inline

Each SKU object also accepts:

FieldDescription
url.ipnUrlYour IPN endpoint. Centrobill posts the final payment status here
url.redirectUrlThe URL the customer is redirected to after payment
titleDisplay title shown on the payment page
domainNameDomain name override for the site
xsellCross-sell display state: checked or unchecked
action.typeRetry type for retrying a transaction with the same order ID after an SCA decline
action.idOrder ID to retry

consumer (optional)

Pre-fill customer data on the payment page. consumer.ip is required if payment.selected or payment.method are set.

FieldDescription
idCentrobill gateway consumer ID
externalIdYour internal user ID
emailCustomer email
firstName / lastNameCustomer name
country, state, city, address, zipBilling address
phoneCustomer phone number
birthdayDate of birth
ipCustomer IP address. Required if payment.method or payment.selected are set
deviceIdDevice fingerprint

payment (optional)

Controls which payment methods are shown and how the page behaves.

FieldDescription
methodArray of payment methods to display (e.g. ["card", "sepa"])
selectedPayment method pre-selected when the page loads
secureIf true, the gateway attempts 3DS verification. Defaults to true
testIf true, processes in test mode
terminalModeDisables consumer tracking, one-clicks, and antifraud checks
midSpecific MID to route the payment through
binBIN used for pre-routing decisions
domainCustom domain displayed in the link instead of the default

template (optional)

Customises the appearance of the payment page.

FieldDescription
languageISO2 language code (e.g. "DE"). Determined automatically if omitted
layoutPage layout (theme). Falls back to the default theme if omitted
templateParametersKey–value pairs passed to the layout

Other fields

FieldDescription
ttlPayment page lifetime in seconds. Defaults to 600
metadataArbitrary key–value pairs attached to the transaction. Returned in the IPN
emailOptions.sendIf true, Centrobill sends a payment confirmation email to the customer

Step 2: Handle the response

A successful request returns HTTP 201 with a single url field:

{
  "url": "https://pay.centrobill.com/unique-hash"
}

This is the unique, one-time payment page URL. It expires after the ttl you specified (default 600 seconds). If the customer doesn't complete payment before it expires, you'll need to generate a new URL.


Step 3: Redirect the customer

Redirect the customer's browser to the URL returned in Step 2. You can do this with a standard HTTP redirect from your server.

// Server-side redirect example (Node.js / Express)
res.redirect(paymentPageUrl);

The customer lands on the Centrobill-hosted payment page, enters their payment details, and, if required, completes a 3DS challenge with their bank. Non-EU transactions and frictionless EU transactions are completed without a 3DS challenge.


Step 4: Handle the IPN callback

After the payment completes, Centrobill sends an HTTP POST to your ipnUrl with the final payment status. Don't rely on the customer returning to your redirectUrl as confirmation — always use the IPN as the source of truth.

{
  "payment": {
    "code": "0",
    "description": "APPROVED",
    "action": "charge",
    "mode": "sale",
    "status": "success",
    "amount": 29.99,
    "currency": "USD",
    "orderId": "235324530",
    "transactionId": "12345",
    "descriptor": "centrohelp.com",
    "source": {
      "method": "card",
      "number": "402400****6348",
      "brand": "visa",
      "paymentAccountId": "ae853c41-2d85-4c8a-9a61-3a5daeea311d"
    }
  },
  "consumer": {
    "id": "cb-gateway-id",
    "externalId": "user-00123",
    "email": "[email protected]",
    "firstName": "Jonny",
    "lastName": "Sonny"
  },
  "subscription": {
    "id": "sub-abc123",
    "status": "active",
    "renewalDate": "2025-02-17 13:43:02",
    "cancelDate": null,
    "cycle": 0
  },
  "metadata": {
    "orderId": "ord_9182"
  },
  "timestamp": {
    "dateTime": "2025-01-17 13:43:02",
    "timezone": "UTC+00.00",
    "unixTime": "1737116582"
  }
}

Respond with HTTP 200, 201, or 202 to acknowledge receipt. Respond as quickly as possible — do any heavy processing asynchronously after acknowledging. If Centrobill doesn't receive an acknowledgement, it retries the IPN according to the documented retry schedule.

Check payment.status to determine the outcome:

payment.statusMeaningNext action
successPayment approvedProvision access, save transactionId and paymentAccountId
pendingAwaiting async confirmationWait for a follow-up IPN callback
failPayment declinedDo not provision access

Save the following values from the IPN — you'll need them if you want to charge the customer again without the HPP using stored data:

  • payment.source.paymentAccountId — the stored card identifier
  • consumer.id — the Centrobill gateway consumer ID

Step 5: Handle the customer redirect

After payment, Centrobill redirects the customer to your redirectUrl. Use this to show a confirmation or error page. Do not use the redirect as confirmation of payment — rely on the IPN instead, as the customer may close the browser before the redirect completes.


Before you go live

Before switching to the Production environment, complete the following steps:

  1. Test your integration in the Staging environment. Use synthetic payment credentials to simulate approvals, declines, and 3DS flows.
  2. Confirm account activation with the Merchant Support team. Your profile must be activated before production payments are processed. Contact [email protected] to confirm.
  3. Switch the base URL from https://stage.api.centrobill.com to https://api.centrobill.com in all requests.

Troubleshooting

400 Bad Request A required field is missing or invalid. The sku array is required. Each SKU object must include either name or siteId, and a url object with at least ipnUrl and redirectUrl.

401 Unauthorized Your API key is missing or incorrect. Verify the Authorization header matches your key exactly as it appears in the Merchant Portal.

403 Forbidden Your account doesn't have permission for this operation, or the request IP isn't on the allowlist. Contact Centrobill support.

Payment page URL expired HPP URLs are short-lived. If the customer tries to use an expired link, generate a new URL and redirect them again. Increase ttl in your request, if customers regularly fail to complete payment within the default 600 seconds.

Customer returned to redirectUrl but IPN hasn't arrived The IPN is delivered asynchronously and may arrive slightly after the redirect. Don't provision access immediately on redirect, wait for the IPN with payment.status = "success" before fulfilling the order.

payment.status is pending Some flows, particularly 3DS, resolve asynchronously. Wait for the follow-up IPN callback before fulfilling the order.