## Zoho Payments Documentation Index Access the complete documentation index at: https://www.zoho.com/us/payments/llms.txt Use this file to discover all available documentation pages before proceeding. # Integrating Hosted Checkout ![](/payments/svg/cross.svg) ## Install Skills Give your coding agents the context they need to build with Zoho Payments. [View documentation](/us/payments/developerdocs/agent-skills/) `npx skills add https://www.zoho.com/payments/` ![](/payments/svg/copy-icon.svg) **Note:** Skills-only installs don't receive automatic updates. Run `npx skills update -y` to get the latest version. The Hosted Checkout is a pre-built, secure payment interface hosted by Zoho Payments. Instead of embedding a checkout widget in your website, you redirect customers to a hosted checkout where they can complete their payment. Check out our [API Docs](https://www.zoho.com/us/payments/api/v1/introduction/#overview "API Docs") for endpoint details and request examples. Follow the steps below to integrate the hosted checkout. * [Establish Communication](#establish-communication) * [Create Payment Session](#create-payment-session) * [Redirect Customer](#redirect-customer) * [Handle Payment Outcome](#handle-payment-outcome) * [Verify Signature](#verify-signature) * [Verify Payment Status](#verify-status) ## 1\. Establish Communication To communicate with our APIs and webhooks, you must first establish connectivity. Ensure that your setup allows or whitelists the Zoho Payments domain, **payments.zoho.com**. ## 2\. Create Payment Session To initiate the payment process, create a payment session on your server. The session captures the payment amount, currency, and hosted checkout configuration, including redirect URLs and customer details. To create a payment session: 1. Collect the payment details (amount, currency, etc.) and the hosted checkout parameters (success or failure URLs, customer info) from your application. 2. Call the [Payment Session Create API](https://www.zoho.com/us/payments/api/v1/payment-session/#create-payment-session "payment-session") from your server. Include the `hosted_checkout_parameters` object within the `configurations` field. Create Payment Session Copy ```json { "amount": "500", "currency": "USD", "configurations": { "allowed_payment_methods": [ "ach", "card" ], "hosted_checkout_parameters": { "phone": "7654345673", "description": "Test Payment", "email": "test@example.com", "success_url": "https://example.com/success", "failure_url": "https://example.com/failure", "udf1": "testingudf1", "udf2": "testingudf2", "udf3": "testingudf3", "udf4": "testingudf4", "udf5": "testingudf5" } } } ``` The `hosted_checkout_parameters` object supports the following fields: **Parameter** **Type** **Required** **Description** `success_url`\* String Yes The URL to redirect the customer to after a successful payment. `failure_url`\* String Yes The URL to redirect the customer to after a failed payment. `phone` String No Customer’s phone number. `email` String No Customer’s email address. `description`\* String No A brief description of the payment. `udf1` – `udf5` String No Custom fields for passing additional information. These values are returned in the redirect URL after payment completion. Do not pass any sensitive information in these fields. \*_Indicates mandatory fields._ **Notes:** * The `max_retry_count` is set to 1 by default for hosted checkout. If you set a higher value via the Payment Session API, the customer gets multiple attempts to complete the payment. If you’re listening to the `payment.failed` webhook, note that it is triggered for each failed attempt, not once for the entire session. For example, if a payment attempt fails three times before succeeding, you’ll receive three `payment.failed` webhooks for that session. * Once a payment is successful, the session is closed, and no further attempts are allowed. Ensure your server handles these webhook events correctly to determine the final payment status. 3. The API will return a response containing an `access_key`. Use this key to construct the hosted checkout URL in the next step. Payment Session Response Copy ```json { "code": 0, "message": "success", "payments_session": { "access_key": "8VMvUrsh2WdUpkwGaiM4SAfPrP-RgbD3s2OFZ-Y0Uw", "configurations": { "allowed_payment_methods": [ "ach", "card" ], "hosted_checkout_parameters": { "phone": "7654345673", "description": "Test Payment", "failure_url": "https://example.com/failure", "udf1": "testingudf1", "udf2": "testingudf2", "udf3": "testingudf3", "udf4": "testingudf4", "udf5": "testingudf5", "email": "test@example.com", "success_url": "https://example.com/success" } }, "payments_session_id": "9324000001068001", "currency": "USD", "amount": "500.00", "created_time": 1774939546, "expiry_time": 1774940446, "meta_data": [] } } ``` ## 3\. Redirect Customer After creating the payment session, redirect the customer to the hosted checkout using the `access_key` from the response. Hosted Checkout Redirect URL Format Copy ```text https://payments.zoho.com/hostedcheckout/ ``` Example URL Copy ```text https://payments.zoho.com/hostedcheckout/8VMvUrsh2WdUpkwGaiM4SAfPrP-RgbD3s2OFZ-Y0Uw ``` The customer will be able to choose a payment method and complete their payment. ## 4\. Handle Payment Outcome Once the customer completes the payment, they are redirected to either the `success_url` or `failure_url` you provided during session creation, based on the payment outcome: * **Succeeded:** The customer is redirected to the `success_url`. * **Failed:** The customer is redirected to the `failure_url`. * **In Progress:** Applicable for ACH transfers. The customer is redirected to the `success_url`. You can verify the final payment status using [configured webhooks](/us/payments/developerdocs/webhooks/configure/ "configure-webhooks"). The redirect URL includes the following query parameters: **Parameter** **Type** **Always Present** **Description** `payments_session_id` String Yes The unique identifier assigned to the payment session. `payment_session_status` String Yes The status of the session: `succeeded`, `failed`, or `in_progress` (ACH). `payment_id` String No The unique identifier assigned to the payment transaction. The `payment_id` is not returned when the status is `in_progress` (ACH). `payment_status` String No The payment status: `succeeded` or `failed`. `amount` String No The amount charged (e.g., `1200.00`). `udf1` – `udf5` String No Custom fields passed during session creation. `signature` String Yes HMAC-SHA256 signature for verification. **Note:** In some cases, you may not receive the `payment_id` if the customer accidentally closes the browser or navigates away before a response is returned. In such cases, use your configured webhooks or the `payment_session_id` to retrieve the payment status. ## 5\. Verify Signature To ensure the redirect is authentic and has not been tampered with, verify the `signature` parameter included in the return URL. The signature is an HMAC-SHA256 hash computed over key parameters. To verify the signature: 1. Concatenate the following fields with `.` (dot) as the separator, in this exact order. Use an empty string for any absent field. Signature Message Format Copy ```text payments_session_id.payment_session_status.payment_id.payment_status.amount.udf1.udf2.udf3.udf4.udf5 ``` 2. Use your signing key to compute the HMAC-SHA256 hash of the message string constructed in the previous step. 3. Compare the computed hash with the `signature` parameter from the redirect URL. For example, a successful payment returns the following URL: Example Return URL Copy ```text https://example.com/success?payments_session_id=4000000106013&payment_session_status=succeeded&payment_id=4000000106034&payment_status=succeeded&amount=5.000&udf1=customerid1234&udf2=orderref5678&udf3=productskuabc&udf4=merchantrefxyz&udf5=campaignsummer24&signature=81515cc0deb8f0d95cc4a4cb755bbef33aa7fa068325756df5b4e360a2b3a0d2 ``` The message to sign would be: Message String Copy ```text 4000000106013.succeeded.4000000106034.succeeded.5.000.customerid1234.orderref5678.productskuabc.merchantrefxyz.campaignsummer24 ``` **Insight:** Always verify the signature on your server before trusting the payment status from the redirect URL. This prevents tampering and ensures the payment outcome is authentic. ## 6\. Verify Payment Status You can verify your payment status in two ways: * **Verify via Webhooks:** Use your [configured webhooks](/us/payments/developerdocs/webhooks/configure/ "configure-webhooks") for the events `payment.success` and `payment.failed` to receive the final payment status directly. * **Verify via Session ID:** Use this method when the payment status is not received through the widget response or webhooks. This can happen in the following scenarios: * The customer closes the payment widget before completion. * The `payment.success` or `payment.failed` webhooks are not configured. * Webhooks are temporarily inactive due to repeated delivery failures. In such cases, retrieve the payment status using the [Payment Session Retrieve API](https://www.zoho.com/us/payments/api/v1/payment-session/#retrieve-payment-session "Session"). This allows you to check the final outcome of the payment using the session ID. **Note:** Ensure that all three options are configured for reliable payment verification. Update your system only after verifying the payment status using any of the methods listed above.