Skip to main content
GET
https://www.xn--dkkango-n2a.com/api/integrations
/
orders
/
cancel-reasons
Get Cancel Reasons
curl --request GET \
  --url https://www.xn--dkkango-n2a.com/api/integrations/orders/cancel-reasons \
  --header 'Access-Token: <api-key>'
{
  "status": true,
  "data": [
    {
      "id": 123,
      "reason": "<string>"
    }
  ]
}

Overview

Returns the list of available cancellation reasons that can be used when canceling orders.

Headers

Access-Token
string
required
Your API access token

Response

status
boolean
true if successful
data
array
Array of cancellation reason objects

Examples

curl -X GET https://www.xn--dkkango-n2a.com/api/integrations/orders/cancel-reasons \
  -H 'Access-Token: your-access-token'

Success Response (200)

{
  "status": true,
  "data": [
    {
      "id": 1,
      "reason": "Ürün tükendi"
    },
    {
      "id": 2,
      "reason": "Adres bulunamıyor"
    },
    {
      "id": 3,
      "reason": "Yoğunluk nedeniyle"
    },
    {
      "id": 4,
      "reason": "Müşteri iptal etti"
    },
    {
      "id": 5,
      "reason": "Teknik sorun"
    },
    {
      "id": 6,
      "reason": "Çok uzak teslimat adresi"
    },
    {
      "id": 7,
      "reason": "Ödeme problemi"
    },
    {
      "id": 8,
      "reason": "Diğer"
    }
  ]
}

Error Response (401)

{
  "status": false,
  "error": "yetkisiz erişim"
}

Cancel Reasons Reference

IDReason (Turkish)English TranslationWhen to Use
1Ürün tükendiProduct out of stockIngredient unavailable
2Adres bulunamıyorAddress not foundInvalid/unclear address
3Yoğunluk nedeniyleDue to congestionRestaurant too busy
4Müşteri iptal ettiCustomer canceledCustomer requested
5Teknik sorunTechnical issueSystem/equipment failure
6Çok uzak teslimat adresiDelivery address too farOutside service area
7Ödeme problemiPayment problemPayment verification failed
8DiğerOtherAny other reason

Use Cases

Display reasons in dropdown menu for staff.
async function buildCancelDialog() {
  const reasons = await getCancelReasons();
  
  const dropdown = reasons.map(r => `
    <option value="${r.id}">${r.reason}</option>
  `).join('');
  
  return `
    <select id="cancelReason">
      ${dropdown}
    </select>
  `;
}
Cache reasons when POS starts.
async function initializePOS() {
  const reasons = await getCancelReasons();
  
  // Store in local cache
  localStorage.setItem('cancelReasons', 
    JSON.stringify(reasons));
  
  console.log('Cancel reasons cached');
}
Ensure valid reason before canceling.
function validateCancelReason(reasonId) {
  const reasons = getCachedReasons();
  const validIds = reasons.map(r => r.id);
  
  if (!validIds.includes(reasonId)) {
    throw new Error(`Invalid reason_id: ${reasonId}`);
  }
  
  return true;
}
Get reason text by ID.
function getReasonText(reasonId) {
  const reasons = getCachedReasons();
  const reason = reasons.find(r => r.id === reasonId);
  
  return reason ? reason.reason : 'Unknown';
}

// Usage
console.log(getReasonText(3)); // "Yoğunluk nedeniyle"

Integration Example

class CancelOrderDialog {
  async show(order) {
    // 1. Fetch reasons
    const reasons = await this.getCancelReasons();
    
    // 2. Show dialog with reasons
    const selectedReasonId = await this.showDialog(order, reasons);
    
    if (selectedReasonId) {
      // 3. Validate
      this.validateReason(selectedReasonId, reasons);
      
      // 4. Cancel order
      await this.cancelOrder(order.payment_key, selectedReasonId);
      
      // 5. Log cancellation
      await this.logCancellation({
        orderId: order.id,
        reasonId: selectedReasonId,
        reasonText: this.getReasonText(selectedReasonId, reasons),
        timestamp: new Date(),
        user: currentUser.id
      });
      
      // 6. Notify
      showSuccessMessage('Order canceled successfully');
    }
  }
  
  async showDialog(order, reasons) {
    return new Promise((resolve) => {
      const dialog = createDialog({
        title: `Cancel Order ${order.id}?`,
        content: `
          <p>Select cancellation reason:</p>
          <select id="reason-select">
            ${reasons.map(r => 
              `<option value="${r.id}">${r.reason}</option>`
            ).join('')}
          </select>
        `,
        buttons: [
          {
            text: 'Cancel Order',
            onClick: () => {
              const reasonId = document.getElementById('reason-select').value;
              resolve(parseInt(reasonId));
            }
          },
          {
            text: 'Keep Order',
            onClick: () => resolve(null)
          }
        ]
      });
      
      dialog.show();
    });
  }
}

Caching Strategy

Cancel reasons rarely change. Cache them locally to improve performance.
class CancelReasonsCache {
  constructor() {
    this.reasons = null;
    this.lastFetch = null;
    this.cacheDuration = 24 * 60 * 60 * 1000; // 24 hours
  }
  
  async getReasons() {
    const now = Date.now();
    
    // Return cached if recent
    if (this.reasons && (now - this.lastFetch) < this.cacheDuration) {
      return this.reasons;
    }
    
    // Fetch fresh
    const response = await fetch('/orders/cancel-reasons');
    const data = await response.json();
    this.reasons = data.data;
    this.lastFetch = now;
    
    return this.reasons;
  }
  
  invalidate() {
    this.reasons = null;
    this.lastFetch = null;
  }
  
  getById(id) {
    return this.reasons?.find(r => r.id === id);
  }
  
  getText(id) {
    return this.getById(id)?.reason || 'Unknown';
  }
}

// Usage
const reasonsCache = new CancelReasonsCache();

// Get all reasons
const reasons = await reasonsCache.getReasons();

// Get specific reason text
const reason = reasonsCache.getText(3); // "Yoğunluk nedeniyle"

Best Practices

// ✅ Good: Fetch reasons before showing dialog
async function cancelOrder(order) {
  const reasons = await getCancelReasons();
  const reasonId = await showCancelDialog(order, reasons);
  await cancelOrder(order.payment_key, reasonId);
}