# refundDeal

## Overview

The `refundDeal` command refunds funds to customers for transactions that have already been settled. This command automatically handles the complexity of refund vs cancellation logic based on the transaction's transmission status to Shva (Israel's payment processor).

**Key Features:**

* **Automatic fallback**: Cancels non-transmitted transactions, refunds transmitted ones
* **Partial refunds**: Support for amounts less than the original transaction
* **Installment flexibility**: Customizable refund schedules for installment transactions
* **Multiple lookup methods**: Find transactions using various identifiers

  <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p><strong>Best Practice</strong>: Use <code>refundDeal</code> instead of <code>cancelDeal</code> when unsure about transmission status. The system automatically determines whether to cancel or refund based on the transaction state.</p></div>

  \## Use cases
* **Refund settled transactions**: Process refunds for transactions that have been transmitted to Shva (see [Refunds & Cancellations](/creditguard/additional-payment-scenarios/refunds-and-cancellations.md))
* **Partial refunds**: Support for amounts less than the original transaction with flexible refund scheduling
* **Customer refund requests**: Handle standard customer refund scenarios (recommended over `cancelDeal` in most cases)
* **Installment transaction refunds**: Refund installment transactions with customizable refund schedules (see [Refunds & Cancellations](/creditguard/additional-payment-scenarios/refunds-and-cancellations.md))
* **Automatic fallback processing**: Let the system determine whether to cancel or refund based on transmission status
* **Invoice-specific refunds**: Use with [`refundCgInvoice`](/creditguard/documents-and-invoicing/refund-invoices.md) for document-tied refunds

## Request structure

For a comprehensive overview of the API request format and authentication, see [API Request & Response General Structure](/creditguard/introduction/request-and-response-general-structure.md).

Send a standard Hyp API request to your assigned server endpoint with the `refundDeal` command in the `int_in` parameter.

{% hint style="success" %}
**Server Endpoints**: Use the server endpoint provided during merchant onboarding (e.g., `https://your-hyp-environment-url/xpo/Relay`).
{% endhint %}

The `refundDeal` command uses the following endpoint:

**POST** `https://your-hyp-environment-url/xpo/Relay`

### Request parameters

| Parameter    | Type   | Description                                              |
| ------------ | ------ | -------------------------------------------------------- |
| **user**     | string | Username for API authentication (body parameter)         |
| **password** | string | Password for API authentication (body parameter)         |
| **int\_in**  | string | XML payload containing the request data (body parameter) |

### XML payload structure

```xml
<ashrait>
    <request>
        <version>2000</version>
        <language>ENG</language>
        <requestId/>
        <command>refundDeal</command>
        <refundDeal>
            <!-- At least one of the following required: tranId, cgUid, or orgUid -->
            <tranId>{transactionId}</tranId>
            <!-- OR <cgUid>{cgIdentifier}</cgUid> -->
            <!-- OR <ashraitEmvData><orgUid>{originalUid}</orgUid></ashraitEmvData> -->
            
            <!-- Optional parameters -->
            <terminalNumber>{terminalNumber}</terminalNumber>
            <total>{refundAmount}</total>
        </refundDeal>
    </request>
</ashrait>
```

## Required parameters

**At least one of the following three parameters must be provided:**

<details>

<summary><strong>tranId</strong> - Transaction ID</summary>

**Type**: String\
**Required**: At least one lookup parameter required\
**Description**: Unique transaction request ID for a specific transaction step

**Example**: `118372223`

**Usage Notes**:

* When provided, other lookup elements are ignored
* Most specific identifier for a transaction step
* Returned in response from the original transaction

</details>

<details>

<summary><strong>cgUid</strong> - CG Identifier</summary>

**Type**: String\
**Required**: At least one lookup parameter required\
**Description**: CG identifier shared across related transactions (finds latest transaction state)

**Example**: `118372223`

**Usage Notes**:

* Links related transactions together
* Useful for tracking transaction chains
* Returned in response from the original transaction

</details>

<details>

<summary><strong>orgUid</strong> - Original UID</summary>

**Type**: String\
**Required**: At least one lookup parameter required\
**Description**: A unique transaction ID assigned according to the Ashrait protocol

**Example**:

```xml
<ashraitEmvData>
    <orgUid>25062617340908828192261</orgUid>
</ashraitEmvData>
```

**Usage Notes**:

* Must be wrapped in `ashraitEmvData` element
* Unique identifier from Shva payment processor
* Used for direct transaction reference

</details>

## Optional parameters

<details>

<summary><strong>terminalNumber</strong> - Your merchant terminal identifier</summary>

**Type**: String\
**Required**: No\
**Description**: The unique terminal number assigned during merchant onboarding

**Example**: `0882819014`

**Usage Notes**:

* Must match your assigned terminal number
* Used for transaction lookup and authorization
* Available in your merchant dashboard

</details>

<details>

<summary><strong>user</strong> - User Field</summary>

**Type**: String (1-19) **Required**: No\
**Description**: Custom user identifier from original transaction

**Example**: `customer123`

**Usage Notes**:

* Must match the value from the original transaction
* Useful for merchant-specific tracking

</details>

<details>

<summary><strong>total</strong> - Refund amount in currency subunits</summary>

**Type**: String (numeric)\
**Required**: No\
**Description**: Amount to refund in cents/agorot (e.g., 4730 = $47.30)

**Default**: Full amount of original transaction\
**Example**: `4730` (refunds $47.30)

**Usage Notes**:

* Must be less than or equal to the original transaction amount
* For partial refunds, the original transaction remains unchanged
* Even partial refunds of non-transmitted transactions create credit transactions

</details>

<details>

<summary><strong>shiftId1, shiftId2, shiftId3</strong> - Shift identifiers for transaction grouping</summary>

**Type**: String\
**Required**: No\
**Description**: Used to mark the refund transaction with shift values

**Usage Notes**:

* Used for internal transaction grouping
* Helpful for reconciliation and reporting
* Not suitable for searching the original debit transaction

</details>

## Response structure

### Successful response

A successful `refundDeal` response contains details of the new credit transaction:

```xml
<?xml version='1.0'?>
<ashrait>
    <response>
        <command>refundDeal</command>
        <dateTime>2025-06-26 17:37</dateTime>
        <requestId/>
        <tranId>118372255</tranId>
        <result>000</result>
        <message>Permitted transaction</message>
        <userMessage>Permitted transaction</userMessage>
        <version>2000</version>
        <language>ENG</language>
        <refundDeal>
            <status>000</status>
            <statusText>Permitted transaction</statusText>
            <terminalNumber>0882819014</terminalNumber>
            <transactionType code="52">Cancel</transactionType>
            <total>11400</total>
            <cgUid>118372223</cgUid>
            <cardMask>411111******1111</cardMask>
            <authNumber>7823673</authNumber>
            <!-- Additional transaction details -->
        </refundDeal>
    </response>
</ashrait>
```

**Key Response Fields**:

* `result`: `000` indicates successful refund
* `tranId`: New transaction ID for the refund/cancellation
* `transactionType`: Shows transaction type (Cancel for non-transmitted, Refund for transmitted)
* `total`: Amount that was refunded
* `cgUid`: Links back to original transaction

### Error response

Error responses include specific error codes and messages. The response contains many fields, most of which will be empty for error cases. The key fields to focus on are `result`, `message`, `userMessage`, `status`, and `statusText`:

````xml
<?xml version='1.0'?>
<ashrait>
    <response>
        <command>refundDeal</command>
        <dateTime>2025-08-20 10:19</dateTime>
        <requestId />
        <tranId>119576079</tranId>
        <result>321</result>
        <message>The refund amount is large/small than the charge amount</message>
        <userMessage>The refund amount is large/small than the charge amount amount is different than the charge deal amount</userMessage>
        <additionalInfo>Refund above limit</additionalInfo>
        <version>2000</version>
        <language>Eng</language>
        <refundDeal>
            <status>321</status>
            <statusText>The refund amount is large/small than the charge amount</statusText>
            <extendedStatus />
            <extendedStatusText />
            <extendedUserMessage />
            <terminalNumber>0882804010</terminalNumber>
            <cardBin />
            <cardMask />
            <cardLength>0</cardLength>
            <cardNo />
            <cardName />
            <cardExpiration />
            <cardType code="" />
            <extendedCardType code="" />
            <creditCompany code="" />
            <cardBrand code="" />
            <cardAcquirer code="" />
            <serviceCode />
            <transactionType code="" />
            <creditType code="" />
            <currency code="" />
            <baseCurrency />
            <baseAmount />
            <transactionCode code="" />
            <total />
            <firstPayment />
            <periodicalPayment />
            <numberOfPayments />
            <clubId />
            <validation code="" />
            <idStatus code="" />
            <cvvStatus code="" />
            <authSource code="" />
            <authNumber />
            <fileNumber />
            <slaveTerminalNumber />
            <slaveTerminalSequence />
            <eci />
            <clientIp />
            <email />
            <cavv code="" />
            <user />
            <addonData />
            <supplierNumber />
            <id />
            <shiftId1 />
            <shiftId2 />
            <shiftId3 />
            <shiftTxnDate />
            <cgUid />
            <cardHash />
            <ashraitEmvData>
                <mti>100</mti>
            </ashraitEmvData>
            <extendedTranCode />
            <sendNotification />
        </refundDeal>
    </response>
</ashrait>
```<div data-gb-custom-block data-tag="hint" data-style='info'>**Note**: Error responses include the full structure with many empty fields. Focus on the `result`, `status`, and message fields for error handling.</div>## Code examples<div data-gb-custom-block data-tag="tabs"><div data-gb-custom-block data-tag="tab" data-title='cURL'>```bash
#!/bin/bash

# Example 1: Full refund using tranId
curl -X POST https://your-hyp-environment-url/xpo/Relay \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "user=your_username" \
  -d "password=your_password" \
  -d "int_in=$(cat <<'EOF'
<ashrait>
    <request>
        <version>2000</version>
        <language>ENG</language>
        <requestId/>
        <command>refundDeal</command>
        <refundDeal>
            <tranId>118372223</tranId>
        </refundDeal>
    </request>
</ashrait>
EOF
)"

# Example 2: Partial refund using cgUid with optional terminalNumber
curl -X POST https://your-hyp-environment-url/xpo/Relay \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "user=your_username" \
  -d "password=your_password" \
  -d "int_in=$(cat <<'EOF'
<ashrait>
    <request>
        <version>2000</version>
        <language>ENG</language>
        <requestId/>
        <command>refundDeal</command>
        <refundDeal>
            <cgUid>118372223</cgUid>
            <terminalNumber>0882819014</terminalNumber>
            <total>5000</total>
        </refundDeal>
    </request>
</ashrait>
EOF
)"
```</div><div data-gb-custom-block data-tag="tab" data-title='Java'>```java
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;

public class RefundDealExample {
    
    public static class RefundResult {
        public boolean success;
        public String tranId;
        public String amount;
        public String transactionType;
        public String error;
    }
    
    public static RefundResult processRefund(String terminalNumber, String cgUid, String refundAmount) throws IOException {
        String serverUrl = "https://your-hyp-environment-url/xpo/Relay";
        String username = "your_username";
        String password = "your_password";
        
        RefundResult result = new RefundResult();
        
        // Build XML payload
        StringBuilder xmlPayload = new StringBuilder();
        xmlPayload.append("<ashrait>")
                  .append("<request>")
                  .append("<version>2000</version>")
                  .append("<language>Eng</language>")
                  .append("<dateTime/>")
                  .append("<requestId/>")
                  .append("<command>refundDeal</command>")
                  .append("<refundDeal>")
                  .append("<cgUid>").append(cgUid).append("</cgUid>");
        
        // Optional: add terminal number if provided
        if (terminalNumber != null && !terminalNumber.isEmpty()) {
            xmlPayload.append("<terminalNumber>").append(terminalNumber).append("</terminalNumber>");
        }
        
        if (refundAmount != null && !refundAmount.isEmpty()) {
            xmlPayload.append("<total>").append(refundAmount).append("</total>");
        }
        
        xmlPayload.append("</refundDeal>")
                  .append("</request>")
                  .append("</ashrait>");
        
        // Build POST data
        String postData = "user=" + URLEncoder.encode(username, StandardCharsets.UTF_8) +
                         "&password=" + URLEncoder.encode(password, StandardCharsets.UTF_8) +
                         "&int_in=" + URLEncoder.encode(xmlPayload.toString(), StandardCharsets.UTF_8);
        
        // Send request
        URL url = new URL(serverUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        connection.setDoOutput(true);
        
        try (OutputStream os = connection.getOutputStream()) {
            os.write(postData.getBytes(StandardCharsets.UTF_8));
        }
        
        // Read response
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(connection.getInputStream()))) {
            String line;
            StringBuilder response = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            
            // Parse response (simplified - use proper XML parser in production)
            String responseText = response.toString();
            if (responseText.contains("<result>000</result>")) {
                result.success = true;
                // Extract key fields (use proper XML parsing in production)
                result.tranId = extractValue(responseText, "tranId");
                result.amount = extractValue(responseText, "total");
                result.transactionType = extractValue(responseText, "transactionType");
            } else {
                result.success = false;
                result.error = extractValue(responseText, "userMessage");
            }
        }
        
        return result;
    }
    
    private static String extractValue(String xml, String tagName) {
        String startTag = "<" + tagName + ">";
        String endTag = "</" + tagName + ">";
        int start = xml.indexOf(startTag);
        if (start != -1) {
            start += startTag.length();
            int end = xml.indexOf(endTag, start);
            if (end != -1) {
                return xml.substring(start, end);
            }
        }
        return "";
    }
    
    public static void main(String[] args) throws IOException {
        // Full refund example (terminal number is optional, pass null if not needed)
        RefundResult result = processRefund(null, "118372223", null);
        
        if (result.success) {
            System.out.println("Refund successful!");
            System.out.println("New Transaction ID: " + result.tranId);
            System.out.println("Amount: " + result.amount);
            System.out.println("Type: " + result.transactionType);
        } else {
            System.out.println("Refund failed: " + result.error);
        }
    }
}
```</div><div data-gb-custom-block data-tag="tab" data-title='Python'>```python
import requests
from urllib.parse import urlencode
from xml.etree import ElementTree as ET

def process_refund(cg_uid, terminal_number=None, refund_amount=None):
    """Process a refund using CG identifier"""
    
    server_url = "https://your-hyp-environment-url/xpo/Relay"
    username = "your_username"
    password = "your_password"
    
    # Build XML payload
    xml_payload = f"""
    <ashrait>
        <request>
            <version>2000</version>
            <language>ENG</language>
                <requestId/>
            <command>refundDeal</command>
            <refundDeal>
                <cgUid>{cg_uid}</cgUid>
                {f'<terminalNumber>{terminal_number}</terminalNumber>' if terminal_number else ''}
                {'<total>' + str(refund_amount) + '</total>' if refund_amount else ''}
            </refundDeal>
        </request>
    </ashrait>
    """
    
    # Prepare POST data
    post_data = {
        'user': username,
        'password': password,
        'int_in': xml_payload.strip()
    }
    
    try:
        # Send request
        response = requests.post(
            server_url,
            data=post_data,
            headers={'Content-Type': 'application/x-www-form-urlencoded'},
            timeout=30
        )
        
        response.raise_for_status()
        
        # Parse XML response
        root = ET.fromstring(response.text)
        result_code = root.find('.//result').text
        
        if result_code == '000':
            return {
                'success': True,
                'tran_id': root.find('.//tranId').text,
                'amount': root.find('.//refundDeal/total').text,
                'transaction_type': root.find('.//refundDeal/transactionType').text,
                'message': root.find('.//userMessage').text
            }
        else:
            return {
                'success': False,
                'error_code': result_code,
                'error': root.find('.//userMessage').text
            }
            
    except requests.exceptions.RequestException as e:
        return {
            'success': False,
            'error': f"Request failed: {e}"
        }
    except ET.ParseError as e:
        return {
            'success': False,
            'error': f"XML parsing failed: {e}"
        }

# Example usage
if __name__ == "__main__":
    # Full refund example (terminal number is optional)
    result = process_refund("118372223", terminal_number="0882819014")
    
    if result['success']:
        print("Refund successful!")
        print(f"New Transaction ID: {result['tran_id']}")
        print(f"Amount: {result['amount']}")
        print(f"Type: {result['transaction_type']}")
    else:
        print(f"Refund failed: {result['error']}")
    
    # Partial refund example without terminal number
    partial_result = process_refund("118372223", refund_amount="5000")
    
    if partial_result['success']:
        print("Partial refund successful!")
        print(f"Refunded amount: {partial_result['amount']}")
    else:
        print(f"Partial refund failed: {partial_result['error']}")
```</div><div data-gb-custom-block data-tag="tab" data-title='Node.js'>```javascript
const https = require('https');
const querystring = require('querystring');
const { parseStringPromise } = require('xml2js');

function processRefund(cgUid, terminalNumber = null, refundAmount = null) {
    return new Promise((resolve, reject) => {
        const serverUrl = 'https://your-hyp-environment-url/xpo/Relay';
        const username = 'your_username';
        const password = 'your_password';
        
        // Build XML payload
        const totalElement = refundAmount ? `<total>${refundAmount}</total>` : '';
        const xmlPayload = `
        <ashrait>
            <request>
                <version>2000</version>
                <language>ENG</language>
                        <requestId/>
                <command>refundDeal</command>
                <refundDeal>
                    <cgUid>${cgUid}</cgUid>
                    ${terminalNumber ? `<terminalNumber>${terminalNumber}</terminalNumber>` : ''}
                    ${totalElement}
                </refundDeal>
            </request>
        </ashrait>
        `;
        
        // Prepare POST data
        const postData = querystring.stringify({
            user: username,
            password: password,
            int_in: xmlPayload.trim()
        });
        
        const options = {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Content-Length': Buffer.byteLength(postData)
            }
        };
        
        const req = https.request(serverUrl, options, async (res) => {
            let responseData = '';
            
            res.on('data', (chunk) => {
                responseData += chunk;
            });
            
            res.on('end', async () => {
                try {
                    if (res.statusCode === 200) {
                        // Parse XML response
                        const result = await parseStringPromise(responseData);
                        const response = result.ashrait.response[0];
                        const resultCode = response.result[0];
                        
                        if (resultCode === '000') {
                            const refundData = response.refundDeal[0];
                            resolve({
                                success: true,
                                tranId: response.tranId[0],
                                amount: refundData.total[0],
                                transactionType: refundData.transactionType[0]['_'] || refundData.transactionType[0],
                                message: response.userMessage[0]
                            });
                        } else {
                            resolve({
                                success: false,
                                errorCode: resultCode,
                                error: response.userMessage[0]
                            });
                        }
                    } else {
                        reject(new Error(`HTTP ${res.statusCode}: ${responseData}`));
                    }
                } catch (parseError) {
                    reject(new Error(`XML parsing failed: ${parseError.message}`));
                }
            });
        });
        
        req.on('error', (error) => {
            reject(error);
        });
        
        req.write(postData);
        req.end();
    });
}

// Example usage
async function example() {
    try {
        // Full refund example (terminal number is optional)
        const result = await processRefund('118372223', '0882819014');
        
        if (result.success) {
            console.log('Refund successful!');
            console.log(`New Transaction ID: ${result.tranId}`);
            console.log(`Amount: ${result.amount}`);
            console.log(`Type: ${result.transactionType}`);
        } else {
            console.log(`Refund failed: ${result.error}`);
        }
        
        // Partial refund example without terminal number
        const partialResult = await processRefund('118372223', null, '5000');
        
        if (partialResult.success) {
            console.log('Partial refund successful!');
            console.log(`Refunded amount: ${partialResult.amount}`);
        } else {
            console.log(`Partial refund failed: ${partialResult.error}`);
        }
        
    } catch (error) {
        console.error('Operation failed:', error.message);
    }
}

example();
```</div></div>

## Error codes

| Error Code | Description | Resolution |
|------------|-------------|------------|
| **310** | No debit deal matches the credit deal | Verify lookup parameters match an existing transaction |
| **317** | Missing required parameters | Ensure at least one lookup element is provided |
| **320** | Credit transaction already performed | Transaction already has a refund; cannot refund again |
| **321** | Credit amount differs from charge deal amount | Check refund amount against original transaction |
| **324** | Terminal not permitted to perform refund transactions | [Contact support](mailto:cg-support@hyp.co.il) to enable refund permissions |
| **332** | Multiple transactions found | Use more specific lookup criteria or configure terminal settings |
| **339** | Refund credit type differs from original transaction | Ensure `creditType` matches original transaction |
| **340** | Refund number of payments differs from original transaction | Verify installment configuration |
| **341** | Refund amount differs from original transaction | Check amount validation settings |

## Related commands

- **[`doDeal`](doDeal.md)** - Process original payment transactions that can later be refunded
- **[`cancelDeal`](cancelDeal.md)** - Cancel non-transmitted transactions (refundDeal automatically chooses this when appropriate)
- **[`refundCgInvoice`](../documents-and-invoicing/refund-invoices.md)** - Process invoice-specific refunds with document generation
- **[Request Structure](../introduction/request-and-response-general-structure.md)** - General API request format
- **[Refunds & Cancellations](../additional-payment-scenarios/refunds-and-cancellations.md)** - Detailed guide on refund vs cancellation logic and installment handling
````


---

# 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://developers.hyp.co.il/creditguard/api-reference/refunddeal.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.
