Adding Orders to BOCP

The full connector integration flow: publish products to the connector, read the published product list, send orders using those product codes, and receive real-time webhook notifications when invoices and AWBs are issued.

Two connector types, one endpoint: Both Dropship and eCommerce connectors use the same URL, the same payload, and the same webhook format. The only difference is where the invoice goes — see the eCommerce Orders endpoint reference for details. The connector type is configured in BOCP when your account is set up; it is not a field you send.

Integration flow

Once the connector exists (see Setup), the integration follows four steps:

  1. Publish products to the connector — done in BOCP by your team; it decides which products the connector may see.
  2. Read the published products — pull the catalog to get product codes, prices, and stock.
  3. Send orders — POST orders using those product codes (and PUT to update them).
  4. Receive notifications — BOCP pushes status, invoice, and AWB events back to your URL.

Setup

Each integration requires its own connector. A connector is a named slot in the BOCP eCommerce module that holds the type, credentials, and settings for one external platform.

1. Verify you have a free connector slot

Connector slots are part of your BOCP license. The REST API package includes one eCommerce connector; additional connectors are licensed separately. Check your active slots in eCommerce → Connectors before proceeding.

2. Add a new connector in BOCP

In the BOCP back-end go to eCommerce → Connectors → Add new connector. Fill in:

Save the connector. BOCP automatically generates a dedicated username and password (API key pair) for it.

3. Connector types

TypeInvoice goes toWhen to use
BOCP Rest API (eCommerce) The client supplied in the order payload Your own webshop — the end customer is invoiced directly.
Dropship The preconfigured dropshipper contact in BOCP A partner who sells on your behalf — you are invoiced, not their end customer.

4. Collect your credentials

After saving, the connector detail page shows:

Product codes: every product item you send must use a code that exists in the BOCP product catalog. You obtain these codes in Step 2 by reading the product list — orders with unknown codes are rejected with 400.

You also provide a notification URL on your server and enter it in the connector settings — BOCP will POST event notifications there whenever the order status changes, an invoice is issued, or an AWB is generated.

5. Read the connector configuration (optional but recommended)

Before wiring up the flow, pull the connector's configuration so your integration knows what to expect — which automations BOCP will run on the orders you send (sale issue, invoicing, proforma, AWB), how products sync in both directions, and the event → status mapping used for notifications:

GET https://secure.bocp.eu/app/rest/v1/{company_id}/connector/{connector_id}/config/
Authorization: Basic <base64(username:password)>

The response groups the settings under connector, products (auto-import mode, update options, push feed URL), order_processing (confirmation method, working point, on-import action), invoicing, proforma, awb, and status_sync. Option fields include the full list of possible values, and settings that fall back to an account-wide default carry a source key (connector or global). The call is read-only. See the endpoint reference for the full field list.

Step 1 — Publish products to the connector

A connector can only see products that have been published to it. This is done inside BOCP (not through the API) by your team:

No external category mapping is required — the BOCP category structure travels inside the feed.

Step 2 — Read the published products

Pull the catalog from your connector to get the product code, price, and stock of every published item. Poll it to keep your local catalog in sync.

Only products published to your connector (Step 1) are returned. The response is identical in shape to the main /product/list/ endpoint, so you can reuse the same parser. Prices and stock reflect the working point configured on the connector.
GET https://secure.bocp.eu/app/rest/v1/{company_id}/connector/{connector_id}/products/
Authorization: Basic <base64(username:password)>

Filters

Filters are appended as key:value path segments (see Conventions), not query strings. The most useful ones:

FilterPurpose
page:nPage number. Results are paginated; keep requesting the next page while has_more_pages is true.
format:json|xml|csvResponse format. Defaults to json.
code:SKUReturn a single product by its code or barcode.
modifiedafter:YYYY-MM-DD HH:MM:SSOnly products changed after this timestamp — use it for incremental sync.
include:images,propertiesOpt-in extra data: product images and characteristics.
magazia_id:nOverride the working point used for prices/stock (defaults to the connector's).
GET https://secure.bocp.eu/app/rest/v1/{company_id}/connector/{connector_id}/products/include:images/page:1/

Response

Standard envelope; data is the array of products for the current page. Trimmed example:

{
    "is_error": false,
    "page": 1,
    "has_more_pages": true,
    "data": [
        {
            "product_id":          4521,
            "cod_varianta":        "TS-001",
            "cod_produs":          "ABC123456",
            "barcode":             "0789876543210",
            "product_name":        "Product Name",
            "category_name":       "T-Shirts",
            "stoc_global":         37,
            "unitate_masura":      "buc",
            "pret_vanzare":        100.00,
            "pret_vanzare_cu_tva": 119.00,
            "cota_tva_vanzare":    19,
            "selling_currency_txt":"RON",
            "website_published":   1,
            "producator":          "Acme",
            "last_changed_ts":     "2024-01-01 10:00:00"
        }
    ]
}

Use cod_produs as the code when you build order items. Poll with modifiedafter to keep your local catalog and stock in sync.

Step 3 — Send a new order

When a customer places an order on your platform, POST it to BOCP. The {order_id} in the URL is your own order identifier and must exactly match order_unique_id in the body.

POST https://secure.bocp.eu/app/rest/v1/{company_id}/connector/{connector_id}/order/ABC123456/
Authorization: Basic <base64(username:password)>
Content-Type: application/json

{
    "order_unique_id":     "ABC123456",
    "order_reference":     "ABC123456",
    "order_date":          "2024-01-01",
    "order_updated_at":    "2024-01-01 10:00:00",
    "order_status":        "new",
    "order_cancelled":     0,
    "order_mentions":      "Please deliver in the morning",
    "order_currency_code": "RON",
    "shipping_method":     "courier",
    "cod_amount":          0,
    "cod_currency":        "RON",

    "client": {
        "name":                "John Doe",
        "representative":      "John Doe",
        "email":               "john@example.com",
        "phone":               "0722222222",
        "vat_id":              "",
        "registration_number": "",
        "client_unique_id":    123456,
        "invoice_address": {
            "city":      "Bucharest",
            "county":    "Bucharest",
            "country":   "Romania",
            "zip":       "123456",
            "street":    "Street Name",
            "number":    "1",
            "building":  "",
            "stair":     "",
            "floor":     "",
            "apartment": "",
            "GLN":       ""
        },
        "delivery_address": {
            "city":                   "Bucharest",
            "county":                 "Bucharest",
            "country":                "Romania",
            "zip":                    "123456",
            "street":                 "Street Name",
            "number":                 "1",
            "building":               "",
            "stair":                  "",
            "floor":                  "",
            "apartment":              "",
            "shipping_contact_name":  "John Doe",
            "shipping_contact_phone": "0722222222",
            "GLN":                    ""
        }
    },

    "items": [
        {
            "type":              "product",
            "code":              "ABC123456",
            "ean":               "0789876543210",
            "item_name":         "Product Name",
            "item_quantity":     2,
            "item_price":        100.00,
            "item_vat_percent":  19,
            "item_price_with_vat":              119.00,
            "line_value_with_vat":              238.00,
            "discounted_price_with_vat":         98.00,
            "line_discount_value_with_vat":       4.00
        },
        {
            "type":              "discount",
            "code":              "DISCOUNT",
            "item_name":         "Promo Code: BONUS10",
            "item_quantity":     1,
            "item_price":        -10.00,
            "item_vat_percent":  19,
            "item_price_with_vat": -11.90,
            "line_value_with_vat": -11.90
        },
        {
            "type":              "service",
            "code":              "SHIPPING",
            "item_name":         "Shipping via courier",
            "item_quantity":     1,
            "item_price":        24.00,
            "item_vat_percent":  19,
            "item_price_with_vat": 28.56,
            "line_value_with_vat": 28.56
        },
        {
            "type":              "service",
            "code":              "SERVICE",
            "item_name":         "Special gift wrap",
            "item_quantity":     1,
            "item_price":        50.00,
            "item_vat_percent":  19,
            "item_price_with_vat": 59.50,
            "line_value_with_vat": 59.50
        }
    ],

    "payments": [
        {
            "payment_method":    "card",
            "payment_status":    "confirmed",
            "payment_date":      "2024-01-01 12:11:42",
            "payment_amount":    274.16,
            "payment_currency":  "RON",
            "payment_reference": "TXN-ABSJ-2",
            "payment_comments":  "Paid online"
        }
    ]
}

Item types

typeWhen to useNotes
product A stocked product code must exist in the BOCP product catalog. A 400 is returned if not found.
discount Promo code, voucher, order-level discount Use a negative item_price and item_price_with_vat. Use code DISCOUNT.
service Shipping cost, gift wrap, handling fee Use code SHIPPING for the shipping line; SERVICE for any other service.

Key field notes

FieldNotes
order_unique_id Must match the {order_id} URL segment. Use your platform's native order ID.
order_currency_code ISO code (e.g. RON, EUR). Must be configured in the BOCP account. All item prices must be in this currency.
shipping_method One of: courier, post, personal_pickup, other.
cod_amount Cash-on-delivery amount collected by the courier from the customer. Send 0 if none. Required for correct AWB generation when COD applies.
client.client_unique_id Recommended. Your platform's customer ID. BOCP uses it to recognise returning customers and avoid duplicates.
client.invoice_address.zip May be left blank — BOCP will attempt to resolve it from city + county.
line_value_with_vat Must equal item_quantity × item_price_with_vat.
discounted_price_with_vat Optional. When provided alongside line_discount_value_with_vat and less than item_price_with_vat, BOCP applies it as the effective unit price.
payments Send only payments forwarded through your platform. Omit or send an empty array if no payment yet — resend the full order when payment is confirmed. Only "payment_status": "confirmed" entries count toward paid_amount.

Successful response

BOCP returns HTTP 200 with the standard envelope. The data object contains:

{
    "is_error": false,
    "data": {
        "BOCP_order_id": 4521,
        "notices": [],
        "errors": []
    }
}

Save BOCP_order_id to correlate your order IDs with BOCP internal IDs. Non-fatal issues appear in notices; fatal ones appear in errors with HTTP 400.

Step 4 — Update an order

Send a PUT to the same URL to update an existing order. Only fields present in the body are changed. A minimal status-only update:

PUT https://secure.bocp.eu/app/rest/v1/{company_id}/connector/{connector_id}/order/ABC123456/
Content-Type: application/json

{
    "order_unique_id": "ABC123456",
    "order_status":    "processing"
}

To cancel an order:

{
    "order_unique_id": "ABC123456",
    "order_cancelled": 1
}
Items on PUT are a full replacement. If you include the items array in a PUT request it completely replaces all existing lines — there is no merge. Omit items entirely when you only want to update status or payments.

Step 3 — Receive webhook notifications

Configure an HTTPS endpoint on your server as the notification URL. BOCP POSTs a JSON body; read it with:

$data = json_decode(file_get_contents('php://input'));

Respond based on the outcome:

Your HTTP responseEffect
200Notification accepted and closed.
4xxPermanent error. Notification closed without retry.
Any other codeTransient error. BOCP retries periodically.

Use the notification_type field to distinguish events.

Status change

Sent whenever the order status changes in BOCP (e.g. picked, packed, dispatched, delivered).

{
    "order_unique_id":   "ABC123456",
    "notification_type": "status",
    "status_text":       "Livrata"
}

Invoice issued

Sent when BOCP issues the fiscal invoice. Both an HTML view URL and a PDF download URL are included. For Dropship connectors the invoice goes to the preconfigured dropshipper contact; for eCommerce connectors it goes to the client in the order payload.

{
    "order_unique_id":   "ABC123456",
    "notification_type": "invoice",
    "invoice_number":    "5243",
    "invoice_date":      "2024-09-12",
    "invoice_series":    "SLON",
    "invoice_total":     252.00,
    "invoice_currency":  "RON",
    "invoice_total_RON": 252.00,
    "invoice_url_html":  "https://secure.bocp.eu/...",
    "invoice_url_pdf":   "https://secure.bocp.eu/..."
}

AWB issued

Sent when a courier AWB is generated. Use awb_url_pdf to retrieve the shipping label and awb_number for tracking.

{
    "order_unique_id":           "ABC123456",
    "notification_type":         "awb",
    "awb_number":                "1ONBLN291059727",
    "awb_packet_count":          1,
    "weight":                    1.5,
    "awb_service_type":          "Standard",
    "shipping_payer":            "expeditor",
    "cash_on_delivery":          0.00,
    "cash_on_delivery_currency": "RON",
    "delivery_country":          "Romania",
    "delivery_country_code":     "RO",
    "declared_value":            252.00,
    "awb_type":                  "sameday",
    "awb_subtype":               "",
    "awb_url_pdf":               "https://secure.bocp.eu/..."
}

Product push (catalog changes)

The same notification URL also receives product-catalog pushes, so your integration doesn't need to poll GET .../products/ on a schedule — BOCP pushes the CURRENT full state of a product whenever it changes: on first publish, on any tracked field edit, and on stock or price changes. This is the same mechanism used for every other connector type BOCP pushes to (Shopify, GoMag, ...) — BOCPRAPI is treated as a regular push destination, not a passive feed.

Full state, not a diff. Every push carries the complete current product — identity, category, price, stock, description — using the same field names as GET .../products/, so one parser handles both. Which fields you receive updates for is controlled by the "Câmpuri actualizate" selection in the connector settings, same as for any other push destination.
notification_typeSent when
product_publishedA product is newly published to your connector, or explicitly republished.
product_updateA tracked field, the stock, or the price changed on an already-published product.
product_unpublishedA product was disconnected or deleted from your connector — stop offering it.
{
    "notification_type":     "product_update",
    "cod_produs":            "ABC123456",
    "barcode":               "0789876543210",
    "product_name":          "Product Name",
    "product_website_title": "Product Name",
    "product_description":   "...",
    "category_name":         "Category",
    "producator":            "Brand",
    "stoc_global":           50,
    "stock_reserved":        8,
    "stock_available":       42,
    "pret_vanzare":          100.00,
    "pret_vanzare_cu_tva":   119.00,
    "cota_tva_vanzare":      19,
    "selling_currency_txt":  "RON",
    "deleted":               0,
    "last_changed_ts":       "2026-08-17 10:00:00"
}

product_unpublished is a short packet with just the identifier, since there is nothing else to send:

{"notification_type": "product_unpublished", "cod_produs": "ABC123456"}

Single packet per product for now — batching multiple products into one request may follow later.