Send a new invoice data from Books to local certified solution via API json due local compliance

Send a new invoice data from Books to local certified solution via API json due local compliance

Greetings,  
I hope you are doing well and staying safe.  

Due to local compliance regulations, I am required to issue invoices exclusively using locally certified software, which Zoho Books is not. However, we would like to continue using Zoho Books, so we need to send invoice data to an external certified solution each time a new invoice is issued. This external system should automatically generate a corresponding invoice, essentially mirroring the one created in Zoho Books.  

I have access to the API documentation for the external certified solution and have attempted to create a custom function to extract invoice data, format it in JSON, and send it to the external system. However, due to my limited knowledge, I have been unable to save the custom function successfully, as the Deluge editor consistently flags syntax errors.  

The API documentation for the external solution can be found here: https://api.factplus.co.ao/documentation/  

Below are some of the approaches I have attempted:  

===
void EnviarFctraParaFctpls( Map invoice, Map organization, Map user )
{
    // A função já recebe os detalhes da fatura e organização como 'invoice' e 'organization'
    // Não precisamos usar zoho.books.getRecordsByID para os dados básicos da fatura.
    // Usaremos 'invoice' diretamente.

    // 1. Extrair Detalhes da Fatura (diretamente do 'invoice' Map)
    invoiceData = invoice; // 'invoice' já é o mapa com os dados da fatura
    organizationId = organization.get("organization_id"); // ID da sua organização no Zoho Books

    invoiceNumber = invoiceData.get("invoice_number");
    invoiceDate = invoiceData.get("date"); // Formato 'YYYY-MM-DD'
    dueDate = invoiceData.get("due_date"); // Formato 'YYYY-MM-DD'
    reference = invoiceData.get("reference_number"); // Pode usar o número de referência do Zoho Books
    currency = invoiceData.get("currency_code");
    // observation = invoiceData.get("notes"); // Supondo que 'notes' seja para observações
    
    // ATENÇÃO: Verifique na documentação do Factplus como lidar com 'retention'.
    // Se o Zoho Books não tiver um campo direto para 'retention', você pode precisar de lógica extra
    // ou definir como "0" se não for aplicável no seu caso.
    retention_value = "0"; 
    
    // Dados do Cliente
    customerData = invoiceData.get("customer_details");
    clientName = customerData.get("customer_name");
    clientNIF = customerData.get("vat_reg_no"); // Assumindo que NIF seja o VAT Registration Number
    clientEmail = customerData.get("email");
    clientCity = customerData.get("city");
    clientAddress = customerData.get("billing_address").get("address"); // Endereço de fatura
    clientPostalCode = customerData.get("billing_address").get("zip"); // CEP de fatura
    clientCountry = customerData.get("billing_address").get("country"); // País de fatura

    // Itens da Fatura
    lineItems = invoiceData.get("line_items");
    factplusItems = collection(); // Coleção para armazenar os itens formatados para o Factplus

    for each item in lineItems
    {
        // Para itemcode, é ideal usar um ID que seja único e identificável no Factplus.
        // item.get("item_id") é o ID interno do Zoho Books, o que pode não ser ideal se o Factplus
        // espera um código de item de produto/serviço. Considere usar item.get("name") ou um campo personalizado.
        itemCode = item.get("item_id"); 
        description = item.get("description");
        price = item.get("rate");
        quantity = item.get("quantity");
        taxRate = item.get("tax_percentage"); // Taxa de imposto
        discount = item.get("discount"); // Desconto por linha de item
        
        // ATENÇÃO: exemption_code e retention por item precisam ser verificados na API do Factplus.
        exemptionCode = ""; // Valor padrão, ajuste se tiver campo correspondente
        itemRetention = "0"; // Valor padrão, ajuste se tiver campo correspondente

        factplusItem = Map();
        factplusItem.put("itemcode", itemCode);
        factplusItem.put("description", description);
        factplusItem.put("price", price);
        factplusItem.put("quantity", quantity);
        factplusItem.put("tax", taxRate);
        factplusItem.put("discount", discount);
        factplusItem.put("exemption_code", exemptionCode);
        factplusItem.put("retention", itemRetention);
        
        factplusItems.add(factplusItem);
    }
    
    // 2. Construir o Objeto JSON para a API do Factplus
    // ATENÇÃO: SUBSTITUA 'SUA_CHAVE_API_AQUI' PELA SUA CHAVE DE 32 DÍGITOS DO FACTPLUS
    factplusPayload = Map();
    factplusPayload.put("apicall", "CREATE");
    factplusPayload.put("apikey", "SUA_CHAVE_API_AQUI"); // <-- SUA CHAVE API DO FACTPLUS AQUI!

    documentMap = Map();
    documentMap.put("type", "factura"); // Tipo de documento, confirme se "factura" é o correto
    documentMap.put("date", invoiceDate);
    documentMap.put("duedate", dueDate);
    documentMap.put("vref", invoiceNumber); // Usando o número da fatura como referência. Verifique se o Factplus aceita este formato.
    // A "serie" é crucial. O exemplo do Factplus mostra "2020". Você precisa definir uma série apropriada.
    // Se o Zoho Books não tiver um campo para série, pode ser um valor fixo ou derivado.
    documentMap.put("serie", "2024"); // <-- ATENÇÃO: Defina a série correta para o Factplus (ex: "2024", "FS_A")
    documentMap.put("currency", currency);
    documentMap.put("exchange_rate", "0"); // Ajuste se houver taxa de câmbio
    // documentMap.put("observation", invoiceData.get("notes")); // Se usar campo de notas
    documentMap.put("retention", retention_value);

    clientMap = Map();
    clientMap.put("name", clientName);
    clientMap.put("nif", clientNIF);
    clientMap.put("email", clientEmail);
    clientMap.put("city", clientCity);
    clientMap.put("address", clientAddress);
    clientMap.put("postalcode", clientPostalCode);
    clientMap.put("country", clientCountry);
    
    factplusPayload.put("document", documentMap);
    factplusPayload.put("client", clientMap);
    factplusPayload.put("items", factplusItems);

    // Converter o mapa Deluge para string JSON
    jsonString = factplusPayload.toString();

    // 3. Fazer a Chamada HTTP POST para a API do Factplus
    // ATENÇÃO: Você PRECISA substituir "https://api.factplus.co.ao" pelo ENDPOINT COMPLETO
    // da API do Factplus para a criação de faturas.
    // Ex: "https://api.factplus.co.ao/v1/invoices" ou similar.
    factplusAPI_URL = "https://api.factplus.co.ao"; // <-- SUBSTITUIR PELO ENDPOINT ESPECÍFICO DE CRIAÇÃO DE FATURA

    // Cabeçalhos (Content-Type é essencial para JSON)
    headers = Map();
    headers.put("Content-Type", "application/json");

    // Executar a chamada API
    apiResponse = invokeurl
    [
        url : factplusAPI_URL
        type : POST
        headers: headers
        content : jsonString
    ];

    // 4. Tratar a Resposta da API
    info "Request sent to Factplus: " + jsonString; // Para depuração, mostre o que foi enviado
    info "Factplus API Response: " + apiResponse;

    // Adicione lógica para verificar a resposta aqui.
    // Ex: if (apiResponse.get("status") == "success") { ... }
    // ou if (apiResponse.get("code") == 200) { ... }
    // Logar erros se a resposta indicar falha e talvez enviar um email de alerta.
    if (apiResponse.get("status") == "success") // Supondo que a API retorne um campo 'status'
    {
        info "Fatura enviada com sucesso para o Factplus!";
        // Opcional: Atualizar a fatura no Zoho Books com um campo de status "Enviado para Factplus"
        // Ou armazenar o ID de retorno do Factplus.
    }
    else
    {
        error "Erro ao enviar fatura para o Factplus: " + apiResponse.get("message"); // Supondo campo 'message'
        // Opcional: Enviar email de erro para o cliente ou para o administrador
    }
}
===

And

===
// Função para enviar fatura do Zoho Books para o Factplus
// Parâmetro: invoice_id (ID da fatura criada)
invoice_id = input.invoice_id;

// Obter detalhes da fatura do Zoho Books
invoice = zoho.books.getRecordsByID("Invoices", organization_id, invoice_id);
invoice_data = invoice.get("invoice");

// Mapear dados do cliente
customer_id = invoice_data.get("customer_id");
customer = zoho.books.getRecordsByID("Contacts", organization_id, customer_id);
customer_data = customer.get("contact");
client_map = Map();
client_map.put("name", customer_data.get("contact_name"));
client_map.put("nif", customer_data.get("tax_reg_no", ""));
client_map.put("email", customer_data.get("email", ""));
client_map.put("city", customer_data.get("billing_address").get("city", ""));
client_map.put("address", customer_data.get("billing_address").get("address", ""));
client_map.put("postalcode", customer_data.get("billing_address").get("zip", ""));
client_map.put("country", customer_data.get("billing_address").get("country", "Angola"));

// Mapear itens da fatura
items_list = List();
for each item in invoice_data.get("line_items")
{
    item_map = Map();
    item_map.put("itemcode", item.get("item_id", "ITEM" + item.get("line_item_id")));
    item_map.put("description", item.get("name"));
    item_map.put("price", item.get("rate").toString());
    item_map.put("quantity", item.get("quantity").toString());
    item_map.put("tax", "14"); // Ajuste conforme a tributação aplicável
    item_map.put("discount", item.get("discount", "0").toString());
    item_map.put("exemption_code", "");
    item_map.put("retention", "");
    item_map.put("unit", "Unidade");
    items_list.add(item_map);
}

// Construir o corpo da requisição para o Factplus
payload = Map();
payload.put("apicall", "CREATE");
payload.put("apikey", "SUA_CHAVE_API_FACTPLUS"); // Substitua pela sua chave de API
document_map = Map();
document_map.put("type", "factura");
document_map.put("date", invoice_data.get("date"));
document_map.put("duedate", invoice_data.get("due_date"));
document_map.put("vref", invoice_data.get("invoice_number"));
document_map.put("serie", invoice_data.get("date").left(4)); // Ano da fatura
document_map.put("currency", "AOA");
document_map.put("exchange_rate", "0");
document_map.put("observation", "");
document_map.put("retention", "0");
payload.put("document", document_map);
payload.put("client", client_map);
payload.put("items", items_list);

// Enviar requisição para o Factplus
headers = Map();
headers.put("Content-Type", "application/json");
response = invokeurl
[
    type: POST,
    parameters: payload.toString(),
    headers: headers,
    connection: "FactplusAPI"
];

// Logar a resposta para depuração
info response;
===

Any help?
Thanks in advance.
    • Recent Topics

    • Is there any way to send an Excel received by email to Dataprep?

      Every day I receive an email alert with an Excel file that I want to process through a Dataprep pipeline. To do this, I need to: -Save the file to disk -Open the pipeline -Run the pipeline -Update the source -Several clicks to select and open the saved
    • Bin Locations

      Dear all, I am wondering if someone has the ability to develop the bin locations option for zoho inventory (integrated with zoho books) Regards, Ryan
    • Create and populate a record in an instant: Introducing zero-shot field prompting to Zia's ICR

      A couple of months ago, we upgraded our in-house AI image detection and validation tool, Zia Vision, with intelligent character recognition (ICR). By training Zia with sample images, you could create and enrich CRM records with data extracted from standard
    • How to Prevent Users From Skipping LMS Videos in Zoho People

      How to Prevent Users From Skipping LMS Videos in Zoho People Hello Zoho Developers, In this blog, we will quickly look at how you can stop users from skipping or fast-forwarding videos in Zoho People LMS. Zoho People provides a feature called Disable
    • Sent mail sort by date disappeared

      Hello, We used to be able to sort the emails by date in the sent folder, but this feature has recently disappeared. Can we bring it back?
    • [Integration Edition] Deluge Learning Series – Custom API with Deluge | November 2025

      We’re excited to conclude this four-month Integration Edition of the Deluge Learning Series: Session 1 – Integrating Zoho Apps with Deluge Using Built-In Integration Tasks Session 2 – Integrating Zoho Apps with Deluge Using invokeURL and invokeAPI Session
    • Automate Backups

      This is a feature request. Consider adding an auto backup feature. Where when you turn it on, it will auto backup on the 15-day schedule. For additional consideration, allow for the export of module data via API calls. Thank you for your consideration.
    • Tips for Organizing Workflows and Improving Team Coordination in Zoho

      Hi everyone, I’m looking for some general advice on how different teams are organizing their daily work within Zoho’s apps. Our team recently expanded, and we’re trying to streamline how tasks, discussions, and documents are shared so everything stays
    • Prevent user from viewing all records?

      I have a report that is meant to be used by vendors to view only the records that are assigned to them. All the vendor information is stored in a separate application, so I need to call a function to get the current user's ID (not the zoho user ID). The report settings criteria doesn't support using function calls, so instead I'm embedding the report in an html page like this: if (thisapp.Global.CurrentUserIs("Vendor")) {       personID = common.getLoggedInPersonID();       query = "Assigned_Vendor.ID="
    • Zoho Site pages not displaying in iframes

      I simply want to show a Zoho Site page inside an iframe on another non Zoho website. When testing this across many browsers, the iframe content simply does not appear. IE reports that the host does not allow their content to be displayed in iframes. Very disappointing. Is there a way around this please? Here is the URL of the page I would like to appear in an iframe. http://ips-properties-to-rent.zohosites.com
    • Zoho Inventory as connector in Zoho Creator

      Hello, It doesn't appear that Zoho Inventory is one of the many built in connectors in Zoho Creator? I see that there are non-Zoho inventory applications that have built in connectors such as Cin7, which leads me to believe that I'm missing something
    • Send Zoho Forms Link using Zoho CRM Email Templates

      I have set up Zoho Forms and CRM integration to pre-populate data from Zoho CRM to Zoho Forms. The setup is working fine. I have also created an email template in the Zoho CRM deals module to send Zoho forms links. So when I send an email using that template
    • My go to On Load Client Script - Fast, efficient, and works for ALL profiles; Hides everything except initial fields

      This is my on Load client script that I use for Create pages. I use a modified version for Edit and Display pages which you can create yourself using the same basic structure that I will give you below. First up, the script. Below that will be an explanation
    • CRM x WorkDrive: File storage for new CRM signups is now powered by WorkDrive

      Availability Editions: All DCs: All Release plan: Released for new signups in all DCs. It will be enabled for existing users in a phased manner in the upcoming months. Help documentation: Documents in Zoho CRM Manage folders in Documents tab Manage files
    • Zoho Books Finance Modules Not Accessible in Zoho CRM Mobile App

      We have integrated Zoho CRM with Zoho Books using the Zoho Finance Suite integration. In the CRM web version, we can see the Finance modules (Estimates/Quotes, Invoices, Sales Orders, Items, Payments) and are able to create invoices and quotes directly
    • Custom Search using HTM+CSS Snippet

      Suppose I wanted to create my own list view using HTML and CSS snippets inside a Page with a custom search input at the top of the list (not the Search snippet). Without Javascript, is there a way to retrieve a user's entry from that search input and
    • Cliq iOS can't see shared screen

      Hello, I had this morning a video call with a colleague. She is using Cliq Desktop MacOS and wanted to share her screen with me. I'm on iPad. I noticed, while she shared her screen, I could only see her video, but not the shared screen... Does Cliq iOS is able to display shared screen, or is it somewhere else to be found ? Regards
    • Mass Update of Lookup Fields not possible

      Hello List I've created a custom field for Leads and Contacts 'Current Campaign'. This is very Handy as I can filter leads and then related them to a campaign. Everything ready, but then I realized that mass update doesn't work for lookup fields... a
    • Zoho CRM Kiosk Upload Files

      Hello all, We are trying out Kiosks at the moment to see where it can fit best in our business. We are still a bit off in the application but lets say we will sort this out. My question is the following - when I create a Kiosk I can add "File Upload"
    • Double opt-in notifications and customizable confirmation messages for your webforms

      Dear CRM Community, We are excited to announce a major upgrade to our Webforms feature. You can now customize the confirmation message shown to your users who double opt-in from your webform and also customize your confirmation emails when they submit
    • Has Anyone successfully integrated Zoho and Sage Intact?

      Hey all, We’re evaluating Zoho One + Sage Intacct and I’m trying to connect with anyone who has actually implemented the two together.Specifically, I’d love to know: -- Which functions you kept in Zoho vs. Intacct (e.g., Product Catalog, AR/AP, invoicing,
    • Introducing Image Upload Field

      Hello everyone, In this post we will discuss about the benefits and usage of the Image upload field. The field is available for standard and custom modules.  Usage: This field can be used to upload a gallery of images to a record and share the record with peers or customers. The record can be made accessible to users outside of Zoho CRM via Portals, where they can upload the necessary images. Preview, editing, and deleting images: The uploaded images can be directly edited and saved from the record
    • Trigger a Workflow Function if an Attachment (Related List) has been added

      Hello, I have a Case Module with a related list which is Attachment. I want to trigger a workflow if I added an attachment. I've seen some topics about this in zoho community that was posted few months ago and based on the answers, there is no trigger
    • Free webinar alert on November 19 - Email driven strategies - Master personality based styles

      Hello Zoho Community! Want to make email management easier, smarter, and more you? We’ve got just the session for you! Join our interactive, game-based webinar to discover how Zoho Mail adapts to your personality and work style. Learn practical hacks,
    • Subform edits don't appear in parent record timeline?

      Is it possible to have subform edits (like add row/delete row) appear in the Timeline for parent records? A user can edit a record, only edit the subform, and it doesn't appear in the timeline. Is there a workaround or way that we can show when a user
    • AI generated meeting notes associated to Account or Deal

      As our organization works to improve efficiency we are looking for a solution to leverage AI to generate meeting notes and then add those notes to a CRM record such as an Account or Deal. I see Zoho has a Notebook AI offering that talks about the ability
    • due date on cheue

      how to handle cheque in zoho books for customers and vendors including due date
    • Zoho CRM Portal Field Level Permission Issue

      Hi Support Team, I am using the Zoho CRM Portal and configuring field-level editing permissions. However, we are unable to restrict portal users from editing certain fields. We have created a portal and provided View and Edit (Shared Only) access for
    • WebDAV / FTP / SFTP protocols for syncing

      I believe the Zoho for Desktop app is built using a proprietary protocol. For the growing number of people using services such as odrive to sync multiple accounts from various providers (Google, Dropbox, Box, OneDrive, etc.) it would be really helpful if you implemented standard protocols such as WebDAV / FTP / SFTP so that alternative inc clients can be used.
    • 'Statement of Accounts does not exist' error received, when creating PO using api in Zoho Inventory

      Here is request json -- JSONString = { "date": "2019-09-24", "purchaseorder_number": "PO-6-1", "delivery_date": null, "delivery_org_address_id": 36221200000056XXX, "vendor_id": 362212000000564XXX, "attention": "Testing", "line_items": [{ "unit": "Pieces", "account_id": 36221200000003XXX, "quantity": 1, "item_id": 362212000000049XXX, "tax_type": "", "tax_name": "", "name": "One HD", "purchase_rate": 85, "tax_percentage": 0, "item_total": 85.00, "tax_id": "", "warehouse_id": 362212000000564XXX }] }
    • Zoho Projects API 100 requests/2 min. Limit

      Hi Requesting clarification on the API documentation. "You can invoke or call an API for 100 times in a span of two minutes. If you invoke more than 100 times, the particular API request will be locked for the next 30 minutes. " Does this limit apply
    • Unveiling Zoho Sites 2.0 - A new dimension in website building

      Dear Zoho Sites Users, We are thrilled to announce the launch of Zoho Sites 2.0 today! This refresh represents a significant step forward in the capabilities of Zoho Sites and is crucial for creating a lasting and positive impact on our customers' businesses.
    • Integrate your Outlook/ Office 365 inbox with Zoho CRM via Graph API

      Hello folks, In addition to the existing IMAP and POP options, you can now integrate your Outlook/Office 365 inbox with Zoho CRM via Graph API. Why did we add this option? Microsoft Graph API offers a single endpoint to access data from across Microsoft’s
    • Zoho Projects - Attachments added to Task and Bug emails are not saved

      Hi Projects team, I have been experimenting with emails into projects to create tasks and bugs. I have noticed that attachments added to the emails are not saved to the task or bug. Is this normal behaviour? Thanks, Ashley
    • Zoho Inventory's latest shipping integration updates at a glance.

      Hello Users, We would like to share some important news about our latest improvements in the Shipping integration capabilities of Zoho Inventory that we achieved in 2024 with some of our major integration partners in key editions across APAC, North America,
    • Sorting a list of record acquired from the zoho.crm.searchRecords function.

      This is something for which I'm trying to figure out a straightforward way to do. The searchRecords does a great job fetching me the records that I want. However, in some cases, where it returns multiple records, I want it to sort the returned list by date of creation of that record, so that when I do records.get(0), I get the most recent record.  As an example, here's my sample pseudo code: records = zoho.crm.searchRecords("Clients", "Office_Number:equals:123456"); Now the "records" list above contains
    • Zoho Inventory Custom Field Update

      Hello All, In this post I am describing how can we Update the Custom Field Value in Zoho Inventory. // Get Org ID orgid = organization.get("organization_id"); // Field Value resvp = ifnull(item.get("purchase_rate"),null); // Record ID iid = item.get("item_id");
    • Deprecation of the Zoho OAuth connector

      Hello everyone, At Zoho, we continuously evaluate our integrations to ensure they meet the highest standards of security, reliability, and compliance. As part of these ongoing efforts, we've made the decision to deprecate the Zoho OAuth default connector
    • Alphabetically

      How can i arrange alphabetically - (Manage Manufacturer) Field in Item Master 
    • Spotlight series #6: The Show app for Android TV has a new look!

      Hello everyone! We are delighted to introduce our revamped and redesigned Show app for Android TV.  Smart TVs are exploding in popularity. Android TV alone has over 110 million active monthly devices. Zoho Show, as part of a constant effort to improve
    • Next Page