Te recomiendo estudiar el ejemplo en VB.Net que utiliza la libreria CFDLib.dll (para Facturacion electronica), creo que la definicion y el llamado se parecen a lo de Contabilidad Electronica que utiliza la libreria CELib.dll
Código: Seleccionar todo
Imports System.Runtime.InteropServices
Imports Microsoft.VisualBasic
Public Class Form1
Private Enum TError As Byte
OK = 0
Arch_No_Encontrado = 1
Dato_Obligatorio = 2
Problemas_Certificado = 3
Vigencia_Certificado = 4
LlavePrivada = 5
Version_CFD_Invalida = 6
ErrorGeneral = 7
End Enum
''' <summary>
''' Esta es la funcion principal, toma un archivo tipo *.ini con la informacion necesaria
''' para crear la factura, si todo sale bien entonces devuelve un "OK", de otra forma devuelve
''' uno de los errores de la tabla TError
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function GeneraCFD(ByVal IniFileName As String, ByVal ClaveLlavePrivada As String) As TError
End Function
''' <summary>
''' Esta es la funcion principal, toma un archivo tipo *.txt con la informacion necesaria
''' para crear la factura, si todo sale bien entonces devuelve un "OK", de otra forma devuelve
''' uno de los errores de la tabla TError. ********Usa formato de IT Complements Forms Appeal*******
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function GeneraCFD2(ByVal IniFileName As String, ByVal ClaveLlavePrivada As String) As TError
End Function
''' <summary>
''' Funcion para generar el Timbrefiscal, hay que definir en el archivo ini el nombre del PAC
''' y la seccion especial correspondiente al PAC seleccionado, el resultado es el mismo XML
''' pero ya con el timbre insertado
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function TimbrarCFD(ByVal IniFileName As String) As TError
End Function
''' <summary>
''' Funcion para cancelar un CFDI, toma como parametro el nombre de un archivo
''' con extension ini en donde vienen los datos necesarios para la cancelacion/
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function CancelarCFD(ByVal IniFileName As String) As TError
End Function
''' <summary>
''' Funcion para Recuperar el Acuse de Cancelacion que emite el SAT, toma como parametro
''' el nombre de un archivo con extension ini en donde vienen los datos necesarios
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function RecuperaAcuseCancelacion(ByVal IniFileName As String) As TError
End Function
''' <summary>
''' Funcion para consultar el saldo de los timbres, el resultado se graba en el mismo archivo ini
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ConsultaSaldo(ByVal IniFileName As String) As TError
End Function
''' <summary>
''' Funcion para recuperar un CFDI previamente emitido
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function RecuperarCFD(ByVal IniFileName As String) As TError
End Function
''' <summary>
''' PruebaClaveDeLlavePrivada es util para los menus de configuracion, en ese tipo de menus
''' se puede pedir la Clave de la Llave Privada y asegurarse que es la correcta sin necesidad
''' de crear una factura, ya cuando se asegure de que es correcta la clave puede ser grabada
''' para no tener que estarla pidiendo cada vez que se requiera elaborar un CFD
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function PruebaClaveDeLlavePrivada(ByVal IniFileName As String, ByVal ClaveLlavePrivada As String) As Byte
End Function
''' <summary>
''' Funcion que regresa la version de la libreria
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function CFDLibVersion() As String
End Function
''' <summary>
''' La siguiente funcion regresa la Cadena Original y el Sello Digital que se uso para sellar la
'''factura, es necesaria para poder programar la representacion impresa (el PDF)
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function CadenaOriginal() As String
End Function
''' <summary>
''' La siguiente funcion regresa la Cadena Original y el Sello Digital que se uso para sellar la
''' factura, es necesaria para poder programar la representacion impresa (el PDF)
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function SelloDigital() As String
End Function
''' <summary>
''' Si la funcion GeneraCFD no puede crear el CFD devuelve un numero entero -
''' con el error, la funcion GetError devuelve una cadena que explica ese error
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function GetError() As String
End Function
''' <summary>
''' GetErrorExt es una cadena adicional al error que indica con mas detalle en donde
''' ocurrio el error, por ejemplo, GetError puede devolver "Archivo no encontrado"
''' y GetErrorExt devuelve el *nombre* del archivo que no fue encontrado
''' </summary>
<DllImport("CFDLib.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function GetErrorExt() As String
End Function
Private Sub CrearCFDIClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CrearCFDI.Click
OpenDialog.Title = "CARGAR ARCHIVO INI PARA CONVERTIR A FACTURA"
OpenDialog.DefaultExt = "ini"
OpenDialog.Filter = "Archivo INI (*.ini)|*.ini"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim clave As String = Interaction.InputBox("Introduzca la clave de la Llave Privada", "", "12345678a", -1, -1)
Dim err As TError = GeneraCFD(OpenDialog.FileName, clave)
If err = TError.OK Then
Dim cadenaOriginalString As String = CadenaOriginal()
If cadenaOriginalString.Length > 50 Then
cadenaOriginalString = cadenaOriginalString.Substring(0, 50)
End If
Dim selloDigitalString As String = SelloDigital()
If selloDigitalString.Length > 50 Then
selloDigitalString = selloDigitalString.Substring(0, 50)
End If
MessageBox.Show("Se grabo la factura en formato XML" & vbCrLf & vbCrLf & "La Cadena Original y el Sello Digital son" & vbCrLf & vbCrLf & cadenaOriginalString & "..." & vbCr & vbLf & vbCr & vbLf & selloDigitalString & "...", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCrLf & GetError() & vbCrLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
Private Sub TimbradoClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timbrado.Click
OpenDialog.Title = "CARGAR INI CON LA CONFIGURACION PARA TIMBRADO"
OpenDialog.DefaultExt = "ini"
OpenDialog.Filter = "Archivo INI (*.ini)|*.ini"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim err As TError = TimbrarCFD(OpenDialog.FileName)
If err = TError.OK Then
MessageBox.Show("TIMBRADO EXITOSO!!" & vbCr & vbLf & "Ahora el XML ya contiene un timbre", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCr & vbLf & GetError() & vbCr & vbLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
Private Sub CancelacionClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancelacion.Click
OpenDialog.Title = "CARGAR INI CON LA CONFIGURACION PARA CANCELAR UN CFDI"
OpenDialog.DefaultExt = "ini"
OpenDialog.Filter = "Archivo INI (*.ini)|*.ini"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim err As TError = CancelarCFD(OpenDialog.FileName)
If err = TError.OK Then
MessageBox.Show("EL CFDI FUE CANCELADO", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCrLf & GetError() & vbCrLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
Private Sub RecuperaAcuseClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RecuperaAcuse.Click
OpenDialog.Title = "CARGAR INI CON LA CONFIGURACION PARA RECUPERAR EL ACUSE DE CANCELACION"
OpenDialog.DefaultExt = "ini"
OpenDialog.Filter = "Archivo INI (*.ini)|*.ini"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim err As TError = RecuperaAcuseCancelacion(OpenDialog.FileName)
If err = TError.OK Then
MessageBox.Show("EL ACUSE FUE RECIBIDO Y SE GRABO EN DISCO", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCrLf & GetError() & vbCrLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
Private Sub SaldoClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Saldo.Click
OpenDialog.Title = "CARGAR INI CON LA CONFIGURACION PARA CONSULTAR SALDO"
OpenDialog.DefaultExt = "ini"
OpenDialog.Filter = "Archivo INI (*.ini)|*.ini"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim err As TError = ConsultaSaldo(OpenDialog.FileName)
If err = TError.OK Then
MessageBox.Show("EL SALDO DE TIMBRES SE GRABO EN EL ARCHIVO INI", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCrLf & GetError() & vbCrLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
Private Sub RecuperarCFDIClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RecuperarCFDI.Click
OpenDialog.Title = "CARGAR INI CON LA CONFIGURACION PARA RECUPERAR UN CFDI"
OpenDialog.DefaultExt = "ini"
OpenDialog.Filter = "Archivo INI (*.ini)|*.ini"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim err As TError = RecuperarCFD(OpenDialog.FileName)
If err = TError.OK Then
MessageBox.Show("EL XML SE GRABO EN DISCO", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCrLf & GetError() & vbCrLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
Private Sub VersionClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Version.Click
MessageBox.Show("Version de la libreria : " & CFDLibVersion(), "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub PruebaLlaveClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PruebaLlave.Click
OpenDialog.Title = "CARGAR LLAVE PRIVADA PARA PROBAR LA CLAVE"
OpenDialog.DefaultExt = "key"
OpenDialog.Filter = "Llave Privada (*.key)|*.key"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim clave As String = Interaction.InputBox("Introduzca la clave de la Llave Privada", "", "12345678a", -1, -1)
Dim b As Byte = PruebaClaveDeLlavePrivada(OpenDialog.FileName, clave)
If b <> 0 Then
MessageBox.Show("La clave es correcta", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("La clave NO es correcta", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
End Sub
Private Sub FormsAppealClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles FormsAppeal.Click
OpenDialog.Title = "CARGAR ARCHIVO TXT PARA CONVERTIR A FACTURA"
OpenDialog.DefaultExt = "txt"
OpenDialog.Filter = "Archivo TXT (*.txt)|*.txt"
If OpenDialog.ShowDialog() = DialogResult.OK Then
Dim clave As String = Interaction.InputBox("Introduzca la clave de la Llave Privada", "", "12345678a", -1, -1)
Dim err As TError = GeneraCFD2(OpenDialog.FileName, clave)
If err = TError.OK Then
Dim cadenaOriginalString As String = CadenaOriginal()
If cadenaOriginalString.Length > 50 Then
cadenaOriginalString = cadenaOriginalString.Substring(0, 50)
End If
Dim selloDigitalString As String = SelloDigital()
If selloDigitalString.Length > 50 Then
selloDigitalString = selloDigitalString.Substring(0, 50)
End If
MessageBox.Show("Se grabo la factura en formato XML" & vbCrLf & vbCrLf & "La Cadena Original y el Sello Digital son" & vbCrLf & vbCrLf & cadenaOriginalString & "..." & vbCrLf & vbCrLf & selloDigitalString & "...", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MessageBox.Show("Hubo un Error" & vbCrLf & GetError() & vbCrLf & GetErrorExt(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End If
End Sub
End Class