> For the complete documentation index, see [llms.txt](https://paytiko.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://paytiko.gitbook.io/docs/solutions/hosted-page.md).

# Hosted Page

[![Run In Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/16521666-e641ab7e-370c-4006-be1d-075aea644f1d?action=collection%2Ffork\&source=rip_markdown\&collection-url=entityId%3D16521666-e641ab7e-370c-4006-be1d-075aea644f1d%26entityType%3Dcollection%26workspaceId%3D88104d01-75d4-48c1-b1ee-ecff38c2902f)

<mark style="color:green;">`POST`</mark> `{CORE_URL_ISSUED_BY_PAYTIKO}/api/payment/hosted-page`

#### Headers

<table><thead><tr><th>Name</th><th width="127">Type</th><th>Description</th></tr></thead><tbody><tr><td>Content-Type<mark style="color:red;">*</mark></td><td>String</td><td>application/json</td></tr><tr><td>X-Merchant-Secret<mark style="color:red;">*</mark></td><td>String</td><td><code>{MERCHANT_SECRET_KEY_ISSUED_BY_PAYTIKO}</code></td></tr></tbody></table>

#### Request Body

<table><thead><tr><th width="270">Name</th><th width="119">Type</th><th>Description</th></tr></thead><tbody><tr><td>timestamp<mark style="color:red;">*</mark></td><td>String</td><td>Unix Epoch timestamp.</td></tr><tr><td>signature<mark style="color:red;">*</mark></td><td>String</td><td><p>$rawSignature = `<code>${billingDetails.email};${timestamp};${MERCHANT_SECRET_KEY_ISSUED_BY_PAYTIKO}`</code></p><p></p><p>$signature = SHA256($rawSignature)</p></td></tr><tr><td>webhookUrl</td><td>String</td><td>Webhook notification URL.</td></tr><tr><td>successRedirectUrl</td><td>String</td><td>URL where client will be redirectied when payment is successful.</td></tr><tr><td>failedRedirectUrl</td><td>String</td><td>URL where client will be redirectied when payment is failed.</td></tr><tr><td>billingDetails.lockedAmount</td><td>Numeric</td><td>Locked amount value. If not provided - amount can be changed by client.</td></tr><tr><td>billingDetails.firstName<mark style="color:red;">*</mark></td><td>String</td><td>First Name (or full name if last name cannot be provided).</td></tr><tr><td>billingDetails.lastName</td><td>String</td><td>Last Name.</td></tr><tr><td>billingDetails.email<mark style="color:red;">*</mark></td><td>String</td><td>Unique client e-mail.</td></tr><tr><td>billingDetails.street</td><td>String</td><td>Street.</td></tr><tr><td>billingDetails.region</td><td>String</td><td>Region.</td></tr><tr><td>billingDetails.city</td><td>String</td><td>City.</td></tr><tr><td>billingDetails.country<mark style="color:red;">*</mark></td><td>String</td><td>2-chars country code. (ISO 3166-1 alpha-2).</td></tr><tr><td>billingDetails.zipCode</td><td>String</td><td>ZIP / Postal Code.</td></tr><tr><td>billingDetails.phone<mark style="color:red;">*</mark></td><td>String</td><td>Phone number.</td></tr><tr><td>billingDetails.dateOfBirth</td><td>String</td><td><p>Date of birth.</p><p>Format: <code>YYYY-MM-dd</code></p></td></tr><tr><td>billingDetails.gender</td><td>String</td><td>[ 'Male', 'Female' ]</td></tr><tr><td>billingDetails.currency<mark style="color:red;">*</mark></td><td>String</td><td>3-chars currency code (ISO 4217).</td></tr><tr><td>orderId<mark style="color:red;">*</mark></td><td>String</td><td>Your internal unique order identifier. Used to identify your order and update it on webhooks.</td></tr><tr><td>disabledPspIds</td><td>Array</td><td>Ids of APM payment processors which should be disabled in the cashier. Ex: [12321, 54455, 34212]</td></tr><tr><td>creditCardOnly</td><td>Boolean</td><td>This parameter is used to show only credit card processors in the payment widget.</td></tr><tr><td>cashierDescription</td><td>String</td><td>Text shown in the cashier as an order description. (Max length is 1024 characters)</td></tr><tr><td>isPayOut</td><td>Boolean</td><td>Activates cashier in payout mode.</td></tr></tbody></table>

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "redirectUrl": "https://{CASHIER_HOST}?sessionToken=hp-b8fc5a8f-ce0b-49ab-a027-a1d05cc5c7a3&m_orderId=7f00853a-03de-4605-bb3f-f16ab9510fe1"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
    "errors": {
        "MerchantId": [
            "Property is required. Path 'billingDetails.email', line 1, position 1."
        ]
    },
    "title": "One or more validation errors occurred.",
    "status": 400
}
```

{% endtab %}
{% endtabs %}

### **Additional query parameters**

You can supply additional query parameters to adjust your widget visualization.

{% hint style="info" %}
**The complete redirect URL looks as the follows:**

https\://{CASHIER\_HOST}?sessionToken=hp-b8fc5a8f-ce0b-49ab-a027-a1d05cc5c7a3\&m\_orderId=7f00853a-03de-4605-bb3f-f16ab9510fe1<mark style="color:purple;">**\&m\_fixed\_pp\_id=14854**</mark>
{% endhint %}

Full list of query parameters presented below:

| Query Parameter | Type      | Description                                                                                               |
| --------------- | --------- | --------------------------------------------------------------------------------------------------------- |
| `m_fixed_pp_id` | `numeric` | Fixed payment processor identifier. Only this processor will be shown within the current cashier session. |

{% hint style="warning" %}
"Phone", "City", "Street", "Region" & "ZipCode" fields are not required on our side, but Credit Card solutions have them as mandatory. Leaving these parameters empty can cause errors on PSP side and deposits will be failed.
{% endhint %}

**Request body example**

{% code fullWidth="false" %}

```json
{
    "timestamp": "1669923838",
    "orderId": '3aa1e912-6ff3-4925-82dc-66bd7927676c',
    "signature": "gJTYTtv4MO6TNDBfBETz/V2hiXoDgVe5vKKenLITj18=",
    "webhookUrl": "http://your-api-url.com/webkook",
    "successRedirectUrl": "https://your-site-url.com/success",
    "failedRedirectUrl": "https://your-site-url.com/failed",
    "billingDetails": 
    {
        "firstName": "TestName",
        "lastName": "TestLastName",
        "email": "test1234@gmail.com",
        "street": "Khreshatyk street",
        "region": "Kyiv",
        "city": "Kyiv",
        "phone": "+380982013541",
        "zipCode": "01001",
        "country": "UA",
        "dateOfBirth": "1990-03-15",
        "currency": "USD"
    }
}
```

{% endcode %}

### Webhook Control

To receive order status updates from us, you need to expose an open API endpoint (HTTP POST) and share with us this endpoint URL.\
We resend this webhook to your server with exponential interval until your response status code won't be `200`.<br>

**Webhook request body sample**

{% code fullWidth="true" %}

```javascript
{
    "Action": "TRANSACTION_DATA_UPDATE",
    "ActionId": "34d3e8a5-c9ad-4553-a940-00e8bc025720", // Webhook corellation action ID.
    "OrganizationId": 12, // Organization identifier.
    "OrderId": "3aa1e912-6ff3-4925-82dc-66bd7927676c", // Merchant Order ID.
    "MerchantOrderId": "3aa1e912-6ff3-4925-82dc-66bd7927676c", // Merchant order ID (duplicate/external reference).
    "AccountId": "c6aad9e8-4fe6-4895-b82c-cc1ea66b4aad", // Account Unique Identitier.
    "AccountDetails": { // Payer Account Details.
        "MerchantId": 20115, // Merchant Identifier.
        "CreatedDate": "2022-07-18T10:18:31.67087+00:00", // Payer Account Creation Date.
        "FirstName": "John", // First Name.
        "LastName": "Doe", // Last Name.
        "Email": "john@doe.com", // Email.
        "Currency": "GBP", // ISO Currency Code.
        "Country": "GB", // ISO Country Code.
        "Dob": "12/16/1990", // Date of Birth.
        "City": "London", // City.
        "ZipCode": "5123", // Postal Code.
        "Region": "London", // Region.
        "Street": "Baker Str. 12", // Street.
        "Phone": "+44839958434" // Phone.
     },
     "BinType": null, // Card BIN type (debit/credit/prepaid if available).
     "UsdAmount": 13.62, // Transaction amount converted to USD.
     "TransactionType": "PayIn", // PayIn / PayOut / Refund.
     "TransactionStatus": "Success", // Success / Rejected / Failed.
     "Amount": 12.58, // Final processed amount.
     "InitialAmount": 12.58, // Order price.
     "Currency": "EUR", // Payment currency.
     "TransactionId": 179411, // Internal transaction ID.
     "ExternalTransactionId": "63793736354518895200", // External transaction ID.
     "PaymentProcessor": "World Pay", // Payment processor name.
     "PaymentProcessorId": 50590, // Payment processor identifier.
     "PaymentProcessorTitleForSync": "World Pay", // Payment processor display name for sync.
     "DeclineReasonText": null, // Processing error description.
     "DeclineReasonCode": null, // Processing error code.
     "CardType": "Visa", // Visa, MasterCard, AMEX, JCB, UnionPayChina, Discover, DinersClub, MIR.
     "CardIssuer": null, // Card issuing bank name.
     "LastCcDigits": "5432", // Last 4 digits of CC number.
     "CascadingInfo": { // Cascading history (for CC payment systems only).
         "SessionId": "6908d8cf-06e6-4121-9969-3791aa77ace3",
         "AttemptsVector": [
            { // First attempt.
              "PaymentSystem": "Safe Charge",
              "PaymentProcessorId": 50133,
              "PaymentProcessorKey": "ad6335b8-7f52-45d7-81fb-11e5f81bc7f5",
              "DeclineReason": "Acquirer Validation",
              "ExternalTransactionId": "63814313373237072733",
              "InternalPspId": "711000000021055202",
              "TransactionId": 400854,
              "Date": "2023-03-13T14:09:33.2372322+00:00",
              "Status": "Rejected"
            },
            { // Last attempt.
              "PaymentSystem": "World Pay",
              "PaymentProcessorId": 50590,
              "PaymentProcessorKey": "1f052a08-7aeb-442c-aeed-b4040898d423",
              "DeclineReason": null,
              "ExternalTransactionId": "63793736354518895200",
              "InternalPspId": "5456650000021055202",
              "TransactionId": 179411,
              "Date": "2023-03-13T14:12:33.2372322+00:00",
              "Status": "Success"
            }
        ]
    },
    "IssueDate": "2023-03-13T14:12:33.2372322+00:00", // UTC+0 Webhook Issue date.
    "ClientIP": null, // Client IP address.
    "InternalPspId": "5456650000021055202", // Payment gateway's transaction unique ID.
    "MaskedPan": "455636******5432", // Masked credit card number for CC processors.
    "EncryptedGatewayData": null, // Encrypted gateway payload (if provided).
    "CreditCardDigest": null, // Card fingerprint/hash.
    "CreditCardCountry": null, // Card issuing country.
    "CrmPaymentType": 0, // Internal CRM payment type.
    "PlanKey": null, // Subscription plan key.
    "IsSubscriptionTransaction": false, // Indicates subscription-related transaction.
    "SubscriptionInvoiceId": null, // Subscription invoice ID.
    "Retried": true, // Indicates if transaction attempt was retried (read the section below).
    "Signature": "Xrg3DzkEsWlPzTjFFfe1K..7qqtPntyjtc6pCwCuTDY=" // Webhook signature.
}
```

{% endcode %}

> Webhook signature generated as:
>
> $signature = SHA256(\``` ${MERCHANT_SECRET_KEY_ISSUED_BY_PAYTIKO}:${orderId}` ``)

### Handling Retries

{% hint style="danger" %}
The merchant system domain logic implementation **must support successful order completion after previous rejections**.
{% endhint %}

#### Required Behavior

If an incoming webhook contains:

```json
{ 
    ...
    "Retried": true
    ...
}
```

the merchant system **must allow the order to transition to a successful state**, even if the order was previously marked as `Rejected`.

#### Important Notes

* A rejected order **must not be treated as permanently final** when `Retried = true`.
* The retry flow represents a new processing attempt initiated by the provider.
* Merchant systems must ensure that their state management logic does not block successful completion after a retry.

#### Example Scenario

1. Initial payment attempt → Order `Rejected`
2. Provider retries the transaction
3. Webhook received with:

```json
{
    ...
    "TransactionStatus": "Success", 
    "Retried": true
    ...
}
```

4. Merchant system updates the order status to `Success`

#### Required Order Status Transition

```
Rejected → Success (when Retried = true)
```

### JS Events

{% hint style="warning" %}
If you are going to host checkout page in the iframe instead of client redirection, please connect the following JS script to ensure payment flow redirections are properly handled:

<https://core.paytiko.com/cdn/js/helpers/js-events-subscribtion.1.0.min.js>
{% endhint %}

How to connect the script on your iframe container page:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Checkout page iframe container</title>
    <!-- Link to Paytiko event subscription helper script -->
    <script src="https://core.paytiko.com/cdn/js/helpers/js-events-subscribtion.1.0.min.js"></script>
</head>
<body>
    <!-- Your HTML content here -->
</body>
</html>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://paytiko.gitbook.io/docs/solutions/hosted-page.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
