Hosted Payment Page
Accept payments online with PayOrc's fully managed hosted payment page. Redirect your customers to a secure, PCI-compliant checkout without handling card data.
Hosted Payment Page
Version: 3.0.0
What is the Hosted Payment Page? The Hosted Payment Page is PayOrc's easiest integration method. You redirect your customer to a fully managed, PCI DSS-compliant checkout page hosted by PayOrc. Your application never touches raw card data — PayOrc handles collection, validation, 3D Secure, and authorization on your behalf.
Why Use the Hosted Payment Page?
- Zero PCI burden — Card data never touches your servers, so you avoid SAQ-A or SAQ-A-EP compliance entirely.
- Fastest time to market — One API call generates a payment link. Redirect your customer and you're done.
- Full branding control — Customize colors, logos, and fields through your PayOrc dashboard before redirecting.
- Built-in security — 3D Secure 2.0, tokenization, fraud screening, and SSL are all handled for you.
Prerequisites
Before integrating, ensure you have:
- An active PayOrc merchant account
- An API key generated for the Hosted Solution channel
- Navigate to Developers → API Keys → Add new API key → Select "Hosted Solution" in the Channel dropdown
- Your
merchant-keyandmerchant-secretcredentials ready
Authentication
All API requests require two headers:
| Header | Description |
|---|---|
merchant-key | Your unique merchant API key |
merchant-secret | Your secret key paired with the merchant key |
Keep your credentials safe. Never expose merchant-secret in client-side code or public repositories. All requests must be made from your server.
Flow Overview
Here is the complete step-by-step payment flow:
Step 1 — Create Order:
Your server sends a POST request to the PayOrc API to create a payment order. You include order details (amount, currency, customer info, redirect URLs).
Step 2 — Receive Payment Link:
PayOrc responds with a payment_link URL and an iframe_link URL. The payment link points to the hosted checkout page.
Step 3 — Redirect Customer:
You redirect your customer to the payment_link. The customer enters their card details on PayOrc's secure page.
Step 4 — 3D Secure (if enabled): If 3D Secure is enabled for the transaction, the customer is redirected to their bank's authentication page, then brought back to PayOrc.
Step 5 — Transaction Processing:
PayOrc processes the payment (authorization and/or capture depending on your capture_method setting).
Step 6 — Redirect to Merchant:
Based on the outcome, the customer is redirected to your success, failure, or cancel URL with transaction details appended.
Step 7 — Server-Side Callback: PayOrc also sends a POST callback to your configured endpoint with the full transaction payload for server-side verification.
Step 1: Create Order
Make a POST request to the /orders/v1/create endpoint with your order details. This is the only call you need to initiate a hosted payment.
Endpoint:
POST https://api.payorc.com/orders/v1/createRequest Body
All fields are nested inside a top-level data object: { "data": { ... } }. The customer_details, order_details, billing_details, shipping_details, and urls objects are all required — a request missing any of them is rejected (e.g. Shipping details object missing). Individual fields marked "Yes" are required by the schema but may be passed as empty strings unless noted otherwise.
| Field | Type | Required | Description |
|---|---|---|---|
data.action | String | Yes | Transaction action. Use AUTH for authorization, SALE for immediate capture, or AUTH_REVERSAL for card tokenization. |
data.class | String | Yes | Transaction class. Accepts ECOM (hosted e-commerce checkout) or CAUTH (charge a stored card via payment_token). Use ECOM for a standard hosted payment. |
data.capture_method | String | No | AUTOMATIC (default) or MANUAL. Only relevant when action is AUTH; ignored for SALE. Defaults to AUTOMATIC when omitted. |
data.payment_token | String | No | Stored-card token. Only used with class: "CAUTH". Leave empty or omit for ECOM. |
data.customer_details | Object | Yes | Customer information object (required). |
data.customer_details.m_customer_id | String | No | Your internal customer identifier. |
data.customer_details.name | String | Yes | Full name of the customer. May be an empty string. |
data.customer_details.email | String | Yes | Customer email address. May be an empty string. |
data.customer_details.mobile | String | No | Customer mobile number (digits only, without country code). |
data.customer_details.code | String | No | Country dial code (e.g., 91 for India, 971 for UAE). |
data.order_details | Object | Yes | Order details object (required). |
data.order_details.m_order_id | String | No | Your internal order identifier. |
data.order_details.amount | Number | Yes | Transaction amount. Minimum 1 (e.g., 150). |
data.order_details.convenience_fee | Number | Yes | Additional fee. May be 0 or an empty string. |
data.order_details.quantity | Number | Yes | Number of items. May be an empty string; defaults to 1 in processing. |
data.order_details.currency | String | Yes | Three-letter ISO 4217 currency code (e.g., AED, USD). |
data.order_details.description | String | Yes | Human-readable order description. May be an empty string. |
data.order_details.return_url | String | No | Optional return URL stored with the order. |
data.billing_details | Object | Yes | Billing address object (required). All keys should be present; values may be empty strings. |
data.billing_details.address_line1 | String | Yes | Primary billing address line. May be "". |
data.billing_details.address_line2 | String | Yes | Secondary billing address line. May be "". |
data.billing_details.city | String | Yes | Billing city. May be "". |
data.billing_details.province | String | Yes | Billing state/province. May be "". |
data.billing_details.country | String | Yes | ISO 3166-1 alpha-2 country code (e.g., AE, IN). May be "". |
data.billing_details.pin | String | Yes | Postal/ZIP code. May be "". |
data.shipping_details | Object | Yes | Shipping details object (required). Requests without it are rejected with Shipping details object missing. All keys should be present; values may be empty strings. |
data.shipping_details.shipping_name | String | Yes | Recipient's full name. May be "". |
data.shipping_details.shipping_email | String | Yes | Recipient's email address. May be "". |
data.shipping_details.shipping_code | String | No | Country dial code for the shipping mobile. |
data.shipping_details.shipping_mobile | String | No | Recipient's phone number (digits only). |
data.shipping_details.address_line1 | String | Yes | Shipping address line 1. May be "". |
data.shipping_details.address_line2 | String | Yes | Shipping address line 2. May be "". |
data.shipping_details.city | String | Yes | Shipping city. May be "". |
data.shipping_details.province | String | Yes | Shipping state/province. May be "". |
data.shipping_details.country | String | Yes | ISO 3166-1 alpha-2 country code. May be "". |
data.shipping_details.pin | String | Yes | Shipping postal/ZIP code. May be "". |
data.shipping_details.location_pin | String | Yes | Map location URL. May be "". |
data.shipping_details.shipping_currency | String | Yes | ISO 4217 currency for shipping. May be "". |
data.shipping_details.shipping_amount | Number | Yes | Shipping cost. May be 0 or an empty string. |
data.items | Array | No | Line items for the order. See the Payment Request API for the full item field list. |
data.urls | Object | Yes | Redirect and webhook URLs object (required). |
data.urls.success | String | No | URL to redirect the customer on successful payment. Falls back to the MID default URL when omitted. |
data.urls.cancel | String | No | URL to redirect the customer if they cancel. Falls back to the MID default URL when omitted. |
data.urls.failure | String | No | URL to redirect the customer if payment fails. Falls back to the MID default URL when omitted. |
data.urls.webhook_url | String | No | Per-order webhook URL (must use HTTPS). Overrides the dashboard webhook for this order. |
data.parameters | Array | No | Merchant metadata echoed back in webhook notifications. |
data.custom_data | Array | No | MID Group / Split Payment configuration. See Custom Data. |
Code Examples
curl --location --globoff 'https://api.payorc.com/orders/v1/create' \
--header 'merchant-key: YOUR_MERCHANT_KEY' \
--header 'merchant-secret: YOUR_MERCHANT_SECRET' \
--header 'Content-Type: application/json' \
--data-raw '{
"data": {
"action": "SALE",
"class": "ECOM",
"capture_method": "AUTOMATIC",
"payment_token": "",
"customer_details": {
"m_customer_id": "CUST-10042",
"name": "John Doe",
"email": "[email protected]",
"mobile": "9876543210",
"code": "91"
},
"order_details": {
"m_order_id": "ORD-2024-001",
"amount": 150,
"convenience_fee": 0,
"quantity": 1,
"currency": "AED",
"description": "Annual subscription plan",
"return_url": "https://your-site.com/return"
},
"billing_details": {
"address_line1": "123 Business Park",
"address_line2": "Unit 5B",
"city": "Dubai",
"province": "Dubai",
"country": "AE",
"pin": "54044"
},
"shipping_details": {
"shipping_name": "John Doe",
"shipping_email": "[email protected]",
"shipping_code": "",
"shipping_mobile": "",
"address_line1": "123 Business Park",
"address_line2": "Unit 5B",
"city": "Dubai",
"province": "Dubai",
"country": "AE",
"pin": "54044",
"location_pin": "",
"shipping_currency": "AED",
"shipping_amount": 0
},
"items": [
{
"title": "Annual Subscription",
"description": "12-month plan",
"quantity": 1,
"unit_price": "150.00",
"discount_amount": "0.00",
"reference_id": "SUB-ANNUAL",
"is_refundable": true
}
],
"urls": {
"success": "https://your-site.com/payment/success",
"cancel": "https://your-site.com/payment/cancel",
"failure": "https://your-site.com/payment/failure",
"webhook_url": "https://your-site.com/webhook"
},
"parameters": [
{ "alpha": "" },
{ "beta": "" },
{ "gamma": "" },
{ "delta": "" },
{ "epsilon": "" }
],
"custom_data": [
{ "alpha": "" },
{ "beta": "" },
{ "gamma": "" },
{ "delta": "" },
{ "epsilon": "" }
]
}
}'Security Warning: The JavaScript example above uses server-side fetch. Never call this endpoint from a browser's client-side JavaScript — it would expose your merchant-key and merchant-secret. Always make API calls from your backend.
Step 2: Redirect to Payment Page
Once you receive a successful response, redirect the customer to the payment_link URL. This opens PayOrc's fully managed checkout page where the customer can enter their payment details.
Payment Link Expiry: The payment page expires 15 minutes after generation. If the customer does not complete the payment within this window, the link becomes invalid and you must create a new order.
The response also includes an iframe_link if you prefer to embed the checkout directly on your site (see the Iframe Integration page).
Step 3: Handle the Redirect
When the customer completes, cancels, or fails at the payment page, they are redirected back to one of the URLs you specified in the request.
| Redirect URL | Trigger | Use Case |
|---|---|---|
success | Payment authorized/captured successfully | Update order status, show confirmation |
cancel | Customer clicked "Cancel" or navigated away | Log the attempt, show cancellation message |
failure | Payment was declined or an error occurred | Show error, allow retry |
The redirect URL includes query parameters with transaction details (see Post Final Response for the full field reference).
Response Fields
| Field | Type | Description |
|---|---|---|
status | String | SUCCESS or fail |
status_code | String | "00" for success, other codes indicate specific errors |
message | String | Human-readable result message (e.g., Order created) |
p_order_id | Integer | Unique order ID assigned by PayOrc |
m_order_id | String | Your merchant order ID from the request |
p_request_id | Integer | Unique request ID assigned by PayOrc |
order_creation_date | String | Timestamp of order creation (DD/MM/YYYY HH:MM:SS) |
amount | String | Formatted amount with currency (e.g., AED 150.00) |
payment_link | String | Full URL to redirect the customer to the hosted checkout |
iframe_link | String | Full URL for embedding in an iframe |
Example: Success Response
{
"status": "SUCCESS",
"status_code": "00",
"message": "Order created",
"p_order_id": 1000010240,
"m_order_id": "ORD-2024-001",
"p_request_id": 1000010200,
"order_creation_date": "15/06/2023 12:20:27",
"amount": "AED 150.00",
"payment_link": "https://checkout.payorc.com/pay/abc123xyz",
"iframe_link": "https://checkout.payorc.com/embed/abc123xyz"
}Example: Error Response
{
"status": "fail",
"status_code": 401,
"message": "Invalid merchant key and secret",
"code": "401"
}Pro Tip: Store the p_order_id and p_request_id in your database when the order is created. You will need these values to reconcile transactions when the callback arrives.
What Happens After the Customer Pays?
- PayOrc processes the payment with the acquiring bank/PSP.
- If 3D Secure was triggered, the authentication result is included in the authorization decision.
- The customer is redirected to your success/failure/cancel URL with query parameters containing the transaction details.
- PayOrc simultaneously sends a server-to-server POST callback to your configured endpoint with the full transaction payload.
- Your application should verify the callback signature, update the order status, and fulfill the purchase.
Always use the server-side callback for order fulfillment — never rely solely on the client-side redirect. The redirect can be spoofed or lost due to network issues.