# Payment Links The [Payment Links API](/api/reference#payment-link) allows you to generate hosted payment pages that can be shared with customers via email, SMS, chat, or social media. These links support both simple **one-time purchases** and complex **recurring subscriptions**. ## Manual Creation via Merchant Dashboard While this guide focuses on the API for automated integrations, please note that Payment Links can also be created manually without any coding. **When to use the Dashboard:** - **Ad-hoc Requests:** Quickly creating a link for a specific customer support interaction. - **No-Code Testing:** Verifying the payment flow before integrating the API. - **Simple Operations:** Merchants who do not need programmatic generation. You can access this functionality by logging into your **xMoney Merchant Dashboard** and navigating to the **Payment Links** section. The dashboard provides a visual interface to set the amount, currency, and description, instantly generating a URL you can copy and paste. ## API Base Configuration #### Server Endpoint Important Payment Links use a specific server URL different from the standard API transaction endpoints. Base URL: - Stage Env: https://office-api-stage.xmoney.com - Live Env: https://office-api.xmoney.com #### Authentication All requests require authentication using a Bearer Token in the header. ```http Authorization: ``` ## 1. Create a Payment Link Generate a new payment link via API. You can define the link to be a simple description-based charge or a detailed itemized cart. - Endpoint: `POST /payment-link` - Content-Type: `application/x-www-form-urlencoded` **Required Parameters** | Parameter | Type | Description | | --- | --- | --- | | siteId | Integer | The ID of your site | | amount | Float | The total amount to charge (e.g., 100.00). | | currency | String | ISO Currency code (e.g., USD, EUR, GBP). | | orderType | String | `purchase` (one-off) or `recurring` (subscription). | | active | Integer | `1` (active) or `0` (inactive). | | contentType | String | `Description` (simple) or `Items` (detailed cart). | #### Scenario A: Simple One-Time Payment Use `contentType: Description` for a generic charge. ```bash curl curl -X POST "https://office-api-stage.xmoney.com/payment-link" \ -H "Authorization: YOUR_PRIVATE_KEY" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "siteId=123" \ -d "amount=50.00" \ -d "currency=USD" \ -d "orderType=purchase" \ -d "active=1" \ -d "contentType=Description" \ -d "content=Consulting Services" \ -d "customerEmail=client@example.com" ``` ```ts index.ts const axios = require('axios'); const qs = require('qs'); const data = qs.stringify({ 'siteId': '123', 'amount': '50.00', 'currency': 'USD', 'orderType': 'purchase', 'active': '1', 'contentType': 'Description', 'content': 'Consulting Services', 'customerEmail': 'client@example.com' }); const config = { method: 'post', url: 'https://office-api-stage.xmoney.com/payment-link', headers: { 'Authorization': 'YOUR_PRIVATE_KEY', 'Content-Type': 'application/x-www-form-urlencoded' }, data : data }; axios(config) .then(function (response) { console.log(JSON.stringify(response.data)); }) .catch(function (error) { console.log(error); }); ``` ```php index.php '123', 'amount' => '50.00', 'currency' => 'USD', 'orderType' => 'purchase', 'active' => '1', 'contentType' => 'Description', 'content' => 'Consulting Services', 'customerEmail' => 'client@example.com' ]; curl_setopt_array($curl, array( CURLOPT_URL => 'https://office-api-stage.xmoney.com/payment-link', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => http_build_query($payload), CURLOPT_HTTPHEADER => array( 'Authorization: YOUR_PRIVATE_KEY', 'Content-Type: application/x-www-form-urlencoded' ), )); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```python Python import requests url = "https://office-api-stage.xmoney.com/payment-link" payload = { 'siteId': '123', 'amount': '50.00', 'currency': 'USD', 'orderType': 'purchase', 'active': '1', 'contentType': 'Description', 'content': 'Consulting Services', 'customerEmail': 'client@example.com' } headers = { 'Authorization': 'YOUR_PRIVATE_KEY', 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` #### Scenario B: Itemized Cart Use `contentType: Items` to list specific products. You must use array notation for the items. ```bash curl curl -X POST "https://office-api-stage.xmoney.com/payment-link" \ -H "Authorization: YOUR_PRIVATE_KEY" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "siteId=123" \ -d "amount=30.00" \ -d "currency=USD" \ -d "orderType=purchase" \ -d "active=1" \ -d "contentType=Items" \ # Item 1 -d "content[0][item]=T-Shirt" \ -d "content[0][unitPrice]=20.00" \ -d "content[0][units]=1" \ -d "content[0][type]=physical" \ # Item 2 -d "content[1][item]=Stickers" \ -d "content[1][unitPrice]=5.00" \ -d "content[1][units]=2" \ -d "content[1][type]=physical" ``` ```ts index.ts const axios = require('axios'); const qs = require('qs'); // qs library automatically handles nested objects like content[0][item] const data = qs.stringify({ 'siteId': '123', 'amount': '30.00', 'currency': 'USD', 'orderType': 'purchase', 'active': '1', 'contentType': 'Items', 'content': [ { 'item': 'T-Shirt', 'unitPrice': '20.00', 'units': '1', 'type': 'physical' }, { 'item': 'Stickers', 'unitPrice': '5.00', 'units': '2', 'type': 'physical' } ] }); const config = { method: 'post', url: 'https://office-api-stage.xmoney.com/payment-link', headers: { 'Authorization': 'YOUR_PRIVATE_KEY', 'Content-Type': 'application/x-www-form-urlencoded' }, data : data }; axios(config) .then((response) => console.log(JSON.stringify(response.data))) .catch((error) => console.log(error)); ``` ```php index.php '123', 'amount' => '30.00', 'currency' => 'USD', 'orderType' => 'purchase', 'active' => '1', 'contentType' => 'Items', 'content' => [ [ 'item' => 'T-Shirt', 'unitPrice' => '20.00', 'units' => '1', 'type' => 'physical' ], [ 'item' => 'Stickers', 'unitPrice' => '5.00', 'units' => '2', 'type' => 'physical' ] ] ]; curl_setopt_array($curl, array( CURLOPT_URL => 'https://office-api-stage.xmoney.com/payment-link', CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => http_build_query($payload), CURLOPT_HTTPHEADER => array( 'Authorization: YOUR_PRIVATE_KEY', 'Content-Type: application/x-www-form-urlencoded' ), )); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```python Python import requests url = "https://office-api-stage.xmoney.com/payment-link" # Python requests does not automatically nest dicts for form-data efficiently. # We define keys explicitly to ensure correct structure. payload = { 'siteId': '123', 'amount': '30.00', 'currency': 'USD', 'orderType': 'purchase', 'active': '1', 'contentType': 'Items', # Item 0 'content[0][item]': 'T-Shirt', 'content[0][unitPrice]': '20.00', 'content[0][units]': '1', 'content[0][type]': 'physical', # Item 1 'content[1][item]': 'Stickers', 'content[1][unitPrice]': '5.00', 'content[1][units]': '2', 'content[1][type]': 'physical' } headers = { 'Authorization': 'YOUR_PRIVATE_KEY', 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` #### Scenario C: Recurring Subscription To create a subscription link, set `orderType` to `recurring` and provide interval details. | Parameter | Description | | --- | --- | | intervalType | `day` or `month`. | | intervalValue | Number of intervals (e.g., 1 for every month). | | trialAmount (Optional) | Amount for the first charge. | | firstBillDate (Optional) | ISO 8601 date for the first recurring charge. | **Example:** ```bash curl curl -X POST "https://office-api-stage.xmoney.com/payment-link" \ -H "Authorization: YOUR_PRIVATE_KEY" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "siteId=123" \ -d "amount=10.00" \ -d "currency=USD" \ -d "orderType=recurring" \ -d "contentType=Description" \ -d "content=Monthly Sub" \ -d "intervalType=month" \ -d "intervalValue=1" ``` ```ts index.ts const axios = require('axios'); const qs = require('qs'); const data = qs.stringify({ 'siteId': '123', 'amount': '10.00', 'currency': 'USD', 'orderType': 'recurring', 'contentType': 'Description', 'content': 'Monthly Sub', 'intervalType': 'month', 'intervalValue': '1' }); const config = { method: 'post', url: 'https://office-api-stage.xmoney.com/payment-link', headers: { 'Authorization': 'YOUR_PRIVATE_KEY', 'Content-Type': 'application/x-www-form-urlencoded' }, data : data }; axios(config) .then((response) => console.log(JSON.stringify(response.data))) .catch((error) => console.log(error)); ``` ```php index.php '123', 'amount' => '10.00', 'currency' => 'USD', 'orderType' => 'recurring', 'contentType' => 'Description', 'content' => 'Monthly Sub', 'intervalType' => 'month', 'intervalValue' => '1' ]; curl_setopt_array($curl, array( CURLOPT_URL => 'https://office-api-stage.xmoney.com/payment-link', CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => http_build_query($payload), CURLOPT_HTTPHEADER => array( 'Authorization: YOUR_PRIVATE_KEY', 'Content-Type: application/x-www-form-urlencoded' ), )); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```python Python import requests url = "https://office-api-stage.xmoney.com/payment-link" payload = { 'siteId': '123', 'amount': '10.00', 'currency': 'USD', 'orderType': 'recurring', 'contentType': 'Description', 'content': 'Monthly Sub', 'intervalType': 'month', 'intervalValue': '1' } headers = { 'Authorization': 'YOUR_PRIVATE_KEY', 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` #### Response ```JSON { "code": 0, "message": "string", "data": { "hash": string, } } ``` ## 2. Retrieve & Manage Links #### Get Payment Link Details Retrieve a single payment link using its unique hash. - Endpoint: `GET /payment-link/{hash}` #### List Payment Links Search for payment links associated with a site. - Endpoint: `GET /payment-link` - Required Parameter: `siteId` **Filtering Options (Query Parameters):** | Parameter | Description | | --- | --- | | amount | Filter by specific amount. | | active | `1` or `0`. | | startDate / endDate | Filter by creation date (format: yyyy-mm-dd hh:mm:ss). | | customerEmail | Filter by customer email. | | limitAccess | Filter by number of allowed accesses. | #### Update Payment Link Modify an existing payment link. Note that changing amounts or items will affect future customers using this link. - Endpoint: `PUT /payment-link/{hash}` - Body: Same parameters as the **Create** endpoint. #### Delete Payment Link Permanently remove a payment link. - Endpoint: `DELETE /payment-link/{hash}` ## 3. Advanced Features #### Controlling Link Access You can limit how a link is used or when it expires via the following parameters during Creation or Update: - `limitAccess`: Integer. The maximum number of times the link can be successfully paid. - `expireDate`: String (Date format: yyyy-mm-dd). The date after which the link becomes invalid. - `active`: Set to 0 to temporarily disable the link without deleting it. #### Customer Data Pre-fill If you know the customer details beforehand, you can pre-fill them to simplify their checkout experience: - `customerEmail` - `customerIdentifier` - `customerTags[]` #### Required Customer Fields You can force specific fields to be mandatory during checkout by setting these parameters to 1: - `customerRequiredFields[firstName]` - `customerRequiredFields[lastName]` - `customerRequiredFields[address]` - `customerRequiredFields[phone]` - (and others as defined in the schema) #### Level 3 Data (Airline & Tourism) For specialized industries, you can pass Level 3 data using the `level3Type` parameter (set to `airline` or `tourism`) and the associated fields (e.g., `level3AirlineTicketNumber`, `level3TourismDepartureDate`, etc.). Refer to the full API schema for the complete list of Level 3 fields. ## Conclusion & Further Reference This guide covers the core functionalities for creating and managing Payment Links, including one-time purchases, subscriptions, and itemized carts. For a complete list of all available parameters, error codes, and specific data constraints (including detailed Level 3 data fields for Airline and Tourism sectors), please refer to the official API documentation: - Full API Reference: [https://docs.xmoney.com/api/reference/payment-links](https://docs.xmoney.com/api/reference/payment-links)