Process purchase invoices
After a purchase invoice is received or uploaded to Banqup, the document goes through the Document Processor app, where the invoice data are extracted and checked for sanity and accuracy.
Once this step is successfully finalized, the document flow can start by performing the most appropriate action on the document: approve, refuse, suspend, dispute etc.
Prerequisites
- The invoice is a valid UBL, XML or PDF.
- The resource IDs necessary to perform the API calls are:
Step 1: Create file
Endpoint: /datastore/documents/transaction/v1/spaces/{spaceId}/files
Request body: View documentation
Path parameter:
spaceId
curl -L 'https://{{serverURL}}/datastore/documents/transaction/v1/spaces/:spaceId/files' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{
"filename": "S_BE0479909676_999.xml",
"description": "XML upload for document FAC-001",
"retentionTime": "2029-09-30T08:30:08.424Z",
"fileSize": 57308,
"fileType": "application/xml",
"contentType": "application/xml",
"metadata": {
"folder": "PURCHASES",
"documentCategory": "INVOICE"
}
}
Successful response:
How to view the file details
Endpoint: /datastore/documents/transaction/v1/spaces/{spaceId}/files/{fileId}
Request body: View documentation
Path parameters:
spaceId
fileId
{
"id": "5db18794-cd31-4582-adba-5e9ff0f02f4b",
"filename": "S_BE0479909676_999.xml",
"description": "XML upload for document FAC-001",
"creatorSubject": "15d02643-04e4-4cb7-b3df-a1c30900576b",
"creatorType": "application",
"retentionTime": "2029-09-30T08:30:08.424Z",
"status": "AWAITING_UPLOAD",
"fileSize": 57308,
"fileType": "application/xml",
"contentType": "application/xml",
"uploadUrl": "https://storage.googleapis.com/gcs-oaxzkhsk-eu-datastore-test/transaction/file/7cbc7e1a-a705-455e-bhj8-152974aa09e1/5db18794-cd31-4582-adba-5e9ff0f02f4b?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=sa-btxdata-datastore-test-eu%40pj-bu-btxdata-test-eu.iam.gserviceaccount.com%2F20241209%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20241209T114309Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=a7913259d2861ac109067c056942030bc7e481700e395f0861d5d2e915ee216886d5dcc2cfaa96fa008e08e78d87652faa82d54cbe85a79c462f08be435959ffd249e3a7df628c9cfce1054d9d630b7ff8d900bdb97a8e2056333b0f7cd8a5f03ad6444ba02c0067f114802c04e39108146812f748ae9d8a790c258b7c1b825b9984e066cb0a7996f18f03db99ac3044dca8f075e58fc81723a9bb23005d5c6e7db2d5d907a39ff26f8fd25cc96fb90faf0b15b90146c514592b74bedab7a0f714f6c28f837b7ba52a0332e3cc2c7908913ce6e5da09c800c2fb11fc4e18082206c4c41a4914c9e1df92ecfd34527d7010f5e30bfbda2a4486ce113317a0a4fd",
"metadata": {
"folder": "PURCHASES",
"documentCategory": "INVOICE"
},
"createdAt": "2024-12-09T11:43:09.615410027Z",
"updatedAt": "2024-12-09T11:43:09.615410027Z"
}
Step 2: Upload file
Endpoint: /
uploadUrl
(returned in the previous response).
The uploadUrl is a presigned URL in GCP which allows users to temporarily and securely access bucket resources for upload.
Request body: Attach the file in PDF, UBL or XML format. Content type: binary.
Successful response: The file has been accepted for processing. File statuses explained.
Step 3: Get the details of extension point 'Document actions'
To perform a document action on a purchase invoice, you need to identify the base path URL associated with a particular document task, which is obtained by executing this step and the next one.
Endpoint: /core/plugin/api/v1/extensionPoints/{extensionPointID}
Path parameter: View documentation
extensionPointID
of Document actions extension
curl -L -X GET 'https://{{serverURL}}/core/plugin/api/v1/extensionPoints/{extensionPointID}' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR TOKEN'
Successful response
{
"extensionPointId": "e1b9173e-2390-4c65-bf0e-e875f2839a85",
"namespace": "com.unifiedpost.btx",
"name": "documentActions",
"version": "1.0",
"authorizationEndpoint": {
"url": "string",
"authorizationHeader": "string",
"httpSignature": true
},
"public": true
}
Step 4: Get the base path of the document task
Endpoint: /core/plugin/api/v1/extensionPoints/{extensionPointID}/extensions
Path parameter: View documentation
extensionPointID
of Document actions extension
curl -L -X GET 'https://{{serverURL}}/core/plugin/api/v1/extensionPoints/{extensionPointID}/extensions' \
-H 'Accept: application/json'
-H 'Authorization: Bearer YOUR TOKEN'
Successful response
{
"extensions": [
{
"extensionId": "74be0d46-642c-4cae-a6c6-4b19923c4ef9",
"data": {
"name": "com.unifiedpost.btx.data:dispute",
"label": "Dispute",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/dispute",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "68c3972e-6406-4084-8bf4-6cc2f61d55d1",
"data": {
"name": "com.unifiedpost.btx.data:complete",
"label": "Complete",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/complete",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "79760144-d413-4bae-af6b-daa72b5676e7",
"data": {
"name": "com.unifiedpost.btx.data:markAsPaid",
"label": "Mark Paid",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/markAsPaid",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "232def5a-a49b-471a-89b0-15a0b2dcd7aa",
"data": {
"name": "com.unifiedpost.btx.data:markAsWontBePaid",
"label": "Mark as won't be paid",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/markAsWontBePaid",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "6759547f-3248-4f33-94f2-44cd83035087",
"data": {
"name": "com.unifiedpost.btx.aggregation:markAsPaid",
"label": "Mark Paid",
"basePath": "https://{{serverURL}}/pay/aggregation/documents/v1/actions/markAsPaid",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "0708b90d-3a4e-4721-9ed2-79d81e906433",
"data": {
"name": "com.unifiedpost.btx.data:reject",
"label": "Reject",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/reject",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "24ff52bc-0f18-4fa6-bd24-37a05f9679d5",
"data": {
"name": "com.unifiedpost.btx.data:refuse",
"label": "Refuse",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/refuse",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "c258f703-e941-4161-bbc3-be3f8283e084",
"data": {
"name": "com.unifiedpost.btx.data:approve",
"label": "Approve",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/approve",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "932c2778-f844-4868-a870-3d40e093f8e2",
"data": {
"name": "com.unifiedpost.btx.data:partiallyApprove",
"label": "Partially Approve",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/partiallyApprove",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "27bbd144-5840-4600-bdb0-4b491b910dc2",
"data": {
"name": "com.unifiedpost.btx.data:markAsUnpaid",
"label": "Mark Unpaid",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/markAsUnpaid",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "b5cfe8da-83f9-4548-b244-2c86fd3e841d",
"data": {
"name": "com.unifiedpost.btx.data:markAsRefused",
"label": "Mark as refused",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/markAsRefused",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "20addebe-a30e-4235-bd12-5e6df52589af",
"data": {
"name": "com.unifiedpost.btx.data:markAsResolved",
"label": "Mark as resolved",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/markAsResolved",
"synchronous": true,
"supportBatch": true
}
},
{
"extensionId": "2df3226c-3cc9-47b0-b37e-fabba57929ba",
"data": {
"name": "com.unifiedpost.btx.data:suspend",
"label": "Suspend",
"basePath": "https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/suspend",
"synchronous": true,
"supportBatch": true
}
}
]
}
Step 5: Perform a document task
Use the base paths obtained in the previous call to perform a document task on the document.
Possible document tasks
- Approve
- Partially approve
- Reject
- Refuse
- Dispute
- Suspend
- Complete
- Mark as paid
- Mark as unpaid
- Mark as won't be paid
- Mark as refused
- Mark as resolved
Note:
- Approving the invoice doesn't necessarily mean that the invoice is entirely correct. After approval, you can still refuse, suspend or dispute it.
- Invoice rejection is performed automatically by the system if the document is not compliant.
- Invoice refusal is performed when the invoice is not correct, while suspending an invoice is done when the invoice is not complete (missing documents).
- Completing an invoice means that a suspended invoice has been resolved.
curl -L -X POST 'https://{{serverURL}}/datastore/documents/documentTasks/v1/tasks/approve' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR TOKEN' \
--data-raw '{
"spaceId": "d44698da-6363-473f-503d-8eb213a2940e",
"documents": "56079d21-a756-49lb-9286-9859c354aa69"
}'
Successful response
{
"success": [
"56079d21-a756-49lb-9286-9859c354aa69"
],
"failure": []
}
Step 6: View results
- Document
- Document events
- Supplier
Endpoint: /datastore/documents/transaction/v1/spaces/{spaceId}/{folder}/documents/{documentId}
Path parameters: View documentation
spaceId
folder
documentId
curl -L -X GET 'https://{{serverURL}}/datastore/documents/transaction/v1/spaces/{spaceId}/{folder}/documents/{documentId}' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
Successful response
{
"id": "0ca2797b-6365-4bf2-a490-247075e3cede",
"spaceId": "56079d21-a756-49fb-9286-9859c354aa69",
"description": "Invoice",
"source": "email",
"folder": "PURCHASES",
"supplier": {
"id": "d44698da-6363-476f-903d-8eb113a2940e"
},
"customer": {
"id": "0639a36a-f5c2-49f8-a2db-2d60d4284362"
},
"status": {
"pay": "UNPAID"
},
"category": "INVOICE",
"metadata": {
"virus": "hidden"
},
"tags": [
"new"
],
"tasks": [
{
"extensionName": "com.unifiedpost.btx.data:approve",
"status": "approve"
}
],
"retentionTime": "2023-10-04T14:20:31.502921Z",
"lines": [
{
"id": "7a1cf570-db5c-4e41-992e-9890532212ae",
"sequence": 1,
"identifier": "ID569874",
"description": "A4 copy paper",
"itemId": "Item1",
"itemCategory": "office supplies",
"productIdentifiers": {
"commodityCode": "BGT1256"
},
"quantity": 2,
"unit": "PCS",
"startDate": "2024-01-23",
"endDate": "2024-06-23",
"discounts": {
"value": "20.0"
},
"charges": {
"value": "76.67"
},
"unitPrice": "40.278192",
"netAmount": "80.56",
"grossAmount": "96.67",
"vatAmount": "16.11",
"currency": "USD",
"vatRate": "0.2",
"vatCode": "VAT"
}
],
"createdAt": "2023-10-04T14:20:31.502921Z",
"updatedAt": "2023-10-04T14:20:31.502921Z"
}
All relevant actions performed on a document are recorded in an events log in Banqup.
Endpoint: /datastore/event/v1/spaces/{spaceId}/events
Request body: View documentation
Path parameter:
spaceId
curl -L -X GET 'https://{{serverURL}}/datastore/event/v1/spaces/:spaceId/events' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
Successful response
{
"events": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"level": "INFO",
"subjectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"subjectType": "user",
"ownerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"ownerType": "SPACE",
"body": "The customer has paid $100.00.",
"category": "payment",
"subcategory": "payment_sent",
"metadata": {
"some": "value"
},
"properties": {
"connector": "chorus_pro"
},
"createdAt": "2024-05-31T11:58:22.189Z"
}
],
"totalElements": 0,
"currentPage": 0,
"pageSize": 0
}
If the supplier doesn't exist in the system when the invoice is received, it will be created based on the information in the invoice as a new connection.
Customers, suppliers and other business partners are collectively called connections in Banqup.
Endpoint: /datastore/documents/transaction/v1/spaces/{spaceId}/connections/{connectionId}
Path parameters: View documentation
spaceId
connectionId
curl -L -X GET 'https://{{serverURL}}/datastore/documents/transaction/v1/spaces/:spaceId/connections/:connectionId' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
Successful response
- Business connection
- Person connection
{
"type": "business",
"id": "aaba0614-b8b6-45d6-94b7-957cde946300",
"spaceUrl": "https://entity.store/entitystore/v1/directory/entities/entity_1/spaces/space_1",
"globalIdentifiers": {
"be:vat": "569874569",
"global:email": [
"john.smith@novafish.com"
],
"global:phoneNumber": [
"0032563653874"
]
},
"localIdentifier": "001",
"alias": "UP",
"connectionStatus": "CONNECTED",
"relationType": "SUPPLIER",
"addresses": {
"main": {
"streetName": "Nitzsche Lodge",
"house": "80728",
"postalCode": "3110",
"city": "Fernandahaven",
"country": "Belgium",
"countryCode": "BE"
}
},
"tags": [
"validate",
],
"active": true,
"metadata": {
"channels": {
"main": "delivery_on_platform",
"secondary": "email"
},
"department": "Accounting",
"logo": "https://address.com/logo.jpg",
"website": "https://mycompanywebsite.com",
"notes": "Professional and amateur fishing gear",
"industry": "Agriculture, Forestry And Fishing"
},
"legalName": "Nova Fish",
"tradeName": "Fishing Gear",
"businessType": "ENTERPRISE"
}
{
"type": "person",
"id": "44285181-3714-40c0-acd2-22dd5596269e",
"spaceUrl": "https://entity.store/entitystore/v1/directory/entities/entity_1/spaces/space_1",
"globalIdentifiers": {
"global:email": [
"susan.anderson@xyz.com"
],
"global:phoneNumber": [
"00301234567"
]
},
"alias": "UP",
"connectionStatus": "CONNECTED",
"relationType": "SUPPLIER",
"addresses": {
"main": {
"street": "Milo Crossroad",
"house": "7850",
"postalCode": "3100",
"city": "Kubhaven",
"country": "Belgium",
"countryCode": "BE"
}
},
"tags": [
"validate"
],
"active": true,
"metadata": {
"channels": {
"main": "delivery_on_platform",
"secondary": "email"
},
"department": "Accounting",
"logo": "https://address.com/logo.jpg",
"website": "https://mycompanywebsite.com",
"notes": "My notes",
"industry": "Construction"
},
"firstName": "Susan",
"lastName": "Anderson"
}