Webhook for Payment Notification

With new regulations being introduced in Spain, we will need to integrate a notification system (via REST API) when a payment is made—this is called Verifactu. This system is already in place in some regions (the interested hub is located in a region where this system has already been implemented) and has been approved by the EU, meaning it will likely be adopted in other countries in the coming years.

To prepare for this, it would be highly practical to have a webhook trigger when a payment is made (or when an invoice is generated—open to discussion). This would allow us to execute a script or workflow (such as with n8n) to make the relevant API call.

The information required each time an order is paid would include the total price, items, and time of the transaction.

My question is whether this feature could be considered by the global community. If it is feasible, we may be able to allocate some budget to support its development.

Thank you for bringing this up.

This request is similar to another webhook that was requested:

The estimate there was 1.5 days dev time. The same applies here. For funding, we usually multiply this by a certain factor to account for review, testing, project management and contribution to maintenance. @Rachel, what’s that factor?

this is a complete stab in the dark but I would suggest a factor of x3

thanks @NickWeir !

@maikel I’m noticing you are talking about 1.5 days here but mentioned 1.5 hours on slack. Which is the good estimate?

@mikel I don’t think it’s a good move to rely on the invoice as current OFN invoices are made on the fly and are not stored (so can be created multiple times).

Can we get into more detail on the type of data needed? A few questions that came in for me:

  • what do you need when you mention “items”: name + unit + quantity sold?
  • what is the time of the transaction for you? time of payment or order completion date? If it is the time of payment, what is the expected behavior when the payment is made later in cash?
  • for price, do you need VAT breakdown?

thanks!

Oh dear, that’s a bad mistake. 1.5 days is the right one.

Hi @Rachel,

Here are the answers to your questions:

  • Yes, the information for the items includes description, quantity, price per unit, and VAT category.
  • The timing for the transaction should occur right after the payment is completed. I believe the transition from “balance due” to “paid” is the appropriate moment to trigger it, this should be adequate for all kind of payments. What do you think?
  • We do not need this, as we already have all the necessary information from the VAT category of the items.

I can share with you the json object that I need to generate if this would more clear

@mikel when dealing with cash payments, this change of payment state can occur very late in the process (only when payments are captured). Will this be a problem here?

I can share with you the json object that I need to generate if this would more clear

that’d be awesome yes :+1:

Hi @Rachel ,
Yes, you are right. When paying with cash, the timing can be delayed due to the nature of this type of payment. However, I don’t see any issue, as this is the moment when the transaction is expected to be reflected in the system and the info is ready to be submitted. Are you aware of any potential issues that I might be missing?

This is the JSON file we would need to provide. Let me know if you need any clarification:

{
“fecha”: “25/09/2024”,
“hora”: “12:45:00”,
“nif”: “XXXXXXXXX”,
“simplificada”: false,
“pais_cliente”: “ES”,
“nombre”: “My Coop”,
“direccion”: “Gasteiz”,
“cp”: “01013”,
“serie”: “A”,
“numero”: “00003”,
“rectificativa”: false,
“clave_rectificativa”: “R1”,
“tipo_rectificativa”: “I”,
“rectificadas”: [ ],
“tipo_operacion”: “servicios”,
“intracomunitaria”: false,
“exportacion”: false,
“retencion”: 0,
“lineas”: [
{
“descripcion”: “product1”,
“cantidad”: 1,
“importe_unitario”: 23.2,
“tipo_iva”: 0,
“tipo_req”: 0
},{
“descripcion”: “product2”,
“cantidad”: 2,
“importe_unitario”: 2,
“tipo_iva”: 0,
“tipo_req”: 0
}
],
“total_factura”: 27.2,
“zuzendu”: false
}

Thanks Mikel. I’m thinking about the balance between creating something useful for your purpose, and potentially useful for other purposes.

You mentioned that you would use this webhook to execute a script or workflow (such as with n8n) to make the relevant API call. So given that you will have the ability to transform the data I’m wondering if we can create a more general format for this webhook, using OFN terms that are more closely aligned with the code (eg enterprise_name instead of nombre). This way it would be more helpful when implementing the system in other countries.

Would that be ok with you?

Either way, to provide the quote we will need to have a clear understanding of what data is required. Can you please annotate your suggested JSON file to describe where the data for each line comes from? You can use OFN database column names, or screenshots from the web interface.

Thanks for the feedback. Here the annotated json. The * indicates the values that need to be sent from OFN:

{
“fecha”: “25/09/2024”, //date, basically today. Not required that it comes from the webhook, it can be done in script or n8n
“hora”: “12:45:00”, //time, basically time. Not required that it comes from the webhook, it can be done in script or n8n
“nif”: “XXXXXXXXX”, // * the business number, ABN in DB
“simplificada”: false, // not related to OFN
“pais_cliente”: “ES”, // that can be hardcoded in the script/n8n
“nombre”: “My Coop”, // * enterprise_name
“direccion”: “Gasteiz”, // * enterprise_address
“cp”: “01013”, // * enterprise_zip_code
“serie”: “A”, // Not required in the webhook. That can be generated in the script/n8n
“numero”: “00003”, // Not required in the webhook. That can be generated in the script/n8n
“rectificativa”: false, //Not required in the webhook.
“clave_rectificativa”: “R1”, //Not required in the webhook.
“tipo_rectificativa”: “I”, // Not required in the webhook.
“rectificadas”: , //Not required in the webhook.
“tipo_operacion”: “servicios”, //Not required in the webhook.
“intracomunitaria”: false, //Not required in the webhook.
“exportacion”: false, //Not required in the webhook.
“retencion”: 0, // Not required in the webhook.
“lineas”: [
{
“descripcion”: “product1”, // * product_name
“cantidad”: 1, // * quantity
“importe_unitario”: 23.2, // * price_per_unit
“tipo_iva”: 0, // * tax type
“tipo_req”: 0 // not applicable
},{
“descripcion”: “product2”, // * product_name
“cantidad”: 2, // * quantity
“importe_unitario”: 2, // * price_per_unit
“tipo_iva”: 0, // * tax_type
“tipo_req”: 0 // not applicable
}
],
“total_factura”: 27.2, // order_total_price to pay
“zuzendu”: false // not applicable
}

To make this webhook more versatile, I suggest triggering it not only when a payment changes from ‘balance due’ to ‘paid,’ but on any status change. Additionally, the updated status should be included to ensure the ability to react appropriately. This approach would enable responses to all status updates.