Hosted payment page

Take a card payment on Datman's hosted form by redirecting the shopper with an encrypted payload.


The Hosted Payment page redirects the shopper to a Datman-hosted form that handles the complete card payment. You don't send an API request yourself, and there's no API key in it. Instead, your server encrypts the payment details and sends the shopper's browser to a Datman URL. Datman takes the payment, sends the shopper back to you, and tells your server the result with a webhook.

This is one of two ways to take online payments. The endpoint reference is Open the hosted payment form (Sale).

Requirements

Before you begin, take into account the following requirements, limitations, and preparations.

RequirementDescription
Integration typeUse this information to build an online payments integration for your merchants.
API credentialsMake sure that you have the following values from Datman:
- Secret key: encrypts the payment details. Keep it on your server only. Never put it in a browser, app or page source.
- Public key (pub_key): tells Datman which secret to decrypt with. It goes in the URL and isn't secret.
WebhooksMake sure that your server can receive the payment status webhook at your webhook_url, and that you have your webhook secret to verify the signature. Keep the webhook secret on your server only.
LimitationsUse HTTPS for redirect_url, cancel_url, webhook_url and back_url.
Setup stepsMake sure that the merchant you take the payment for has a Datman merchant ID (merchant_id) and that online payments are enabled for it.

How it works

For a Hosted Payment page integration, you must integrate the following parts:

  • Your payment server: builds and encrypts the payment details, and builds the URL to the hosted form.
  • Your webhook server: listens for the webhook that includes the outcome of each payment.

Integration steps

To integrate the Hosted Payment page:

  1. Build the payload.
  2. Encrypt it.
  3. Redirect the shopper to the hosted payment page.
  4. Get the payment outcome.

Shopper checkout experience

When the shopper goes to check out:

  1. You redirect the shopper to the Datman-hosted payment form.
  2. The shopper completes the payment on the form.
  3. The shopper is redirected to your redirect_url, or to your cancel_url if they cancel.

Payments integration flow

Your website, your server and the hosted payment page work together to complete the payment flow:

  1. The shopper chooses to check out on your website.
  2. Your server builds the payment details and encrypts them with your secret key.
  3. Your server builds the URL to the hosted form with the encrypted payload as data and your pub_key.
  4. Your website redirects the shopper's browser to that URL.
  5. The shopper completes the payment on the hosted form.
  6. The shopper is redirected to your redirect_url or cancel_url.
  7. Your webhook server receives the payment status webhook with the payment outcome at your webhook_url.

1. Build the payload

Create a JSON object with the payment details. Keys are case-sensitive. Note that amount is in major units, as a string, for example 24.50.

hoststringrequired

Your website's host, without http:// or https://.

merchant_idintegerrequired

The Datman merchant the payment is for.

order_idstring | integerrequired

Your unique order identifier.

customer_idstring | integerrequired

Your identifier for the shopper. Saved cards are linked to it and can be reused for the same shopper later.

emailstringrequired

The shopper's email address.

Format: email

providerstringrequired

The provider value Datman gave you.

phone_numberstringrequired

The shopper's phone number, in international format.

namestring

The merchant's business name.

amountstringrequired

The amount to charge, in major units, as a string.

avs_house_numberstring

House number, for address verification.

avs_postcodestring

Postcode, for address verification.

merchant_referencestring

Your own reference for the payment.

redirect_urlstringrequired

Where the shopper goes after a successful payment. Use HTTPS.

Format: uri

cancel_urlstringrequired

Where the shopper goes if they cancel. Use HTTPS.

Format: uri

webhook_urlstringrequired

Where Datman sends the payment status webhook. Use HTTPS. Treat the webhook, not the redirect, as the final status.

Format: uri

back_urlstringrequired

Where the shopper goes if they choose to go back to your site.

Format: uri

first_namestringrequired

The shopper's first name.

last_namestringrequired

The shopper's last name.

flatstring

Flat or apartment number.

address1string

Address line 1.

address2string

Address line 2.

statement_descriptorstring

Text on the shopper's card statement. Unsupported characters are removed and it's cut to 22 characters.

Max 22 characters

statement_descriptor_addressstring

Second statement line, such as a town. Unsupported characters are removed and it's cut to 20 characters.

Max 20 characters

split_feearray<HostedSplitFee>

Pay part of the amount to other Datman merchants, for example a delivery fee to the delivery partner.

split_fee[].partner_merchant_idstring | integerrequired

The merchant_id that receives this part of the payment.

split_fee[].type_idstring | integerrequired

Commission type: 1 Food/Goods, 2 Marketplace Fee, 3 Delivery Fee, 4 Delivery Tip, 5 Restaurant Tip, 6 Service Charge.

split_fee[].valuestring | numberrequired

The amount, or the percentage when value_type is percentage.

split_fee[].value_typestringrequired

One of: amount, percentage

Example payload (dummy values)
{
  "host": "sandbox.example.com",
  "merchant_id": 63155480,
  "order_id": "987654321",
  "customer_id": "CUST98765",
  "email": "john.doe@example.com",
  "provider": "provider_value",
  "phone_number": "+447911123456",
  "amount": "150.75",
  "redirect_url": "https://example.com/success",
  "cancel_url": "https://example.com/cancel",
  "webhook_url": "https://example.com/webhook",
  "back_url": "https://example.com/back",
  "first_name": "John",
  "last_name": "Doe"
}

2. Encrypt it

Encrypt the payload on your server, because the secret key must never reach the browser. Use AES-256-CBC:

  • Key: your secret key, padded with zero bytes (or cut) to 32 bytes.
  • IV: the first 16 characters of your secret key.
  • Encoding: base64-encode the encrypted bytes, then base64-encode the result again.
Node.js
import crypto from 'node:crypto';

export function encryptPayload(payload, secret) {
  const key = Buffer.concat([Buffer.from(secret), Buffer.alloc(32)], 32); // 32-byte key
  const iv = Buffer.from(secret).subarray(0, 16); // first 16 bytes of the secret
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
  const encrypted = cipher.update(JSON.stringify(payload), 'utf8', 'base64') + cipher.final('base64');
  return Buffer.from(encrypted).toString('base64'); // base64 a second time
}
PHP
function encryptPayload(array $payload, string $secret): string {
    $iv = substr($secret, 0, 16); // first 16 characters of the secret
    // openssl_encrypt pads or cuts the key to 32 bytes, as Datman does
    $encrypted = openssl_encrypt(json_encode($payload), 'AES-256-CBC', $secret, OPENSSL_RAW_DATA, $iv);
    return base64_encode(base64_encode($encrypted)); // base64 twice
}

3. Redirect the shopper to the hosted payment page

Build the URL with the encrypted payload as data and your public key as pub_key, URL-encoding both. Then redirect the shopper's browser to it. The shopper pays on the hosted form.

The Open the hosted payment form (Sale) page in the API Explorer shows the sandbox and production endpoint URLs. Keep the endpoint URL in your configuration.

Node.js (Express)
app.post('/checkout', (req, res) => {
  const data = encryptPayload(buildPayload(req), process.env.DATMAN_SECRET_KEY);
  const url = new URL(process.env.DATMAN_HOSTED_FORM_URL); // endpoint URL from the API Explorer
  url.searchParams.set('data', data);
  url.searchParams.set('pub_key', process.env.DATMAN_PUBLIC_KEY);
  res.redirect(303, url.toString());
});

4. Get the payment outcome

After the hosted form finishes the payment flow, you can show the shopper the current payment status. Datman sends a webhook with the outcome of the payment.

Show the result of the payment

  • After a successful payment, the shopper is sent to your redirect_url.
  • If they cancel, they're sent to your cancel_url.

Don't treat the redirect as the final status, because redirects can be skipped or faked.

Update your order management system

Update your order management system when you get the payment status webhook at your webhook_url. Verify the webhook's signature, then use order_id to match it to your order. Only fulfil the order once the webhook says it's paid.

For a successful payment, the webhook contains status authorisation and success true. For an unsuccessful payment, it contains success false and a reason.

Example webhook for a successful payment

{
  "order_id": "987654321",
  "amount": "150.75",
  "currency": "GBP",
  "customer_id": "CUST98765",
  "xref": "O88213045M63155480T4821937",
  "status": "authorisation",
  "success": "true",
  "date": "2026-10-15 12:34:56+01:00"
}

Test and go live

Build and test against the sandbox endpoint URL. When you are ready to go live:

  1. Switch to the production endpoint URL shown in the API Explorer.
  2. Use your live secret key, public key and webhook secret.
  3. Make sure that redirect_url, cancel_url, webhook_url and back_url use HTTPS.

Troubleshooting

Payment errors

If the request can't be processed, the page shows a message instead of the payment form:

MessageUsual causeWhat to check
Unable to process this request!A required key is missing, or data doesn't decryptThat every required field is present; that you used the right secret for your pub_key, the right IV and both base64 steps; that data is URL-encoded
Online payment not available for this merchant account!Online payments aren't enabled for that merchantContact Datman support

Next steps

On this page

Need help?

Questions about your integration, credentials or going live?

Contact supportRequest a sandbox