# Payment WiFi Integration

## Initialize

### **1- Start Easypay Service:**

* Click the **Connect** button in the Easypay app.
* Click **Start** to initiate the service.
* Save the displayed IP Address for later use.
* Click **Running in Background** to keep the service active.

<div align="left"><figure><img src="/files/xJ7VZtSHmLBOqLthbPkk" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="/files/hcNZZuF3zU58EGK4MiX1" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="/files/DFVZgNQtyt3nX0MTjj7F" alt="" width="188"><figcaption></figcaption></figure></div>

### 2- **Create WebSocket Connection:**

Easypay service operates on two ports:

* **5000**: Insecure connection (HTTP)
* **9000**: Secure connection (HTTPS)

**Insecure Connection Example:**

```javascript
const socket = new WebSocket("ws://localhost:5000"); // Use "localhost" for same device or replace with "IP address" for external connections.

// Response format
socket.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.method === "WebSocketOpen" && data.DeviceName !== 'null') {
        // Initialization successful
        const deviceName = data.DeviceName; // Device name if supported by Easypay
    }
};
```

**Secure Connection Example:**

```javascript
const socket = new WebSocket("wss://localhost:9000"); // Use "localhost" for same device or replace with "IP address" for external connections.

// Response format
socket.onmessage = (event) => {
    const data = JSON.parse(event.data);
    if (data.method === "WebSocketOpen" && data.DeviceName !== 'null') {
        // Initialization successful
        const deviceName = data.DeviceName; // Device name if supported by Easypay
    }
};
```

## Purchase

**Important:** The `amount` should be entered without decimals. For example, `100` represents `1.00 SAR`, and `1455` represents `14.55 SAR`. The maximum length is 12 digits, including the exponent (e.g., `123456789012` equals `1,234,567,890.12 SAR`).

**Reference ID:** You may pass a `Reference ID` in the `customerReferenceNumber` field to attach it to the transaction. Otherwise, set it to `null`.

### **Processing a Purchase Request Using WiFi Integration**

To initiate a payment using the WiFi Integration method, establish a WebSocket connection and communicate with the Easypay service in real-time.

**Example Code:**

```javascript
// Function to make a payment using WebSocket Integration
function makePaymentWebSocket(socket, amount, customerReferenceNumber) {
    // Prepare the payment data
    const paymentData = [
        {
            method: "PURCHASE",
            amount: amount, // [Required] Amount to set (e.g., 100 represents 1.00 SAR)
            customerReferenceNumber: customerReferenceNumber || null // [Optional] Any string as a reference number
        }
    ];

    // Send the payment request through the WebSocket
    try {
        socket.send(JSON.stringify(paymentData));
        console.log("Purchase request sent:", paymentData);
    } catch (sendError) {
        console.error("Failed to send purchase request:", sendError);
        // Optionally, implement retry logic or notify the user
        return;
    }

    // Event listener for handling responses
    socket.onmessage = (event) => {
        try {
            const responseData = JSON.parse(event.data);

            // Simplified Error Handling
            if (responseData.error || responseData === false) {
                console.error("Payment Error:", responseData.error || "Invalid response.");
                // Optionally, notify the user about the error
                return;
            } else {
                const paymentResult = JSON.parse(responseData.message);
                if (paymentResult.is_approved) {
                    console.log("Payment Successful:", paymentResult);
                    // Optionally, proceed with post-payment actions
                } else {
                    console.warn("Payment Rejected:", paymentResult);
                    // Optionally, notify the user about the rejection
                }
            }
        } catch (parseError) {
            console.error("Failed to parse WebSocket message:", parseError);
            // Optionally, handle parsing errors or notify the user
        }
    };
}

// Example usage:
const socket = new WebSocket("wss://your-ip-address:9000");

socket.onopen = () => {
    console.log("WebSocket connection established.");
    makePaymentWebSocket(socket, 100, "1234");
};

socket.onclose = () => {
    console.log("WebSocket connection closed.");
};
```

Find Payment Sample Response model [here](/easypay/models.md#payment-sample-response-json)

## Refund

To process a refund, provide the `transactionUuid` of the original transaction you wish to refund.

### **Processing a Refund Using WiFi Integration**

To initiate a refund using the WiFi Integration method, establish a WebSocket connection and communicate with the Easypay service in real-time.

**Example Code:**

```javascript
// Function to process a refund using WebSocket Integration
function processRefundWebSocket(socket, transactionUuid, amount, customerReferenceNumber) {
    // Prepare the refund data
    const refundData = [
        {
            method: "REFUND",
            transactionUuid: transactionUuid, // [Required] Original transaction UUID.
            amount: amount, // [Required] Amount to refund.
            customerReferenceNumber: customerReferenceNumber || null // [Optional] Any string as a reference number.
        }
    ];

    // Send the refund request through the WebSocket
    try {
        socket.send(JSON.stringify(refundData));
        console.log("Refund request sent:", refundData);
    } catch (sendError) {
        console.error("Failed to send refund request:", sendError);
        // Optionally, implement retry logic or notify the user
        return;
    }

    // Event listener for handling responses
    socket.onmessage = (event) => {
        try {
            const responseData = JSON.parse(event.data);

            // Simplified Error Handling
            if (responseData.error || responseData === false) {
                console.error("Refund Error:", responseData.error || "Invalid response.");
                // Optionally, notify the user about the error
                return;
            } else {
                const refundResult = JSON.parse(responseData.message);
                if (refundResult.is_approved) {
                    console.log("Refund Successful:", refundResult);
                    // Optionally, proceed with post-refund actions
                } else {
                    console.warn("Refund Rejected:", refundResult);
                    // Optionally, notify the user about the rejection
                }
            }
        } catch (parseError) {
            console.error("Failed to parse WebSocket message:", parseError);
            // Optionally, handle parsing errors or notify the user
        }
    };
}

// Example usage:
const socket = new WebSocket("wss://your-ip-address:9000");

socket.onopen = () => {
    console.log("WebSocket connection established.");
    processRefundWebSocket(socket, "f5079b9d-b61c-4180-8a4d-9780f7a9cd8f", 100, "ORDER1234");
};

socket.onclose = () => {
    console.log("WebSocket connection closed.");
};
```

Find Payment Sample Response model [here](/easypay/models.md#payment-sample-response-json)

## Reconciliation

### **Processing a** Reconcile **Using WiFi Integration**

To initiate a Reconcile using the WiFi Integration method, establish a WebSocket connection and communicate with the Easypay service in real-time.

**Example Code:**

```javascript
// Function to reconcile transactions using WebSocket Integration
function reconcileWebSocket(socket) {
    // Prepare the reconcile data
    var data = {
        "method": "reconcile"
    };

    // Send the reconcile request through the WebSocket
    try {
        socket.send(JSON.stringify(data));
        console.log("Reconciliation request sent:", data);
    } catch (sendError) {
        console.error("Failed to send reconciliation request:", sendError);
        // Optionally, implement retry logic or notify the user
        return;
    }

    // Event listener for handling responses
    socket.onmessage = (event) => {
        try {
            const responseData = JSON.parse(event.data);

            // Simplified Error Handling
            if (responseData.error || responseData === false) {
                console.error("Reconciliation Error:", responseData.error || "Invalid response.");
                // Optionally, notify the user about the error
                return;
            } else {
                const reconcileResult = JSON.parse(responseData.message);
                if (reconcileResult .is_balanced !== undefined && reconcileResult .is_balanced.value) {
                    console.log("Reconciliation Successful:", reconcileResult );
                    // Optionally, proceed with post-reconciliation actions
                } else {
                    console.warn("Reconciliation Rejected:", reconcileResult );
                    // Optionally, notify the user about the rejection
                }
            }
        } catch (parseError) {
            console.error("Failed to parse WebSocket message:", parseError);
            // Optionally, handle parsing errors or notify the user
        }
    };
}

// Example usage:
const socket = new WebSocket("wss://your-ip-address:9000");

socket.onopen = () => {
    console.log("WebSocket connection established.");
    reconcileWebSocket(socket);
};

socket.onclose = () => {
    console.log("WebSocket connection closed.");
};
```

## **Receipt Management**

**Printing the Last Transaction Receipt**

```javascript
// Function to print the last transaction receipt using WebSocket Integration
function printLastReceiptWebSocket(socket) {
    // Prepare the print request data
    const printRequest = {
        method: "PrintLastResult"
    };

    // Send the print request through the WebSocket
    try {
        socket.send(JSON.stringify(printRequest));
        console.log("Print request sent:", printRequest);
    } catch (sendError) {
        console.error("Failed to send print request:", sendError);
        // Optionally, implement retry logic or notify the user
        return;
    }

}

// Example usage:
const socket = new WebSocket("wss://your-ip-address:9000");

socket.onopen = () => {
    console.log("WebSocket connection established.");
    printLastReceiptWebSocket(socket);
};

socket.onclose = () => {
    console.log("WebSocket connection closed.");
};
```

### Summary of Core Functionalities WiFi Integration

<table><thead><tr><th width="252">Functionality</th><th>WiFi Integration</th></tr></thead><tbody><tr><td><strong>Making a Payment</strong></td><td>- Sends <code>{ method: "PURCHASE", amount, customerReferenceNumber }</code> via WebSocket<br>- Handles real-time responses</td></tr><tr><td><strong>Processing a Refund</strong></td><td>- Sends <code>{ method: "REFUND", transactionUuid, amount, customerReferenceNumber }</code> via WebSocket<br>- Handles real-time responses</td></tr><tr><td><strong>Printing Last Receipt</strong></td><td>- Sends <code>{ method: "PrintLastResult" }</code> via WebSocket<br>- Handles real-time responses</td></tr><tr><td><strong>Opening the Cash Drawer</strong></td><td>- Sends <code>{ method: "OpenDrawer" }</code> via WebSocket<br>- Handles real-time responses</td></tr></tbody></table>


---

# Agent Instructions: 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:

```
GET https://docs.easypay.sa/easypay/payment-integration-guide/payment-wifi-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
