Deliveries

Upload files for batch processing and manage file-based integrations. This section covers uploading invoice files, agreement files, and payment files for bulk processing.

Overview

The Deliveries endpoint allows you to upload files for batch processing. This is useful for:

  • Bulk invoice creation - Upload multiple invoices at once
  • Agreement management - Upload agreement files for batch processing
  • Payment reconciliation - Upload payment files for reconciliation
  • File-based integrations - Integrate with existing file-based systems

File Upload Process

Two-Step Upload Process

The delivery system supports a two-step upload process for large files:

  1. Create delivery - Submit delivery metadata without file content
  2. Upload file - Upload the actual file using the provided upload URL

Step 1: Create Delivery

POST https://api.farpay.io/v2/deliveries

Request Body (without file data):

{
  "DeliveryType": "Invoice",
  "DeliveryFormat": "XML",
  "File": {
    "Filename": "invoices_january.xml"
  }
}

Response with Upload URL:

{
  "Id": 1234,
  "Created": "2023-01-15T10:30:00Z",
  "DeliveryType": "Invoice",
  "DeliveryStatus": "New",
  "ErrorMessage": null,
  "FileUploadUri": "https://farpay.blob.core.windows.net/uploads/upload_1234?sv=2020-08-04&sr=b&sig=...&sp=w&se=2023-01-15T11:00:00Z&spr=https"
}

Step 2: Upload File

Use the FileUploadUri to upload the actual file:

PUT {FileUploadUri}

Required Headers:

x-ms-blob-type: blockblob
Content-Type: application/octet-stream

Request Body:

[Binary file content]

Important Notes:

  • 30-minute timeout - Upload URLs expire after 30 minutes
  • PUT method only - Only PUT requests are accepted
  • Binary content - Send raw file content, not base64 encoded
  • Required header - x-ms-blob-type: blockblob is mandatory

API Endpoints

Get All Deliveries

Retrieve all deliveries with optional filtering.

GET https://api.farpay.io/v2/deliveries

Query Parameters:

  • status (optional) - Filter by status: New, Processing, Ok, Error
  • type (optional) - Filter by type: Invoice, Agreement, Payment
  • direction (optional) - Filter by direction: CompanyToFarPay, FarPayToCompany
  • fromDate (optional) - Start date for filtering
  • toDate (optional) - End date for filtering

Response Example:

{
  "DeliveryReferences": [
    {
      "Id": 1234,
      "Created": "2023-01-15T10:30:00Z",
      "DeliveryType": "Invoice",
      "DeliveryStatus": "Ok",
      "ErrorMessage": null,
      "FileUploadUri": null
    }
  ],
  "Count": 1
}

Get Single Delivery

Retrieve detailed information for a specific delivery.

GET https://api.farpay.io/v2/deliveries/{id}?includeFile=true

Parameters:

  • id (path) - The delivery's unique identifier
  • includeFile (query) - Include file content in response (true/false)

Response Example:

{
  "Id": 1234,
  "DeliveryFormat": "XML",
  "DeliveryStatus": "Ok",
  "ErrorMessage": null,
  "DeliveryType": "Invoice",
  "InvoiceNumber": "INV-001",
  "File": {
    "Filename": "invoices_january.xml",
    "Data": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>..."
  }
}

Update Delivery Status

Mark a delivery as processed.

PUT https://api.farpay.io/v2/deliveries/{id}

Request Body:

{
  "Id": 1234,
  "DeliveyStatus": "Ok",
  "DeliveryType": "Invoice",
  "DeliveryFormat": "XML"
}

Delivery Properties

Core Properties

PropertyTypeDescription
IdintegerUnique delivery identifier
CreateddatetimeDelivery creation timestamp
DeliveryTypestringType of delivery (Invoice, Agreement, Payment)
DeliveryStatusstringCurrent processing status
ErrorMessagestringError message (if any)
FileUploadUristringFile upload URL (if applicable)

Delivery Details Properties

PropertyTypeDescription
DeliveryFormatstringFile format (XML, JSON, etc.)
InvoiceNumberstringAssociated invoice number
FileobjectFile information and content

File Properties

PropertyTypeDescription
FilenamestringOriginal filename
DatastringFile content (base64 encoded when included)

Delivery Types

TypeDescriptionUse Case
InvoiceInvoice filesBulk invoice creation
AgreementAgreement filesBatch agreement processing
PaymentPayment filesPayment reconciliation

Delivery Status

StatusDescription
NewDelivery created, waiting for file upload
ProcessingFile uploaded, being processed
OkProcessing completed successfully
ErrorProcessing failed

Delivery Direction

DirectionDescription
CompanyToFarPayFiles sent from your company to FarPay
FarPayToCompanyFiles sent from FarPay to your company

File Upload Examples

Direct Upload (Small Files)

For small files, you can include the file content directly:

const fileContent = fs.readFileSync('invoices.xml');
const base64Data = fileContent.toString('base64');

const delivery = {
  DeliveryType: "Invoice",
  DeliveryFormat: "XML",
  File: {
    Filename: "invoices.xml",
    Data: base64Data
  }
};

const response = await fetch('https://api.farpay.io/v2/deliveries', {
  method: 'POST',
  headers: {
    'X-API-KEY': 'your-api-key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(delivery)
});

Two-Step Upload (Large Files)

For large files, use the two-step process:

// Step 1: Create delivery
const delivery = {
  DeliveryType: "Invoice",
  DeliveryFormat: "XML",
  File: {
    Filename: "large_invoices.xml"
  }
};

const response = await fetch('https://api.farpay.io/v2/deliveries', {
  method: 'POST',
  headers: {
    'X-API-KEY': 'your-api-key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(delivery)
});

const deliveryInfo = await response.json();

// Step 2: Upload file
const fileContent = fs.readFileSync('large_invoices.xml');

const uploadResponse = await fetch(deliveryInfo.FileUploadUri, {
  method: 'PUT',
  headers: {
    'x-ms-blob-type': 'blockblob',
    'Content-Type': 'application/octet-stream'
  },
  body: fileContent
});

if (uploadResponse.ok) {
  console.log('File uploaded successfully');
} else {
  console.error('File upload failed');
}

File Format Specifications

XML Invoice Format

<?xml version="1.0" encoding="UTF-8"?>
<invoices>
  <invoice>
    <customerNumber>12345</customerNumber>
    <invoiceNumber>INV-001</invoiceNumber>
    <amount>125.00</amount>
    <dueDate>2023-02-15</dueDate>
    <description>Monthly subscription</description>
  </invoice>
</invoices>

OIOUBL Format

<?xml version="1.0" encoding="UTF-8"?>
<cac:Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2">
  <cbc:ID>INV-001</cbc:ID>
  <cbc:IssueDate>2023-01-15</cbc:IssueDate>
  <cbc:DueDate>2023-02-15</cbc:DueDate>
  <cac:AccountingCustomerParty>
    <cac:Party>
      <cac:PartyIdentification>
        <cbc:ID>12345</cbc:ID>
      </cac:PartyIdentification>
    </cac:Party>
  </cac:AccountingCustomerParty>
</cac:Invoice>

Delivery Monitoring

Check Delivery Status

// Monitor delivery processing
const deliveryId = 1234;
const response = await fetch(`https://api.farpay.io/v2/deliveries/${deliveryId}?includeFile=false`, {
  headers: {
    'X-API-KEY': 'your-api-key',
    'Accept': 'application/json'
  }
});

const delivery = await response.json();

if (delivery.DeliveryStatus === 'Processing') {
  console.log('File is being processed...');
} else if (delivery.DeliveryStatus === 'Ok') {
  console.log('File processed successfully');
} else if (delivery.DeliveryStatus === 'Error') {
  console.log('Processing failed:', delivery.ErrorMessage);
}

Get Recent Deliveries

// Get deliveries from last 7 days
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

const response = await fetch(`https://api.farpay.io/v2/deliveries?fromDate=${sevenDaysAgo.toISOString().split('T')[0]}`, {
  headers: {
    'X-API-KEY': 'your-api-key',
    'Accept': 'application/json'
  }
});

const deliveries = await response.json();

// Check for errors
const failedDeliveries = deliveries.DeliveryReferences.filter(d => d.DeliveryStatus === 'Error');
if (failedDeliveries.length > 0) {
  console.log('Failed deliveries:', failedDeliveries);
}

Error Handling

Common Error Responses

Status CodeDescription
400Bad request - Invalid delivery data
401Unauthorized - Invalid API key
404Not found - Delivery doesn't exist
403Forbidden - Cannot change delivery status

Common Delivery Errors

ErrorDescriptionSolution
Invalid file formatUnsupported file formatCheck supported formats
File too largeFile exceeds size limitsUse two-step upload
Invalid XML structureMalformed XML contentValidate XML structure
Missing required fieldsRequired data missingCheck file content
Processing timeoutFile processing took too longRetry with smaller file
Upload URL expiredUpload URL expiredCreate new delivery

Best Practices

File Upload

  1. Use appropriate upload method - Direct upload for small files, two-step for large files
  2. Validate file content - Check file format and structure before upload
  3. Handle upload timeouts - Upload URLs expire after 30 minutes
  4. Monitor upload progress - Check delivery status after upload
  5. Implement retry logic - Retry failed uploads with exponential backoff

File Processing

  1. Monitor processing status - Check delivery status regularly
  2. Handle errors gracefully - Log and handle processing errors
  3. Validate results - Verify processing results match expectations
  4. Keep file backups - Maintain local copies of uploaded files

Performance

  1. Optimize file size - Keep files reasonably sized for faster processing
  2. Use appropriate formats - Specify delivery format for faster processing
  3. Batch operations - Group related files in single deliveries when possible
  4. Monitor system load - Avoid overwhelming the system with too many uploads

Integration Examples

Batch Invoice Upload

// Upload multiple invoice files
const invoiceFiles = [
  'invoices_january.xml',
  'invoices_february.xml',
  'invoices_march.xml'
];

for (const filename of invoiceFiles) {
  const fileContent = fs.readFileSync(filename);
  const base64Data = fileContent.toString('base64');
  
  const delivery = {
    DeliveryType: "Invoice",
    DeliveryFormat: "XML",
    File: {
      Filename: filename,
      Data: base64Data
    }
  };
  
  try {
    const response = await fetch('https://api.farpay.io/v2/deliveries', {
      method: 'POST',
      headers: {
        'X-API-KEY': 'your-api-key',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(delivery)
    });
    
    const result = await response.json();
    console.log(`Uploaded ${filename}:`, result.Id);
  } catch (error) {
    console.error(`Failed to upload ${filename}:`, error);
  }
}

Monitor Batch Processing

// Monitor all deliveries
const response = await fetch('https://api.farpay.io/v2/deliveries', {
  headers: {
    'X-API-KEY': 'your-api-key',
    'Accept': 'application/json'
  }
});

const deliveries = await response.json();

const statusCounts = {
  New: 0,
  Processing: 0,
  Ok: 0,
  Error: 0
};

deliveries.DeliveryReferences.forEach(delivery => {
  statusCounts[delivery.DeliveryStatus]++;
});

console.log('Delivery status summary:', statusCounts);

// Handle errors
if (statusCounts.Error > 0) {
  const errors = deliveries.DeliveryReferences.filter(d => d.DeliveryStatus === 'Error');
  console.log('Failed deliveries:', errors);
}

Related Endpoints

Deliveries

This endpoint supports slipping XML file-payloads as files into FarPay, simular to the SFTP connection. With this endpoint you can ship off a file, with filename and content.

The Use-Case scenarios are:

  • Insert a new delivery with an attached file
  • Get the existing delivery (Status and details)
  • Get a collection of deliveries, filtered by status, start- and enddate.

Remark that all requests must have an X-API-KEY, and a Accept mentioned in the header of the request.

Insert a new Delivery

Use POST to the endpoint https://api.farpay.io/{version}/deliveries to insert a file with following data:

Parameters

There are two parameters, that are governing the inserted type.

DeliveryFormat

ValueDescription
xml or oioxmlXML format
oioublOIOUBL format
601BS Payment file
605BS Agreement
rd07Domestic format (Faroe Islands)
farpayxmlFarPay propritary format

Remark! The if the format is not set in the request, the receiver will try to determine the format of the attached file. It will do a right classification if the file has a rootnode of agreements or statement or bill.

DeliveryType

The delivery type, is derived and determine from the DeliveryFormat. The following table shows the DeliveryType, that is derived from the DeliveryFormat.

DeliveryFormatDeliveryType
xml, oioxml, oioubl,601, rd07`Invoice
605Agreement
farpayxmlthe content indicates the type

As JSON:

{
  "DeliveryType": "TransmissionReceipt",
  "File": {
    "Filename": "mySuperFileName.xml",
    "Data": "<base64 file content>"
  }
}

As XML:

<?xml version="1.0"?>
<Delivery>
  <DeliveryType>TransmissionReceipt</DeliveryType>
  <File>
    <Filename>mySuperFileName.xml</Filename>
    <Data>base64-fileContent</Data>
  </File>
</Delivery>

When the data has successfully posted into the endpoint, the result is a Delivery that is presented by following:

{
  "Id": <unique fileId>,
  "Created": "2018-10-02T16:19:42.001Z",
  "DeliveryType": "TransmissionReceipt",
  "DeliveryStatus": "New", "Processing" "Ok" | "Error",
  "ErrorMessage": "<Description of the error>" | ""
}

Get the existing delivery

This endpoints gives you an elaborated detail of the delivery, including the file data if wanted. A single delivery is available as GET from https://api.farpay.io/{version}/deliveries/{deliveryId}?includeFile=false or https://api.farpay.io/{version}/deliveries/{deliveryId}?includeFile=true

The File is null when not included in the request

{
  "Id": <unique delivery id>,
  "DeliveryFormat": "string",
  "DeliveryStatus": "string",
  "ErrorMessage": "string",
  "DeliveryType": "string",
  "File": {
    "Filename": "string",
    "Data": "<64 based string of the file content>" 
  } | null
}

Get a collection of deliveries

The collection is wrapped in a container, that in addition the the collection of deliveries, holds the count of how many deliveries you have retreived. The endpoint is available from a GET from https://api.farpay.io/{version}/deliveries with the optional filters of:

  • status
  • fromDate
  • toDate

Example a return container:

{
  "DeliveryReferences": [
      "Id": 1234,
      "Created": "2018-10-12T04:46:33",
      "DeliveryType": "FarPayXmlType",
      "DeliveryStatus": "Error",
      "ErrorMessage": "Line number 1 Current format is ither not set or not supported. Please make sure that the PrepareFactory method is called"
    },
    {
      "Id": 1235,
      "Created": "2018-09-05T11:02:20.00",
      "DeliveryType": "FarPayXmlType",
      "DeliveryStatus": "Ok",
      "ErrorMessage": ""
    },
  ],
  "Count": 2
}