BreathePay
Getting Started

Hosted Payment Pages Integration

A clear, step-by-step guide to integrating the Gateway's Hosted Integration — signing, wallets, 3-D Secure, testing, and more.

A clear, step-by-step guide to integrating the Gateway's Hosted Integration. It is a condensed, developer-friendly companion to the official guide at https://guides.gitbook.io/integrationguide (V4.21). Where this document simplifies something, the official guide remains the source of truth.

In one sentence: you build a set of fields, sign them, and POST them from the customer's browser to the Gateway; the Gateway shows its payment page, takes the payment (card, Apple Pay, Google Pay, etc.), then sends the customer's browser back to your site with the result — and your server never touches card data.


1. Choosing the right integration method

The Gateway offers three integration methods. Choose Hosted unless you have a specific reason not to.

MethodWho collects card dataPCI scopeUse when
HostedThe Gateway (on its Hosted Payment Page)Lowest — your server needs no SSL certificate and the lowest level of PCI DSSYou want the fastest, safest integration and don't want to handle card data.
DirectYou, on your own secure serverHigher — needs SSL + higher PCI DSS, validated annuallyYou need the customer to stay entirely on your own pages.
BatchYou (queued; no customer interaction)HigherBulk/recurring charges. Cannot do 3-D Secure or interactive wallet/checkout pages.

A middle option, Hosted Payment Fields, lets you build your own form while the sensitive inputs stay hosted by the Gateway — same low PCI scope as Hosted, full control of layout. See §14.3.

PCI note (verified): with Hosted Payment Pages, because the card data is entered on the Gateway's page and never reaches your server, your web server does not need an SSL certificate and you qualify for the lowest level of PCI DSS compliance. (You will still serve your own site over HTTPS in practice, and the Gateway endpoint itself is always HTTPS — see §7.) Transaction and card data are retained for approximately 13 months; your acquirer may differ.


2. How much work is this?

For a basic card sale with a developer who already has the credentials: roughly half a day to two days. Most of that time goes on getting the signature right and handling the callback correctly. Using the official server-side SDK (§14.1) removes most of the manual work because it signs requests and verifies responses for you.

Wallets (Apple Pay / Google Pay) add no extra build time if they're boarded on your merchant account — see §12.


3. Prerequisites

You'll be given these during onboarding (production and test sets):

ItemNotes
Merchant Account ID (merchantID)Identifies the merchant account each request is for. Samples in the docs use 100001.
Hosted Integration URLThe endpoint your form POSTs to. Use the exact URL provided — it may be customised to your account. Docs use the dummy form https://gateway.example.com/<integration>. Always HTTPS.
Signing secretSet per merchant account in the Merchant Management System (MMS). Used to sign requests (strongly recommended; may be mandatory).

Replace all dummy values (100001, gateway.example.com) with the real values you were given. Test accounts connect to the Gateway's Simulator, not a real acquirer — see §15.


4. The payment flow

  Your site (browser)              Gateway (HPP)                Your server
  ──────────────────────────────────────────────────────────────────────────
  1. Build + sign fields
  2. POST form  ────────────────▶  3. Show Hosted Payment Page
                                      (card / Apple Pay / Google Pay / APMs)
                                   4. Customer pays; 3-D Secure if needed
                                   5. Gateway processes the payment
     7. Browser returns       ◀───  6a. Redirect (HTTP POST) to redirectURL
        to redirectURL with
        the response fields
                                   6b. (optional) POST a copy to callbackURL ─▶ 8. Verify + fulfil order
  9. Show confirmation page

Two separate things come back after payment:

  • redirectURL — the customer's browser is sent here (HTTP POST). Use it to show a result page.
  • callbackURL — an independent server-to-server copy of the result. Use it to update your systems / fulfil the order.

Why both? The customer can close their browser before the redirect fires, so you may never receive the redirectURL POST. The Gateway explicitly recommends using redirectURL for a confirmation page only, and callbackURL to update your backend. Fulfil from the callback, not the redirect. This is the single most common integration mistake.


5. Step 1 — Build the request

Requests are name/value pairs, URL-encoded as application/x-www-form-urlencoded. For the Hosted Integration the request is sent from the browser (see §7), so it's normally a set of hidden form fields.

5.1 Actions supported by the Hosted Integration

The Hosted Integration only supports the basic payment actions. This is a common point of confusion:

actionSupported on Hosted?What it does
SALEYesAuthorises and (unless delayed) captures a payment.
VERIFYYesChecks the card account exists; no funds moved/held; amount must be 0.
PREAUTHYesSeeks authorisation then immediately voids it to check validity/funds. The docs recommend VERIFY instead where the acquirer supports it.
REFUND, REFUND_SALE, CAPTURE, CANCEL, QUERYNoThese are not supported on Hosted — use the Direct/Batch Integration or the MMS for refunds, captures, cancellations and lookups.

So a normal checkout uses SALE.

5.2 Core fields for a card SALE

FieldRequiredExampleDescription
merchantIDYes100001Your Merchant Account ID.
actionYesSALESee §5.1.
amountYes1099Minor units (1099 = £10.99) or major units with a decimal (10.99). For VERIFY it must be 0.
typeYes11 = E-commerce (ECOM), 2 = MOTO / Card-Not-Present, 9 = Continuous Authority. Online checkout = 1.
currencyCodeYes826ISO-4217 — 3-letter (GBP) or 3-digit (826).
countryCodeYes826ISO-3166-1 — 2/3-letter (GB/GBR) or 3-digit (826).
redirectURLYeshttps://yoursite.com/payment/returnFully-qualified URL the browser returns to. Mandatory for Hosted.
signatureYes¹(computed)Hash of the request + your secret — see §6.
transactionUniqueRecommended(unique id)Your own unique ID for this attempt; aids duplicate detection and anti-spoofing.
orderRefOptionalOrder 1234Free-text reference stored with the transaction.
callbackURLRecommendedhttps://yoursite.com/api/payment/callbackServer endpoint that receives a copy of the result.

¹ A signature may be mandatory on your account; if so, MMS lets you change the secret but not remove it. A merchantPwd field exists but is discouraged on Hosted (it would be visible in the browser) — use signing instead.

Hosted-specific behaviour (verified):

  • You don't send card fields. cardNumber, cardExpiryMonth/Year, cardCVV are collected on the HPP. If you do send a card value it is only used to pre-fill the corresponding HPP input (and you should only do that if you're PCI-compliant to handle it).
  • Don't send deviceIpAddress — the Hosted Integration uses the customer's IP automatically.
  • The Gateway may add new request/response fields at any time. Don't send fields that might clash with future Gateway fields, and ignore any response fields you don't recognise.

5.3 Field formats

TypeFormat
Monetary amountsMinor units (1099) or major units with one decimal (10.99).
Currency codesISO-4217 — GBP or 826.
Country codesISO-3166-1 — GB, GBR, or 826.
Dates / timestampsYYYY-MM-DD / YYYY-MM-DD HH:MM:SS.
Records / arraysfield[sub] notation; arrays use numeric sub-keys from 0 (e.g. items[0][amount]). Booleans as the words true/false.

Field names are case-sensitive and alphanumeric; root names can't start with a digit. There's a practical limit of ~200 request parameters (255 hard limit, leaving room for response fields).


6. Step 2 — Sign the request

When a signing secret is configured, every request must include a signature. The Gateway recomputes the hash and rejects the request if it doesn't match — proving the data wasn't altered in the browser. The Gateway also signs its response, so you can verify what comes back. If signing is enabled, callback data is signed too.

Algorithm (exactly as the Gateway does it):

  1. Take all request fields except signature.
  2. Sort them by field name (ksort — top-level keys only; record sub-fields keep their order).
  3. URL-encode into a query string (PHP http_build_query, & separator).
  4. Normalise all line endings in that string to %0A (replace %0D%0A, %0A%0D, %0A, %0D%0A).
  5. Append your secret and hash with SHA-512.
  6. If you use a non-default algorithm, prefix the hex digest with {ALGO} (e.g. {SHA256}…). For SHA-512, no prefix.

Reference implementation (PHP — canonical, from the guide):

<?php
function createSignature(array $data, string $key, ?string $algo = null): string {
    if ($algo === null) {
        $algo = 'SHA512';
    }
    ksort($data);

    // URL-encode the sorted fields
    $ret = http_build_query($data, '', '&');

    // Normalise all line endings (CRNL|NLCR|NL|CR) to just NL (%0A)
    $ret = preg_replace('/%0D%0A|%0A%0D|%0A|%0D/i', '%0A', $ret);

    // Hash the signature string and the key together
    $ret = hash($algo, $ret . $key);

    // Prefix the algorithm if not the default
    if ($algo !== 'SHA512') {
        $ret = '{' . $algo . '}' . $ret;
    }
    return $ret;
}

Node.js / TypeScript version (for a Next.js backend). The critical requirement is that your query string is byte-for-byte identical to PHP's http_build_query, or the hash won't match:

import crypto from "crypto";

// Mirror PHP http_build_query (RFC 1738): spaces -> '+', and encode the
// reserved characters PHP encodes that encodeURIComponent leaves alone.
function phpRawEncode(s: string): string {
  return encodeURIComponent(s)
    .replace(/%20/g, "+")
    .replace(/[!'()*~]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());
}

function httpBuildQuery(params: Record<string, unknown>): string {
  const parts: string[] = [];
  const add = (key: string, val: unknown) => {
    if (val === null || val === undefined) return;
    if (typeof val === "object") {
      // Records: PHP does NOT sort sub-fields — keep insertion order.
      for (const k of Object.keys(val as object)) {
        add(`${key}[${k}]`, (val as Record<string, unknown>)[k]);
      }
    } else {
      parts.push(`${phpRawEncode(key)}=${phpRawEncode(String(val))}`);
    }
  };
  for (const k of Object.keys(params).sort()) add(k, params[k]); // ksort: top level only
  return parts.join("&");
}

export function createSignature(
  data: Record<string, unknown>,
  key: string,
  algo: "SHA512" | "SHA256" = "SHA512"
): string {
  let str = httpBuildQuery(data).replace(/%0D%0A|%0A%0D|%0A|%0D/gi, "%0A");
  const hash = crypto.createHash(algo.toLowerCase()).update(str + key).digest("hex");
  return algo === "SHA512" ? hash : `{${algo}}${hash}`;
}

Verify the Node version once against a known-good PHP output or the official SDK before trusting it. Subtle differences in +, ~, *, (, ) encoding are the usual cause of "signature mismatch" (Gateway code 65539). For nested fields (e.g. an items[] basket), prefer the official SDK (§14.1), whose encoding is guaranteed to match.


7. Step 3 — Send the customer to the HPP

The request must be sent from the customer's browser, because the response is the HTML payment page. The simplest method is an auto-submitting form of hidden fields — the browser handles the encoding.

<?php
$gatewayUrl   = 'https://YOUR-GATEWAY-HOST/hosted/';   // exact URL from onboarding (HTTPS)
$signatureKey = 'YOUR_SIGNATURE_SECRET';               // from MMS

$fields = [
    'merchantID'        => '100001',
    'action'            => 'SALE',
    'type'              => 1,
    'amount'            => 1099,
    'currencyCode'      => 'GBP',
    'countryCode'       => 'GB',
    'transactionUnique' => bin2hex(random_bytes(16)),
    'orderRef'          => 'Order 1234',
    'redirectURL'       => 'https://yoursite.com/payment/return',
    'callbackURL'       => 'https://yoursite.com/api/payment/callback',
];
$fields['signature'] = createSignature($fields, $signatureKey);
?>
<form id="pay" action="<?= htmlspecialchars($gatewayUrl) ?>" method="post">
  <?php foreach ($fields as $name => $value): ?>
    <input type="hidden" name="<?= htmlspecialchars($name) ?>"
           value="<?= htmlspecialchars($value) ?>">
  <?php endforeach; ?>
  <noscript><button type="submit">Pay now</button></noscript>
</form>
<script>document.getElementById('pay').submit();</script>

Next.js note: build and sign the fields on the server (Route Handler / Server Action) so the signing secret never reaches the client, then return the hidden-field form to the page and auto-submit it. Don't fetch the Gateway URL server-side and proxy the HTML — the customer's browser must load the HPP.

Full page vs lightbox (verified): the plain redirect form above opens the HPP as a new browser page. To show it as a lightbox/modal overlay on top of your site, use the Hosted Payment Page Library (§14.2) or point the form action at a modal URL. The page is styled with your logo and colours in MMS; fully customised full-page or iframe pages can be arranged separately.

HTTPS: the Gateway endpoint is HTTPS only — HTTP is not supported and is not redirected.


8. Step 4 — Read the result (redirectURL)

After payment the Gateway redirects the browser to your redirectURL via HTTP POST, containing the original request fields plus response fields. Use this page only to show the customer a result, and verify the signature first.

<?php
// https://yoursite.com/payment/return
$response = $_POST;

// 1. Verify the signature the Gateway returned (it signs the response too).
$theirSig = $response['signature'] ?? '';
unset($response['signature']);
if (!hash_equals(createSignature($response, $signatureKey), $theirSig)) {
    http_response_code(400);
    exit('Invalid signature — do not trust this response.');
}

// 2. Show the outcome (responseCode 0 == success).
if (($response['responseCode'] ?? null) === '0') {
    echo 'Payment successful. Thank you!';
} else {
    echo 'Payment was not completed: '
       . htmlspecialchars($response['responseMessage'] ?? 'Unknown error');
}

9. Step 5 — Fulfil the order (callbackURL)

If you set callbackURL, the Gateway POSTs a copy of the result directly to it, independent of the browser. This is where you update your database and fulfil the order.

<?php
// https://yoursite.com/api/payment/callback  (no UI; just return 200)
$response = $_POST;

$theirSig = $response['signature'] ?? '';
unset($response['signature']);
if (!hash_equals(createSignature($response, $signatureKey), $theirSig)) {
    http_response_code(400);
    exit;
}

if (($response['responseCode'] ?? null) === '0') {
    // Mark the order paid using $response['transactionUnique'] / $response['orderRef'].
    // IMPORTANT: make this idempotent — a callback may arrive more than once.
}
http_response_code(200);

Both redirectURL and callbackURL must be fully-qualified (scheme + host). Neither is supported by the Batch Integration.


10. Understanding the response & response codes

The response echoes your request fields and adds response fields. The important ones:

FieldMeaning
responseCodeNumeric outcome — use this, not the message, to decide success. 0 = success.
responseStatusOverall processing status of the request.
responseMessageHuman-readable message (e.g. an auth code on success).
stateTransaction state, e.g. received, approved, captured, etc.
xrefThe Gateway's reference for this transaction (used by Direct/Batch follow-ups).
transactionUnique, orderRefEchoed back so you can match to your order.
acquirerResponseCode / acquirerResponseMessageThe raw response from the acquirer (may be non-numeric; ask your acquirer for meanings).

Rule (verified): a zero responseCode always indicates success. Always branch on responseCode, never on the text of responseMessage.

Response code families

  • 0 — success.
  • Authorisation codes (ISO-8583 based, 0–9999) — the acquirer's decision. Examples: 1 Refer to card issuer · 4/5 Decline (keep card / do not honor) · 14 Invalid card number · 51 Insufficient funds · 54 Expired card · 65 SCA required · 82/935 (N7) CVV failure.
  • Gateway codes (65536+) — problems before/around authorisation. Examples: 65539 Invalid credentials (unknown merchantID or signature mismatch) · 65540 Permission denied (IP not allowed) · 65541 Action not allowed · 65542 Request mismatch (changed card details when completing/refunding) · 65546 Currency not supported · 65554 Duplicate request · 65576 Request cancelled (customer hit Cancel on the HPP — see formCancelRequired in §11).
  • Missing / invalid field codes (66048–67071) — a field is missing or invalid. By design, the invalid code is exactly 256 greater than the matching missing code (e.g. missing action = 66055, invalid action = 66311).

For the complete lists, see the official Response and Advice Codes section.


11. Customising the Hosted Payment Page

You can change what the HPP shows and requires by adding optional fields to the same request. All are optional.

Prefill fields (initial values, still editable by the customer): customerName, customerAddress, customerTown, customerCounty, customerPostcode, customerCountryCode, customerEmail, customerPhone, receiverDateOfBirth. You can also prefill card fields, but only send cardNumber if you're PCI-compliant for card storage, and cardCVV only for testing (CVVs must never be stored).

Show / require fields with the matching *Mandatory fields (Y/N): cardCVVMandatory, customerNameMandatory, customerFullNameMandatory (name must be ≥ two words of ≥ two characters), customerAddressMandatory, customerTownMandatory, customerCountyMandatory, customerPostcodeMandatory, customerCountryCodeMandatory, customerEmailMandatory, customerPhoneMandatory, receiverDateOfBirthMandatory. On the standard modal HPP: Y = shown and required; N = shown but optional; omitting it means the field need not be shown. The Gateway may force some fields mandatory if your acquirer requires them.

Page behaviour:

FieldDescription
allowedPaymentMethodsComma-separated list of payment methods to show on the HPP (where supported).
paymentMethodOpen the HPP straight into a specific alternative method without the customer selecting it.
formResponsiveY/N — let the HPP adapt its layout to the display size.
formCancelRequiredShow a Cancel button. Cancelling returns responseCode 65576 (REQUEST CANCELLED).
formRedirectDelaySeconds before redirecting back after completion. -1 to 300; default 5; 0 = immediate; -1 = no automatic redirect.
formAmountEditableLet the customer choose the amount they pay.

Gateway Wallet (stored cards): walletID, cardID, cardToken, customerAddressID, formWalletRequired, formSaveCardRequired (defaults to Y). These let the customer select a previously stored card/address or save a new one. (WalletRequired is a deprecated alias for formSaveCardRequired.)

Not all option fields/features are supported on a fully customised HPP.


12. Apple Pay, Google Pay & other wallets/APMs

What the guide says (verified). The Gateway supports the Apple Pay, Android Pay and Google Pay digital wallets. A wallet produces a secure payment token, which is sent to the Gateway instead of the cardholder's actual card details. Wallets work on any merchant account configured to accept them.

Account-level prerequisites (verified):

  • Digital wallet support is not available with all acquirers and must be enabled on your merchant account before use (your "mass boarding" wallet setup).
  • Contact customer support to confirm acquirer support, enable a wallet, and for details on accepting payment tokens.

There are two ways a wallet payment reaches the Gateway:

12.1 Via the Hosted Payment Page (your setup)

Because the wallets are enabled on your merchant account, the Hosted Payment Page can present the enabled wallet options; you can influence which methods are shown with allowedPaymentMethods, or open a specific one with paymentMethod (see §11). The HPP handles the wallet interaction and the token, and the result returns through your redirectURL / callbackURL exactly like a card payment — so your result handling (§8–§9) is unchanged. This is why wallets are "easier" on Hosted: the token capture and card-data handling stay on the Gateway side.

The precise HPP presentation/handling for each wallet is a "contact support" item in the guide, and a dedicated Hosted Implementation / Digital Wallet Tokens sub-page may cover specifics I haven't been able to read. The flow is verified; confirm any wallet-specific HPP options with support before relying on them.

12.2 Via the Direct Integration with a token (verified mechanics)

If instead you collect the wallet token yourself (e.g. from an Apple Pay / Google Pay button in your own app or page) and process it server-side, you send it through the Direct Integration. In place of the standard card details, send these two fields alongside the basic request fields (merchantID, action, amount, type, currencyCode, countryCode, signature, etc.):

FieldMandatoryValue
paymentMethodYesThe token type: applepay, androidpay, or googlepay.
paymentTokenYesThe secure payment token produced by the wallet-enabled application.

There are no additional response fields — you read the outcome exactly as for any other transaction (§10).

Note: §12.2 is the Direct Integration path (it requires the higher PCI/SSL setup that Direct implies, though you handle a token rather than raw card data). For the Hosted route (§12.1) you don't send these fields yourself — the HPP does.

For test wallets, Apple Pay / Amazon Pay / PayPal sandbox accounts are arranged via customer support (see §15).


13. 3-D Secure / SCA

For the Hosted Integration, 3-D Secure is handled on the Hosted Payment Page — if a transaction needs Strong Customer Authentication (SCA), the HPP runs the 3-D Secure challenge before returning the customer to your redirectURL. You don't implement the 3DS flow yourself (that complexity is the Direct Integration's concern).

What you should know:

  • An SCA-required outcome surfaces as authorisation responseCode 65 (SCA REQUIRED) in the simulator; a fully authenticated card returns 0.
  • You can test specific 3-D Secure authentication outcomes by varying the card expiry month on test cards — see §15.
  • Batch cannot do 3-D Secure at all; that's one reason checkout flows use Hosted (or Direct).

14. The official libraries

Three official libraries remove most of the manual work. Use the server-side SDK for signing/verification; add a client-side library only if you want the lightbox overlay or your own styled form.

14.1 Gateway Integration Library (server-side SDK)

A server-side library (the Gateway class, P3/SDK namespace) available in many languages. It signs requests, builds the form, and verifies responses. Supports Hosted and Direct (not Batch).

Configure once: hostedURL, directURL, merchantID, merchantSecret (enables auto signing + verification), optional merchantPwd, proxyUrl, debug.

Key methods:

  • hostedRequest(request, options) → returns a ready-to-embed HTML <form> fragment that POSTs to the HPP; adds the correct signature automatically if merchantSecret is set. options can set the submit button (text/image/HTML) and extra form attributes (defaults to a "Pay Now" button).
  • verifyResponse(response, secret) → validates and decodes the data POSTed back to your redirectURL/callbackURL; throws if the signature is wrong or responseCode is missing.
  • sign(request, secret) → returns the signature for a request, to sign manually.

Using hostedRequest() + verifyResponse() is the most reliable route because the signature encoding (including nested fields) is guaranteed correct.

14.2 Hosted Payment Page Library (client-side — the lightbox)

A client-side script that shows the HPP in a lightbox/modal overlay over your site instead of a new page, with no other changes to your site. Load it from your Gateway host:

<script src="https://YOUR-GATEWAY-HOST/sdk/web/v1/js/hostedforms.min.js"></script>
  • Works with or without jQuery (adds a $(el).hostedForm(data) plugin if jQuery is present). Exposes window.hostedForms and a Form class.
  • new window.hostedForms.classes.form.Form(element, data) builds or adapts a <form>. The overlay triggers when data.modal is true, the form has data-hostedform-modal, or its action contains/ends with modal.
  • Auto-submit with data.submit.type: 'auto' or a data-hostedform-autosubmit attribute; otherwise it disables the submit button on click to prevent double-submits.
  • The overlay is a semi-opaque full-screen iframe; your cart stays visible but greyed out. On completion the browser is redirected to your redirectURL as normal.

You still build and sign the same fields server-side (§6) and handle the result the same way.

14.3 Hosted Payment Fields Library (client-side — your own form, hosted inputs)

Use this to design your own payment form while the sensitive inputs stay hosted by the Gateway (the PCI benefit of Hosted with full layout control). Load it from your Gateway host; jQuery is required and must load first:

<script src="https://YOUR-GATEWAY-HOST/sdk/web/v1/js/hostedfields.min.js"></script>
  • Provides 6 components: cardNumber, cardCVV, cardExpiryDate, cardStartDate, cardIssueNumber, and cardDetails (number + expiry + CVV in one line). They validate, format, and show the card-type icon.
  • Declare a field three ways (pick one, don't mix):
    <input type="hostedfield:cardNumber" name="card-number">
    <div class="hostedfield" data-hostedfield-type="cardExpiryDate"></div>
    <input data-hostedfield='{"type":"cardCVV"}'>
    
  • With the default autoSetup/autoSubmit, the library validates on submit, produces a paymentToken representing the collected card data, and adds it to your form as a hidden paymentToken input.
  • You then submit that paymentToken to your server and process the payment via the Direct Integration — your server handles the token, never the raw card data.
  • Style fields with your own CSS via a designated stylesheet (selectors must include the hostedfield class / -hostedfield id suffix); rich hostedfield:* events and hf-* state classes are available.

This is a hybrid (hosted fields + Direct Integration), not the standard Hosted redirect. Use it when you need a fully custom-built form but want to stay out of PCI scope.


15. Testing

Test Merchant Accounts connect to the Gateway's Simulator (not a real acquirer), which emulates authorisation and settlement. (All values below are from the guide's Integration Testing page.)

15.1 Test amounts — drive the outcome with the amount

The transaction amount selects the simulated result:

Amount (minor units)Amount (£)AuthorisationSettlement
100 – 24991.00 – 24.99(0) AUTH CODEACCEPTED
2500 – 499925.00 – 49.99(0) AUTH CODEREJECTED
5000 – 749950.00 – 74.99(1) CARD REFERRED → (0) if authorisationCode suppliedACCEPTED
7500 – 999975.00 – 99.99(1) CARD REFERRED → (0) if authorisationCode suppliedREJECTED
10000 – 14999100.00 – 149.99(5) CARD DECLINEDN/A
15000 – 19999150.00 – 199.99(4) CARD DECLINED – KEEP CARDN/A
20000 – 24999200.00 – 249.99(65) SCA REQUIRED → (0) if not SCA-eligibleACCEPTED
25000 – 29999250.00 – 299.99(65) SCA REQUIRED → (5) if not SCA-eligibleN/A

Any other amount returns responseCode 66311 (Invalid Test Amount). Settlement outcome applies only to transactions that are authorised and captured (not cancelled), and uses the captured amount.

Override trick: set the Cardholder Name to Test [N] where N is a pounds value, to force the simulated outcome regardless of the real amount (e.g. name Test [20] with a £10,000 amount → ACCEPTED, because £20 falls in the accepted band).

15.2 Test cards

Test accounts only accept designated test cards (these won't work on production). Use expiry December of the current year (unless simulating 3DS states — see below). A few examples:

SchemeCard numberCVV
Visa Credit4929 4212 3460 0821356
Visa Debit4539 7910 0173 0106289
Mastercard Credit5301 2500 7000 0191419
Mastercard Debit5573 4712 3456 7898159
American Express3742 4545 5400 0014887

(The guide lists more, including Electron, JCB and Diners Club, plus the billing addresses needed to test AVS/CV2. Diners Club doesn't support AVS — test it on a MID with AVS off.)

15.3 3-D Secure (v2) testing

Test accounts use the 3-D Secure PIT system. For the frictionless flow, the card expiry month selects the returned authentication status:

Expiry monthStatusSimulates
01YFully authenticated
02NNot authenticated
03UUnknown
04AAttempted
06RRejected (don't send for auth)
12CChallenge (non-frictionless; choose the outcome on the challenge dialog)

(If the chosen month has already passed this year, use next year's date or the card shows as expired.)

15.4 Wallet / PayPal / Amazon Pay sandboxes

PayPal, Amazon Pay and similar sandbox test accounts are arranged via customer support so you can watch transactions land in your own sandbox.


16. Going live

  • Swap test merchantID, signing key and Gateway URL for the production ones provided.
  • Confirm end-to-end: HPP loads (signature accepted) → a real small payment returns responseCode 0 to redirectURLcallbackURL fires and verifies → wallet buttons appear if boarded.
  • Always POST to HTTPS.
  • On 5xx (network/maintenance) responses, retry a limited number of times with increasing delays; a 503 means scheduled maintenance — retry after the window.

17. Common mistakes

SymptomLikely cause
"Signature mismatch" / 65539Query-string encoding doesn't match PHP http_build_query; the signature field was included in its own hash; fields not sorted; line endings not normalised to %0A; wrong secret.
Orders not fulfilled despite successFulfilling from redirectURL instead of callbackURL; customer closed the browser before redirect.
Duplicate ordersCallback handled non-idempotently (it can fire more than once) — dedupe on transactionUnique.
Refund/capture "not allowed"Those actions aren't supported on Hosted (§5.1) — do them via Direct/Batch or MMS.
HPP never loadsPOSTing from the server instead of the browser; using HTTP; wrong Gateway URL.
Wallets not showingApple/Google Pay not boarded on that account, or restricted by allowedPaymentMethods.
66311 in testingTest amount outside the valid bands (§15.1).

18. Quick reference

Endpoint:  https://YOUR-GATEWAY-HOST/hosted/   (HTTPS, exact URL from onboarding)
Encoding:  application/x-www-form-urlencoded
Method:    POST from the customer's browser
Actions:   Hosted supports SALE, VERIFY, PREAUTH only
Auth:      signature (recommended)  |  merchantPwd (discouraged for Hosted)
Success:   responseCode == 0  (always; never branch on responseMessage text)
Result in: redirectURL (browser → show page)  +  callbackURL (server → fulfil order)
Wallets:   Apple/Android/Google Pay = token model; enable per account (acquirer-dependent).
           Hosted: HPP presents/handles the wallet, result via redirect/callback.
           Direct: send paymentMethod=applepay|androidpay|googlepay + paymentToken
Lightbox:  use the Hosted Payment Page Library (hostedforms.min.js)

19. Glossary

TermMeaning
GatewayThe payment gateway.
MerchantYou, the business using the Gateway.
AcquirerThe bank/financial institution that processes the merchant's card payments.
IssuerThe bank that issued the cardholder's card.
Cardholder / CustomerThe person making the payment.
Merchant AccountA Gateway account mapped to an acquirer-provided account.
HPP — Hosted Payment PageA page on the Gateway's secure server that collects payment details.
HPF — Hosted Payment FieldAn individual Gateway-hosted input for sensitive card data.
APMAlternative Payment Method (e.g. local payment schemes, wallets).
Checkout / WalletThird-party checkout/wallet solutions (e.g. PayPal, Amazon Pay, Masterpass).
xrefThe Gateway's reference for a transaction.

20. Sources & verification notes

Read and used directly (Gateway Integration Guide V4.21 — https://guides.gitbook.io/integrationguide): Introduction & Disclaimer; Terminology; Integration Methods; Integration Details; Authentication; Prerequisites; Supported Actions; Security and Compliance; New Transactions → Request Fields; Hosted Payment Page Options; Pay Buttons (signature code); Gateway Integration Library; Hosted Payment Page Library; Hosted Payment Fields Library; Response and Advice Codes (Response Codes, Gateway Response Codes, General Error Codes, Authorisation Response Codes); Integration Testing; Digital Wallet Transactions (parent + Direct Implementation sub-page).

Stated, not yet verified verbatim:

  • Any Hosted Implementation / Digital Wallet Tokens sub-page for wallets — §12.2 (the Direct token mechanics: paymentMethod = applepay/androidpay/googlepay + paymentToken) is fully verified. What's not verified is the precise way each wallet is presented and its token handled on the Hosted Payment Page (§12.1); the guide defers some of this to customer support. Confirm HPP wallet specifics with support if needed.
  • Sample Signature Calculation page — the algorithm in §6 is the canonical implementation taken from the Pay Buttons example and the SDK's sign() method; the dedicated page would restate it.
  • The full Response/Advice code lists — §10 covers the families and the key codes; the complete tables live in the official Response and Advice Codes section.

This document summarises the Hosted Integration for day-to-day developer use; the official guide remains authoritative for exhaustive field lists, response codes and edge cases.

Copyright © 2026