๐Ÿ‡บ๐Ÿ‡ธ English ๐Ÿ‡ง๐Ÿ‡ฉ เฆฌเฆพเฆ‚เฆฒเฆพ ๐Ÿ‡ธ๐Ÿ‡ฆ ุงู„ุนุฑุจูŠุฉ ๐Ÿ‡ฎ๐Ÿ‡ณ เคนเคฟเค‚เคฆเฅ€

ZATCA Fatoora Portal Integration

Complete API Guide for Phase 2 E-Invoicing Compliance

Last updated: March 30, 2026

The **Fatoora portal** is ZATCA's (Zakat, Tax and Customs Authority) electronic invoicing platform. All taxpayers in Saudi Arabia must integrate their systems with Fatoora APIs for Phase 2 compliance. This comprehensive guide covers everything from authentication to production deployment.

๐Ÿ“‹ Prerequisites for Integration

๐Ÿ”— Fatoora API Endpoints

Endpoint NameEndpoint URLMethodDescription
Clearance (B2B) https://api.fatoora.zatca.gov.sa/api/v1/invoice/clearance POST Real-time validation for B2B invoices
Reporting (B2C) https://api.fatoora.zatca.gov.sa/api/v1/invoice/reporting POST 24-hour submission for B2C invoices
CSR Generation https://api.fatoora.zatca.gov.sa/api/v1/csr POST Generate Certificate Signing Request
Compliance Check https://sandbox.fatoora.zatca.gov.sa/api/v1/compliance POST Validate XML before submission

๐Ÿ” Authentication (OAuth 2.0)

Fatoora APIs use OAuth 2.0 with client credentials flow. After CSD certificate installation, you must obtain credentials from ZATCA portal:

Token endpoint: https://api.fatoora.zatca.gov.sa/oauth2/token

โš™๏ธ Step-by-Step Integration Process

โœ“ 1. Register in ZATCA Fatoora portal and obtain CSR (Certificate Signing Request)
โœ“ 2. Purchase and install CSD certificate from approved provider (5-10 business days)
โœ“ 3. Generate API credentials (client_id, client_secret) from ZATCA portal
โœ“ 4. Test all API calls in Sandbox environment before production
โœ“ 5. Implement XML invoice generation in UBL 2.1 format with all mandatory fields
โœ“ 6. Generate QR code with cryptographic stamp (TLV encoding + Base64)
โœ“ 7. Submit invoices via Clearance endpoint (B2B) or Reporting endpoint (B2C)
โœ“ 8. Handle ZATCA responses appropriately (cleared/rejected/reported status)
โœ“ 9. Implement webhook or callback URL for asynchronous responses
โœ“ 10. Move to production after successful sandbox testing

๐Ÿ’ป Sample API Call (PHP cURL)

Here is a complete PHP cURL example for submitting an invoice to the Clearance endpoint:

<?php // ZATCA Fatoora API - Clearance Invoice Submission $access_token = "YOUR_ACCESS_TOKEN"; $xml_invoice_data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Invoice>...</Invoice>"; $qr_base64 = "Base64EncodedQRDataHere"; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.fatoora.zatca.gov.sa/api/v1/invoice/clearance", CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_SSL_VERIFYPEER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer " . $access_token, "Content-Type: application/json", "Accept-Language: en" ], CURLOPT_POSTFIELDS => json_encode([ "invoice" => base64_encode($xml_invoice_data), "qr_code" => $qr_base64 ]) ]); $response = curl_exec($curl); $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); $curl_error = curl_error($curl); curl_close($curl); if ($http_code == 200) { $result = json_decode($response, true); echo "Invoice Status: " . $result["status"]; } else { echo "Error: HTTP $http_code - $curl_error"; } ?>

๐Ÿ“จ Understanding ZATCA API Responses

CLEARED

Invoice accepted by ZATCA. You can share it with buyer.

Action: Proceed with delivery

REJECTED

Invoice failed validation. Check XML structure and fields.

Action: Correct and resubmit new invoice

REPORTED

Invoice accepted for reporting (no real-time validation).

Action: No further action needed

PENDING

Invoice under review. Wait for final status.

Action: Implement webhook to receive update

โš ๏ธ Error Handling & Status Codes

HTTP CodeMeaningSolution
200Success - Invoice processed correctlyContinue normal flow
400Bad Request - Invalid XML format or missing mandatory fieldsValidate XML against UBL 2.1 schema
401Unauthorized - Authentication failedCheck access_token validity and regenerate if expired
403Forbidden - CSD certificate expired or invalidRenew CSD certificate immediately
429Rate Limit Exceeded - Too many requestsImplement exponential backoff and reduce request rate
500Internal Server Error - ZATCA server issueRetry with exponential backoff (max 3 attempts)
503Service Unavailable - Maintenance or overloadWait and retry after 5-10 minutes

๐Ÿงช Sandbox Environment (Testing)

Always test your integration in the ZATCA Sandbox before going live:

๐Ÿ”— https://sandbox.fatoora.zatca.gov.sa

โœ… Best Practices for Production

โ“ Frequently Asked Questions

Q: How long does API response take?

A: Clearance endpoint: 2-5 seconds (synchronous). Reporting endpoint: Response within seconds (asynchronous), but invoice status may update later via webhook or status check endpoint.

Q: What is the rate limit for Fatoora APIs?

A: Standard limit is 10 requests per second. For higher volumes (enterprise), contact ZATCA support to request increased limits. Implement queue system for bulk submissions.

Q: Can I use the same access token for multiple requests?

A: Yes, access tokens typically expire after 1 hour. Implement auto-refresh logic to obtain new token before expiry. Do not request new token for every request.

Q: What if my invoice is rejected?

A: You cannot edit a rejected invoice. You must correct the issue in your system and submit a brand new invoice with a new invoice number. Rejected invoices cannot be resubmitted.

Q: How do I get a test CSD certificate for sandbox?

A: ZATCA Sandbox provides test CSD certificates for free. You can generate them directly from the sandbox portal without purchasing from commercial providers.

Q: What is the difference between synchronous and asynchronous APIs?

A: Clearance is synchronous - you wait for immediate response. Reporting is asynchronous - you submit and receive acknowledgement, but final status comes later via webhook.

Q: Do I need static IP for Fatoora API?

A: No, static IP is not required. However, ensure your server's outbound IP is not blocked by ZATCA firewall. Use reliable hosting provider.

Q: What webhook URL format is accepted?

A: ZATCA accepts HTTPS endpoints only. URL must be publicly accessible. Use POST method to receive JSON payloads with invoice status updates.

๐Ÿ“š Related ZATCA Resources