sj_royd / efaktura_service
Platforma Elektronicznego Fakturowania
Requires
- guzzlehttp/guzzle: ^6.0
- netresearch/jsonmapper: ^1.4
Suggests
- sj_royd/efaktura_documents: HTML/XML Generator and XML parser for eFaktura documents
README
The library allows you to download and send documents to the Electronic Invoicing Platform (PEF) (https://efaktura.gov.pl/).
Who is PEF for
The Electronic Invoicing Platform (PEF) is used to forward invoices and other structured documents between public procurement contractors and contracting authorities. Services are provided in parallel by two PEF Brokers.
Implementations of sent documents were prepared on the basis of PEPPOL BIS 3.0 and CEFACT guidelines.
1. Installation
$ composer require sj_royd/efaktura_service
2. Usage
<?php
use SJRoyd\PEF\PEF;
use SJRoyd\PEF\Error;
try {
$pefID = 'user id'; // API user ID
$pefSecret = 'user secret'; // API user secret
$pefService = PEF::BROKER_INFINITE; // available PEF::BROKER_PEFEXPERT or PEF::BROKER_INFINITE
$pef = new PEF($pefID, $pefSecret, $pefService);
$queueLength = 0;
do {
// gets the first message from the queue
$msgGeneral = $pef->queue->getMessage();
$msg = $msgGeneral->getMessage();
// gets the number of messages in the queue
$queueLength = $pef->queue->getQueueLength();
// if the message exists
if($msg){
// if the message indicates the existence of a document
if($msgGeneral->getDocumentContent){
// gets the content of the document
$content = $pef->document->getDocumentContent($msg->documentId);
// sets the status of the document to read
$pef->document->readDocument($msg->documentId);
// do something with the document, ex. save in a storage
}
// sets the status of the message to read last
// because document->getDocumentContent() can throw
// an Error\ClientError or Error\ServerError and we
// can go back to the message next time
$pef->queue->sendMessageAck($msg->messageId);
}
} while($queueLength > 1);
} catch (Error\AuthError $ex) {
echo 'Auth error';
} catch (Error\ClientError $ex) {
echo 'Client error';
} catch (Error\ServerError $ex) {
echo 'Server error';
}
3. Operations
getMessage()
Queue of waiting messages; location$pef->queue
For an external system (identified as an external system account) the PEF system maintains a queue of messages addressed to it. Operation allows downloading the first message in queue. Calling this operation again will return the same message until the external system confirms with the
sendMessageAck()
operation that this message has been processed correctly.sendMessageAck()
Acknowledgment of receipt of the message; location$pef->queue
Operation allows confirming the correct processing of the last downloaded message. After invoking this operation, a new message (if one exists) will be available on the message queue. Calling this operation also means receiving the document (in the context of the message regarding the new incoming document).
getQueueLength()
Number of messages queued; location$pef->queue
The operation returns the number of messages waiting in the queue after performing the operation
getMessage()
.sendDocument()
Forwarding of the document for sending; location$pef->document
The operation enables sending a document to the PEF System.
You can send one of six document types - helper
Document\Type
The document is supplied in Ubl or Cefact format - helper
Document\Format
The recipient of the document is determined based on the content of the document. The PEF system sends the document to the recipient asynchronously. Information about the status of sending the document can be retrieved from the message queue. If the PEF system accepts the document correctly, then this operation returns the document identifier (
documentId
). This identifier should be saved by an external system to associate messages about this document that will appear in the message queue in the future.getDocumentContent()
Getting the content of the document; location$pef->document
Operation allows gets the content (in Ubl format) of a document received or sent from another source. The content of the document is available for 7 days from the time of receiving the message about the new document.
readDocument()
Marking the document as read; location$pef->document
The operation allows to convey information that an external system user has read the document.
4. Message queue
The operation getMessage()
returns the SJRoyd\PEF\Response\Message object
which contains one of five types of message (below) and the information
getDocumentContent
telling whether the message is assigned a document
to be get with the method getDocumentContent()
.
The getMessage()
method on the getMessage()
operation returns a specific
message that came. Each message has a messageId
field identifying the identifier
messages and documentId
being the document identifier.
Messages can be handled using the switch
block:
<?php
$msgGen = $pef->message->getMessage();
$msg = $msgGen->getMessage();
switch(true) {
case $msg instanceof Message\ReceivedDocumentStatusChanged:
// do something
break;
case $msg instanceof Message\SentDocumentStatusChanged:
// do something
break;
// etc...
}
or if
block:
<?php
$msgGen = $pef->message->getMessage();
if(($msg = $msgGen->receivedDocumentStatusChangedMessage)){
// do something
}
if(($msg = $msgGen->sentDocumentStatusChangedMessage)){
// do something
}
// etc...
4.1 Message Message\ReceivedDocumentStatusChanged
Message informing about the change of status of the received document. The message will be triggered if the status of the document has been changed using another channel (WEB application or desktop application).
Message fields:
messageId
: uuiddocumentId
: uuidstatus
: enum [ RECEIVED, READ ] - helperStatus\DocumentReceived
4.2 Message Message\SentDocumentStatusChanged
Message informing about the change of status of the sent document.
Message fields:
messageId
: uuiddocumentId
: uuidstatus
: enum [ PENDING, SENT, RECEIVED, READ ] - helperStatus\DocumentSend
4.3 Message Message\SentDocumentErrorMessage
A message indicating an error in the process of sending the document.
Message fields:
messageId
: uuiddocumentId
: uuiderrors
: list of Message\ErrorerrorCode
: enum [ 401, 402, 403, 404, 501 ]errorMessage
: string
errorCode
according to the dictionary:
401 wrong request
402 document content validation error
403 the recipient's endpoint is not registered in the PEPPOL network
404 the recipient does not support the type of document
501 document delivery error. Despite attempts to retransmit, the document could not be delivered.
errorMessage
- technical description of the error. The description is
to show the technical person (not the end user) what the error was.
4.4 Message Message\DocumentReceived
A message informing you that a document has been received. The document
content can be downloaded using the getDocumentContent()
operation.
Message fields:
messageId
: uuiddocumentId
: uuidbusinessValidationReport
: Message\BusinessValidationReportreportDate
: DateTime objectwarnings
: enum [ EMPTY_CONTRACT_ID, EMPTY_ORDER_REFERENCE, EMPTY_DESPATCH_DOCUMENT_REFERENCE, EMPTY_RECEIPT_DOCUMENT_REFERENCE, EMPTY_INVOICE_DOCUMENT_REFERENCE, REFERENCED_ORDER_NOT_FOUND, REFERENCED_DESPATCH_NOT_FOUND, REFERENCED_RECEIPT_NOT_FOUND, REFERENCED_INVOICE_NOT_FOUND ] - helperMessage\Warning
documentType
: enum [ CREDIT_NOTE, DESPATCH_ADVICE, INVOICE, INVOICE_CORRECTION, ORDER, RECEIPT_ADVICE ] - helperDocument\Type
4.5 Message Message\DocumentSentFromOtherSource
A message informing that a document was sent from a mailbox supported by this system by another channel (from WEB or desktop application). The document content can be downloaded using the getDocumentContent()
operation.
Message fields:
messageId
: uuiddocumentId
: uuiddocumentType
: enum [ CREDIT_NOTE, DESPATCH_ADVICE, INVOICE, INVOICE_CORRECTION, ORDER, RECEIPT_ADVICE ] - helperDocument\Type
5. Helper
Helpers have static methods:
getList(): list
- returns a list of constants in the classexists($const): boolean
- returns information whether the given value exists as a constant
Helper Document\Type
<?php
namespace SJRoyd\PEF\Helper\Document;
use SJRoyd\PEF\Helper\Constants;
class Type
{
use Constants;
const CREDIT_NOTE = 'CREDIT_NOTE';
const DESPATCH_ADVICE = 'DESPATCH_ADVICE';
const INVOICE = 'INVOICE';
const INVOICE_CORRECTION = 'INVOICE_CORRECTION';
const ORDER = 'ORDER';
const RECEIPT_ADVICE = 'RECEIPT_ADVICE';
}
Helper Document\Format
<?php
namespace SJRoyd\PEF\Helper\Document;
use SJRoyd\PEF\Helper\Constants;
class Format
{
use Constants;
const UBL = 'Ubl';
const CEFACT = 'Cefact';
}
Helper Status\DocumentReceived
<?php
namespace SJRoyd\PEF\Helper\Status;
use SJRoyd\PEF\Helper\Constants;
class DocumentReceived
{
use Constants;
const RECEIVED = 'RECEIVED';
const READ = 'READ';
}
Helper Status\DocumentSend
<?php
namespace SJRoyd\PEF\Helper\Status;
use SJRoyd\PEF\Helper\Constants;
class DocumentSend
{
use Constants;
const PENDING = 'PENDING';
const SENT = 'SENT';
const RECEIVED = 'RECEIVED';
const READ = 'READ';
}
Helper Message\Warning
<?php
namespace SJRoyd\PEF\Helper\Message;
use SJRoyd\PEF\Helper\Constants;
class Warning
{
use Constants;
const EMPTY_CONTRACT_ID = 'EMPTY_CONTRACT_ID';
const EMPTY_ORDER_REFERENCE = 'EMPTY_ORDER_REFERENCE';
const EMPTY_DESPATCH_DOCUMENT_REFERENCE = 'EMPTY_DESPATCH_DOCUMENT_REFERENCE';
const EMPTY_RECEIPT_DOCUMENT_REFERENCE = 'EMPTY_RECEIPT_DOCUMENT_REFERENCE';
const EMPTY_INVOICE_DOCUMENT_REFERENCE = 'EMPTY_INVOICE_DOCUMENT_REFERENCE';
const REFERENCED_ORDER_NOT_FOUND = 'REFERENCED_ORDER_NOT_FOUND';
const REFERENCED_DESPATCH_NOT_FOUND = 'REFERENCED_DESPATCH_NOT_FOUND';
const REFERENCED_RECEIPT_NOT_FOUND = 'REFERENCED_RECEIPT_NOT_FOUND';
const REFERENCED_INVOICE_NOT_FOUND = 'REFERENCED_INVOICE_NOT_FOUND';
}