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

        • SMTP email sending problem

          Hello, I've sent emails before, but you haven't responded. Please respond. My work is being disrupted. I can't send emails via SMTP. Initially, there were no problems, but now I'm constantly receiving 550 bounce errors. I can't use the service I paid
        • billing

          hi, I am being billed $12/year, and I can't remember why. My User ID is 691273115 Thanks for your help, --Kitty Pearl
        • Syncing Zoho Forms with Bigin - Embedding issue?

          Hello everyone, I created a Zoho Form for a page on my GoDaddy website to collect leads, which then transfers the data to Bigin. However, I'm facing an issue where it doesn't seem to work properly. I've integrated Zoho Forms with Bigin and tried embedding
        • How to add receipts

          How to add receipts
        • Unable to enable tax checkboxes

          Hi Zoho Commerce Support, I'm writing to report an issue I'm having with the tax settings in my Zoho Commerce store. I've created several tax rates under Settings > Taxes, but all of them appear with the checkbox disabled. When I try to enable a checkbox,
        • Does Zoho Learn integrate with Zoho Connect,People,Workdrive,Project,Desk?

          Can we propose Zoho LEarn as a centralised Knowledge Portal tool that can get synched with the other Zoho products and serve as a central Knowledge repository?
        • Zoho Commerce - Enable Company Name and Tax Number collection for B2B orders in Global Edition

          Please enable Company Name and Tax Details option on checkout settings in Zoho Commerce Global Edition. It is still important to collect Company Name and Tax Number for B2B sales in many countries. My business is based in Ireland (in the EU) and I have
        • Zoho CRM: how can I control which contacts to sync with Outlook?

          I was just playing around syncing contacts from Zoho to MS Outlook (MS365 account.) The problem is our firm has hundreds of thousands of contacts and I don't want to bury my contacts list in outlook. Any help with this is greatly appreciated.
        • ZohoSign and ZohoBooks Integration/Workflow

          Hello All, We utilize ZohoSign for signatures on tax eFiles. We utilize Dynamic KBA. Additionally, we use ZohoBooks for invoicing for these services. Is there a way to accomplish the following: Send a copy of the Tax Return, Invoice and eFiles in one
        • Manage monthly tasks with projectsf

          Hi All I run a finance and operations team where we need both teams to complete monthly tasks to ensure we hit our deadlines. Can Zoho projects be used for this. There many finance focused tools but we have Zoho one so want to explore Thanks Will
        • Zoho Suite is very slow

          Since today Zoho is incredibly slow over all applications! What's going on?
        • How can I track which zoho users are actively using Zoho CRM

          I have several licenses of Zoho CRM. We now need to add a new user. I could purchase a new license, but before I do, I would like to see if any of our existing users are not actively using the license assigned to them. How can I determine the activity
        • Is anyone else having trouble saving a custom image in their email signature, or is it just me?

          When I try to save the image I get an error that says "Operation Failed" I opened a support ticket two weeks ago and received a response that it would be debugged, but it still isn’t working
        • Combine and hide invoice lines

          In quickbooks we are able to create a invoice line that combines and hides invoices lines below. eg. Brochure design         $1000 (total of lines below, the client can see this line) Graphic Design           $600 (hidden but entered to reporting and
        • Option to Disable Knowledge Base Section in Feedback Widget Popup Hello Zoho Desk Team

          Hello Zoho Desk Team, How are you? We are actively using Zoho Desk and would like to make more use of the Feedback Widget. One of the ways we implement it is through the popup option. At the moment, the popup always displays the Knowledge Base section,
        • The Social Wall: August 2025

          Hello everyone, As summer ends, Zoho Social is gearing up for some exciting, bigger updates lined up for the months ahead. While those are in the works, we rolled out a few handy feature updates in August to keep your social media management running smoothly.
        • Change scheduling emails time

          When sending an individual email there is a great feature to schedule them to send later. I could only use the one time that is suggested. Is there a way to select another time? Regards, Glenn
        • Transaction Locking with the dynamic date

          Is it possible to dynamically update dates on transaction locking. We want to lock transaction x days from today
        • Zoho Devops

          We have a Zoho one account which we have integrated with an SAS educational product, sold on a subscription model, using webhooks and API calls. We make some use of custom fields and cross module lookups and relationships. We utilize CRM, Books and billing
        • Fuel up your sales with the Zoho SalesIQ + Bigin integration

          Hi everyone! We’re happy to bring you the all-new Zoho SalesIQ + Bigin integration. With this, every prospect from your website instantly becomes a contact in Bigin, complete with transcripts and follow-up tasks, so you never lose a lead again. Let's
        • Add a 'Log a Call' link to three dot icon in Canvas

          Hi, There's a three dot element when creating a canvas called 'More'. I would like to modify this to add a link that says 'Log a Call' in order to quickly record the details of a cellphone call. I'd also like this to be a simple 'contact' selection and
        • Introducing AI-powered Assessments & Zoho's native LLM, Zia

          We’ve shipped a cleaner, faster way to create assessments in Zoho Recruit. 🚀 Instead of manually building question banks or copying old templates, you can now generate ready-to-use assessments in just a few clicks, all tailored to the role you’re hiring
        • Ability to Reset Visitor Fields During an Active Chat Flow

          Hello Zoho SalesIQ Team, We hope you are doing well. We would like to propose a feature enhancement to Zoho SalesIQ regarding the management of visitor fields within Zobot flows. Use Case: Our bot asks the visitor to provide information about a 3rd person
        • External ID in Zoho CRM

          Hello everyone! We know that Zoho CRM allows you to integrate third-party apps and manipulate data through APIs. While you integrate a third-party application, you may want to store the third-party reference IDs in Zoho CRM's records. To meet this need
        • Some emails are not being delivered

          I have this problem where some of my mail just seems to disappear. When I send it, it appears as sent with no mention of any problem, but my recipient never gets it, not even in the Spam folder. Same for receiving, I have a secondary e-mail address, and
        • New in Zoho Chat : Search for contacts, files, links & conversations with the all new powerful 'Smart Search' bar.

          With the newly revamped 'Smart Search' bar in Zoho Chat, we have made your search for contacts, chats, files and links super quick and easy using Search Quantifiers.   Search for a contact or specific conversations using quantifiers, such as, from: @user_name - to find chats or channel conversations received from a specific user. to: @user_name - to find chats or channel conversations sent to a specific user. in: #channel_name - to find a particular instance in a channel. in: #chat_name - to find
        • Template modifiactions

          Hello, I am struggling with the templates in ZOHO Books. Especially with the placement of some items, like company address, ship to, bill to etc.  For example: One item I like from template X (placement of ship to and bill to next to each other in the
        • Aggregating the First Value in the Group By of a dataset

          Hi I am trying to get the following Aggregate Formula to work in my chart, but cannot seem to get the right format. I have a series of data that I am running an include_groupby and want to SUM only a column in the first row of each group. So for example.
        • Admin Control Over Profile Picture Visibility in Zoho One

          Hello Zoho Team, We hope you are doing well. Currently, as per Zoho’s design, each user can manage the visibility of their profile picture from their own Zoho Accounts page: accounts.zoho.com → Personal Information → Profile Picture → Profile Picture
        • Track Zoho Campaign and Workflow sales impact

          I am attempting to measure the performance of our marketing workflows and campaigns by comparing the date each campaign was sent to a contact with the purchase date of the contact. For example, if Contact A was sent Email A on 9/1 and made a purchase
        • Tables for Europe Datacenter customers?

          It's been over a year now for the launch of Zoho Tables - and still not available für EU DC customers. When will it be available?
        • What is a line break code for zoho?

          Hi, I am archiving data by adding values from a single line field from one form to a multi-line field in another form. So I need a code/function that starts a new line on that multi-line field so it does not just keep adding it on the same line. Example, doing something like this means that it will be on a same line. archive.field1 = archive.field1 + input.Field1 I need a code so the input.Field1 can just start on the next line. Instead of "value 1, 2,3,4,5" It will be: "1 2 3 4 etc.".  something
        • Automatic Project Owner change

          Is there a way to change Project Owner automatically once a specific Milestone in a project is marked as completed. Different Teams are working on projects in our Org, they have their own Milestones to complete and so we transfer the project from team
        • Button to add product to cart

          Is there a way to have a button on a page, that when clicked, will add Qty 1 of a product to the cart?
        • Problem with Submit Button Design

          I have made a template to apply to my forms and under the button controls, I have it set to "standard" and yet it's still filling the container. This is super frustrating and looks weird. Why do we not have full control over button size? How can I fix
        • Zoho CRM- Authorize your Microsoft Teams account issue

          Hi, I tried to link Zoho CRM with Teams and I got the following message: Clicking "Authorize now" sent me to the following page, Microsoft tried to start a session but, after 3 seconds the page closed and nothing happened. I get the same message each
        • Passing the CRM

          Hi, I am hoping someone can help. I have a zoho form that has a CRM lookup field. I was hoping to send this to my publicly to clients via a text message and the form then attaches the signed form back to the custom module. This work absolutely fine when
        • Is there a way to associate an email in ZOHO Main to a Vendor record in ZOHO CRM

          My situation is as below, I have a vendor in ZOHO CRM lets say "Vend A" and an associated contact, "Cont A" If Cont A sends me an email using the email I've registered in the contact record the standard OOTB email sync will work. But the vendor has some
        • Bank charges are applied. Please select a bank account.

          Hello, I'm trying to add bank charges to a customer payment, but I get the error message "Bank charges are applied. Please select a bank account." I found this old thread, where it says that I need to "select a Bank account for the 'Deposit To' dropdown
        • Kaizen #207 - Answering your Questions | Advanced Queries using COQL API

          Hi everyone, and welcome to another Kaizen week! As part of Kaizen #200 milestone, many of you shared topics you would like us to cover, and we have been addressing them one by one over the past few weeks. Today, we are picking up one of those requests
        • Next Page