Skip to content

Δημιουργία παραγγελίας ​

Η κλήση POST /orders δημιουργεί μια νέα παραγγελία στο CourierHub, με τους ίδιους κανόνες όπως η χειροκίνητη δημιουργία παραγγελίας από το περιβάλλον πελάτη. Η παραγγελία εμφανίζεται αμέσως στη λίστα παραγγελιών του CourierHub, όπου μπορείτε να εκδώσετε voucher.

WARNING

Θα πρέπει να συμπεριλάβετε το API Token σας σε κάθε αίτημα ως Bearer Token. Αντικαταστήστε το YOUR_TOKEN με το API Token του καταστήματος (chub_...). Δείτε το Overview.

MethodURIHeaders
POST/api/v2/ordersAuthorization: Bearer YOUR_TOKEN
Content-Type: application/json

Πριν ξεκινήσετε ​

  • Κατάστημα. Η νέα παραγγελία ανήκει στο κατάστημα του token που χρησιμοποιήσατε. Με το token άλλου καταστήματος του ίδιου λογαριασμού δημιουργείτε παραγγελία σε εκείνο το κατάστημα.
  • order_number και order_id. Το order_number είναι ο δικός σας αριθμός παραγγελίας και είναι υποχρεωτικός. Το order_id το παράγει το CourierHub (αριθμητικό, π.χ. 20261015101200482) και δεν το στέλνετε. Δείτε order_id και order_number.
  • Μοναδικός αριθμός. Το order_number πρέπει να είναι μοναδικό ανάμεσα στις (μη διαγραμμένες) παραγγελίες του καταστήματος, συμπεριλαμβανομένων αυτών που ήρθαν από το e-shop. Τα #1001 και 1001 θεωρούνται ο ίδιος αριθμός. Αν υπάρχει ήδη, η απάντηση είναι 409 order_number_taken. Μια διαγραμμένη παραγγελία ελευθερώνει τον αριθμό της.
  • Χωρίς συγχρονισμό με e-shop. Οι παραγγελίες που δημιουργούνται από το API είναι παραγγελίες του CourierHub: δεν στέλνονται σε e-shop (Shopify, WooCommerce κ.λπ.), ακόμα κι αν το κατάστημα του token είναι συνδεδεμένο με e-shop.
  • Courier. Το courier_id είναι το id από το GET /couriers, δηλαδή μία από τις courier που έχετε συνδέσει στον λογαριασμό σας.

Μεταβλητές αποστολής ​

Το σώμα (body) είναι JSON. Τα ποσά μπορείτε να τα στείλετε ως string ("12.90", προτείνεται) ή ως αριθμό (12.9), με έως 2 δεκαδικά. Στην απάντηση επιστρέφονται πάντα ως string.

Variable NameTypeUsageRequired
order_numberStringΟ δικός σας αριθμός παραγγελίας, έως 64 χαρακτήρες. Επιτρέπονται γράμματα (και ελληνικά), ψηφία και οι χαρακτήρες # . _ / -, χωρίς κενά (π.χ. #1001, 1001, INV-2026/17). Τα κενά στην αρχή και στο τέλος αφαιρούνται. Αποθηκεύεται όπως το στείλατε (με ή χωρίς #). Μοναδικό στο κατάστημα.*
statusStringpending (προεπιλογή) ή processing. Οι υπόλοιπες καταστάσεις ορίζονται από το CourierHub. Με receive_from_reception: true η κατάσταση γίνεται store_pickup.
order_dateStringΗμερομηνία παραγγελίας. Προτείνεται ISO 8601 με ζώνη ώρας (π.χ. 2026-10-15T07:05:00Z ή 2026-10-15T10:05:00+03:00). Χωρίς ζώνη ώρας ερμηνεύεται ως ώρα Ελλάδας. Προεπιλογή: η στιγμή της δημιουργίας.
recipientObjectΤα στοιχεία του παραλήπτη (τα παρακάτω πεδία).*
recipient.nameStringΟνοματεπώνυμο, έως 255 χαρακτήρες.*
recipient.phoneStringΤηλέφωνο. Πριν τον έλεγχο αφαιρούνται κενά, παύλες, τελείες, παρενθέσεις και /, και το 00 στην αρχή γίνεται + (π.χ. 0030 2310 123456 γίνεται +302310123456). Το αποτέλεσμα πρέπει να είναι 7 έως 15 ψηφία, με προαιρετικό + στην αρχή.*
recipient.emailStringΈγκυρο email, έως 255 χαρακτήρες.*
recipient.addressStringΔιεύθυνση (οδός και αριθμός), έως 255 χαρακτήρες.*
recipient.cityStringΠόλη / περιοχή, έως 100 χαρακτήρες.*
recipient.postal_codeStringΤαχυδρομικός κώδικας. Τα κενά αφαιρούνται από αριθμητικούς κώδικες (105 63 γίνεται 10563) και τα γράμματα γίνονται κεφαλαία. Για GR: ακριβώς 5 ψηφία. Για CY: ακριβώς 4 ψηφία. Για τις άλλες χώρες: 2 έως 20 γράμματα, ψηφία, κενά ή παύλες.*
recipient.countryStringGR, CY, EU, US ή OTHER (γίνονται δεκτά και με πεζά, π.χ. gr).*
receive_from_receptionBooleantrue για παραλαβή από το δικό σας κατάστημα (store pickup): η παραγγελία δεν έχει courier και παίρνει κατάσταση store_pickup. Προεπιλογή false. Δείτε Παραλαβή από κατάστημα.
courier_idIntegerΗ courier της αποστολής: το id από το GET /couriers. Πρέπει να είναι courier συνδεδεμένη στον λογαριασμό σας. Υποχρεωτικό, εκτός αν receive_from_reception: true (τότε αγνοείται).*
servicesArrayΕπιπλέον υπηρεσίες courier, από τις saturday, epistrofi, receive_from_reception (χωρίς διπλές τιμές). Δεν επιτρέπονται για Box Now ή για παραλαβή από το κατάστημα. Δείτε Υπηρεσίες.
locker_idStringΗ θυρίδα (locker) Box Now, έως 64 χαρακτήρες (γράμματα, ψηφία και . _ : -). Υποχρεωτικό όταν η courier είναι Box Now, δεν επιτρέπεται για άλλες courier.
payment_methodStringΤρόπος πληρωμής: cod (αντικαταβολή), paypal, stripe, bank_transfer, other.*
cod_costStringΈξοδα αντικαταβολής, 0 έως 999999.99, έως 2 δεκαδικά. Μόνο με payment_method: cod: σε άλλο τρόπο πληρωμής γίνεται δεκτό μόνο 0 / null και αποθηκεύεται 0.00. Προεπιλογή 0.
shipping_costStringΜεταφορικά, 0 έως 999999.99, έως 2 δεκαδικά. Προεπιλογή 0.
subtotalStringΑξία προϊόντων, 0 έως 99999999.99, έως 2 δεκαδικά. Αν λείπει, υπολογίζεται ως το άθροισμα των products (0 αν δεν υπάρχουν προϊόντα). Αν το στείλετε, υπερισχύει του αθροίσματος (π.χ. για εκπτώσεις).
weightStringΒάρος σε κιλά, μεγαλύτερο του 0 και έως 99999.999, έως 3 δεκαδικά.
notesStringΣημειώσεις, έως 1000 χαρακτήρες.
productsArrayΤα προϊόντα της παραγγελίας, έως 100.
products[].nameStringΌνομα προϊόντος, έως 255 χαρακτήρες.*
products[].skuStringΚωδικός προϊόντος, έως 100 χαρακτήρες.
products[].unit_priceStringΤιμή μονάδας, 0 έως 99999999.99, έως 2 δεκαδικά.*
products[].quantityIntegerΠοσότητα, 1 έως 100000.*

Τα πεδία με * στο products[] είναι υποχρεωτικά για κάθε προϊόν, όταν στέλνετε products.

Ποσά ​

  • Το total_amount δεν το στέλνετε: υπολογίζεται πάντα ως subtotal + shipping_cost + cod_cost.
  • Το total_price κάθε προϊόντος είναι unit_price × quantity.
  • Σε αντικαταβολή (cod), το ποσό που εισπράττει η courier είναι το total_amount (μαζί με μεταφορικά και έξοδα αντικαταβολής).
  • Το σύνολο της παραγγελίας και το σύνολο κάθε προϊόντος δεν μπορούν να ξεπερνούν το 99999999.99.

Υπηρεσίες (services) ​

ΤιμήΣημασία
saturdayΠαράδοση το Σάββατο.
epistrofiΠαράδοση / Παραλαβή: ο courier παραδίδει το δέμα και παραλαμβάνει ταυτόχρονα δέμα επιστροφής.
receive_from_receptionΟ παραλήπτης παραλαμβάνει το δέμα από το κατάστημα της courier.

Η υπηρεσία receive_from_reception (παραλαβή από κατάστημα της courier) είναι διαφορετική από το πεδίο receive_from_reception: true (παραλαβή από το δικό σας κατάστημα, χωρίς courier). Οι υπηρεσίες εφαρμόζονται όταν εκδίδεται το voucher, εφόσον τις υποστηρίζει η courier.

Παραλαβή από κατάστημα ​

Με receive_from_reception: true η παραγγελία γίνεται Παραλαβή από Κατάστημα: το courier_id αγνοείται (αποθηκεύεται χωρίς courier), δεν επιτρέπονται services ούτε locker_id, και η κατάσταση γίνεται store_pickup. Δεν χρειάζεται voucher.

Box Now ​

Για courier Box Now το locker_id είναι υποχρεωτικό και δεν επιτρέπονται services. Το locker_id είναι το ID της θυρίδας Box Now όπου θα παραδοθεί το δέμα.

Απάντηση αιτήματος ​

Επιτυχής δημιουργία: HTTP 201 με την παραγγελία μέσα στο κλειδί data, με τα πεδία που περιγράφονται στο GET /orders/{id} (μαζί με products και shipments, που είναι κενό). Κρατήστε το id για τις επόμενες κλήσεις (GET, PATCH, DELETE /orders/{id}).

Variable NameTypeDescription
dataObjectΗ νέα παραγγελία (order).
data.idIntegerΤο ID της παραγγελίας για τα /orders/{id}.
data.order_idStringΟ αριθμός που παρήγαγε το CourierHub.

Παράδειγμα σώματος αιτήματος (αντικαταβολή, με προϊόντα):

json
{
    "order_number": "#1001",
    "order_date": "2026-10-15T07:05:00Z",
    "recipient": {
        "name": "Μαρία Παπαδοπούλου",
        "phone": "694 123 4567",
        "email": "maria@example.com",
        "address": "Ερμού 25",
        "city": "Αθήνα",
        "postal_code": "105 63",
        "country": "gr"
    },
    "courier_id": 8,
    "payment_method": "cod",
    "shipping_cost": "3.50",
    "cod_cost": "1.50",
    "weight": "1.2",
    "notes": "Κουδούνι: Παπαδοπούλου",
    "products": [
        { "name": "Κούπα κεραμική", "sku": "MUG-01", "unit_price": "12.90", "quantity": 2 },
        { "name": "Σουβέρ (σετ 4)", "unit_price": "6.00", "quantity": 1 }
    ]
}

Παράδειγμα επιτυχημένης δημιουργίας (HTTP 201).

Το τηλέφωνο, ο ταχυδρομικός κώδικας και η χώρα έχουν κανονικοποιηθεί, το subtotal είναι το άθροισμα των προϊόντων (25.80 + 6.00) και το total_amount είναι 31.80 + 3.50 + 1.50.

json
{
    "data": {
        "id": 1,
        "order_id": "20261015101200482",
        "order_number": "#1001",
        "status": "pending",
        "status_label": "Εκκρεμής",
        "order_date": "2026-10-15T07:05:00Z",
        "recipient": {
            "name": "Μαρία Παπαδοπούλου",
            "phone": "6941234567",
            "email": "maria@example.com",
            "address": "Ερμού 25",
            "city": "Αθήνα",
            "postal_code": "10563",
            "country": "GR"
        },
        "receive_from_reception": false,
        "courier": {
            "id": 8,
            "name": "ACS"
        },
        "services": [],
        "locker_id": null,
        "payment_method": "cod",
        "subtotal": "31.80",
        "shipping_cost": "3.50",
        "cod_cost": "1.50",
        "total_amount": "36.80",
        "weight": "1.200",
        "notes": "Κουδούνι: Παπαδοπούλου",
        "has_shipment": false,
        "store": {
            "id": 1,
            "name": "Το Κατάστημά μου"
        },
        "products": [
            {
                "name": "Κούπα κεραμική",
                "sku": "MUG-01",
                "unit_price": "12.90",
                "quantity": 2,
                "total_price": "25.80"
            },
            {
                "name": "Σουβέρ (σετ 4)",
                "sku": null,
                "unit_price": "6.00",
                "quantity": 1,
                "total_price": "6.00"
            }
        ],
        "shipments": [],
        "created_at": "2026-10-15T07:12:00Z",
        "updated_at": "2026-10-15T07:12:00Z"
    }
}

Παράδειγμα χωρίς αντικαταβολή, με υπηρεσία Σαββάτου (HTTP 201).

Αίτημα:

json
{
    "order_number": "INV-2026/17",
    "recipient": {
        "name": "Γιώργος Νικολάου",
        "phone": "0030 2310 123456",
        "email": "giorgos@example.com",
        "address": "Τσιμισκή 40",
        "city": "Θεσσαλονίκη",
        "postal_code": "54623",
        "country": "GR"
    },
    "courier_id": 9,
    "services": ["saturday"],
    "payment_method": "stripe",
    "shipping_cost": "0",
    "products": [
        { "name": "Τσάντα πάνινη", "sku": "BAG-02", "unit_price": "24.00", "quantity": 1 }
    ]
}

Απάντηση:

json
{
    "data": {
        "id": 2,
        "order_id": "20261015101700155",
        "order_number": "INV-2026/17",
        "status": "pending",
        "status_label": "Εκκρεμής",
        "order_date": "2026-10-15T07:17:00Z",
        "recipient": {
            "name": "Γιώργος Νικολάου",
            "phone": "+302310123456",
            "email": "giorgos@example.com",
            "address": "Τσιμισκή 40",
            "city": "Θεσσαλονίκη",
            "postal_code": "54623",
            "country": "GR"
        },
        "receive_from_reception": false,
        "courier": {
            "id": 9,
            "name": "ELTA"
        },
        "services": [
            "saturday"
        ],
        "locker_id": null,
        "payment_method": "stripe",
        "subtotal": "24.00",
        "shipping_cost": "0.00",
        "cod_cost": "0.00",
        "total_amount": "24.00",
        "weight": null,
        "notes": null,
        "has_shipment": false,
        "store": {
            "id": 1,
            "name": "Το Κατάστημά μου"
        },
        "products": [
            {
                "name": "Τσάντα πάνινη",
                "sku": "BAG-02",
                "unit_price": "24.00",
                "quantity": 1,
                "total_price": "24.00"
            }
        ],
        "shipments": [],
        "created_at": "2026-10-15T07:17:00Z",
        "updated_at": "2026-10-15T07:17:00Z"
    }
}

Box Now και παραλαβή από κατάστημα

Box Now (με locker_id, χωρίς προϊόντα, με subtotal):

json
{
    "order_number": "1003",
    "recipient": {
        "name": "Ελένη Γεωργίου",
        "phone": "6977000111",
        "email": "eleni@example.com",
        "address": "Αγίου Δημητρίου 12",
        "city": "Πάτρα",
        "postal_code": "26221",
        "country": "GR"
    },
    "courier_id": 10,
    "locker_id": "4-123",
    "payment_method": "paypal",
    "subtotal": "18.00",
    "shipping_cost": "2.90"
}

Η απάντηση έχει "courier": {"id": 10, "name": "Box Now"}, "locker_id": "4-123", "products": [] και "total_amount": "20.90".

Παραλαβή από το κατάστημά σας (χωρίς courier_id):

json
{
    "order_number": "1004",
    "recipient": {
        "name": "Νίκος Ιωάννου",
        "phone": "6900000000",
        "email": "nikos@example.com",
        "address": "Ερμού 1",
        "city": "Αθήνα",
        "postal_code": "10563",
        "country": "GR"
    },
    "receive_from_reception": true,
    "payment_method": "other",
    "products": [
        { "name": "Κούπα κεραμική", "sku": "MUG-01", "unit_price": "12.90", "quantity": 1 }
    ]
}

Η απάντηση έχει "status": "store_pickup", "status_label": "Παραλαβή από Κατάστημα", "receive_from_reception": true και "courier": null.

Σφάλματα ​

Ο έλεγχος γίνεται σε δύο στάδια. Πρώτα ελέγχονται τα υποχρεωτικά πεδία και η μορφή κάθε πεδίου. Αν περάσουν, ελέγχεται ότι το order_number είναι ελεύθερο (409) και μετά οι κανόνες που συνδυάζουν πεδία (courier και locker_id / services, cod_cost και payment_method, ταχυδρομικός κώδικας και χώρα). Γι' αυτό, αφού διορθώσετε ένα 422, μπορεί να πάρετε δεύτερο 422 με άλλα πεδία.

HTTPcodeΠότε
409order_number_takenΥπάρχει ήδη μη διαγραμμένη παραγγελία του καταστήματος με αυτό το order_number (#1001 = 1001), ή ένα άλλο αίτημα δημιουργεί αυτή τη στιγμή παραγγελία με τον ίδιο αριθμό.
422validation_failedΛείπουν υποχρεωτικά πεδία ή δεν είναι έγκυρα. Το errors έχει τα προβλήματα ανά πεδίο (π.χ. recipient.phone, products.0.quantity).

Αριθμός παραγγελίας που υπάρχει ήδη (409 Conflict).

Αίτημα με "order_number": "1001", ενώ υπάρχει ήδη η #1001:

json
{
    "message": "An order with this order_number already exists in this store.",
    "code": "order_number_taken"
}

Αν δύο αιτήματα με τον ίδιο αριθμό φτάσουν ταυτόχρονα, το δεύτερο περιμένει το πρώτο και παίρνει το παραπάνω 409. Αν η αναμονή ξεπεράσει τα λίγα δευτερόλεπτα, παίρνει 409 με τον ίδιο code και message "Another request is writing an order with this order_number. Retry later.". Πριν ξαναδοκιμάσετε, ελέγξτε με το GET /orders?order_number=... αν η παραγγελία δημιουργήθηκε ήδη.

Παράδειγμα σφάλματος (κενό σώμα).

json
{
    "message": "The given data was invalid.",
    "code": "validation_failed",
    "errors": {
        "order_number": [
            "The order number field is required."
        ],
        "recipient": [
            "The recipient field is required."
        ],
        "recipient.name": [
            "The recipient.name field is required."
        ],
        "recipient.phone": [
            "The recipient.phone field is required."
        ],
        "recipient.email": [
            "The recipient.email field is required."
        ],
        "recipient.address": [
            "The recipient.address field is required."
        ],
        "recipient.city": [
            "The recipient.city field is required."
        ],
        "recipient.postal_code": [
            "The recipient.postal code field is required."
        ],
        "recipient.country": [
            "The recipient.country field is required."
        ],
        "payment_method": [
            "The payment method field is required."
        ]
    }
}

Παράδειγμα σφάλματος (μορφή πεδίων: "order_number": "WEB 1", "phone": "12-34").

json
{
    "message": "The given data was invalid.",
    "code": "validation_failed",
    "errors": {
        "order_number": [
            "The order number field format is invalid."
        ],
        "recipient.phone": [
            "The recipient.phone field format is invalid."
        ]
    }
}

Παράδειγμα σφάλματος (κανόνες μεταξύ πεδίων).

Courier ELTA με "locker_id": "L1", "payment_method": "stripe" με "cod_cost": "2.00" και "country": "GR" με "postal_code": "5462":

json
{
    "message": "The given data was invalid.",
    "code": "validation_failed",
    "errors": {
        "locker_id": [
            "The locker_id field is only allowed for Box Now shipments."
        ],
        "cod_cost": [
            "The cod_cost field is only allowed when payment_method is cod."
        ],
        "recipient.postal_code": [
            "A Greek postal code has 5 digits."
        ]
    }
}

Άλλα μηνύματα του ίδιου σταδίου:

ΠεδίοΜήνυμαΠότε
courier_idThe courier_id field is required unless receive_from_reception is true.Λείπει το courier_id (ή είναι null) χωρίς receive_from_reception: true.
courier_idThe courier_id must be one of your connected couriers (GET /api/v2/couriers).Η courier δεν είναι συνδεδεμένη στον λογαριασμό σας.
locker_idThe locker_id field is required for Box Now shipments.Courier Box Now χωρίς locker_id.
servicesServices are not available for store pickup or Box Now orders.services με Box Now ή με receive_from_reception: true.
recipient.postal_codeA Cyprus postal code has 4 digits.CY χωρίς 4 ψηφία.
recipient.postal_codeThe postal code may only contain letters, digits, spaces and dashes.Άλλη χώρα, μη έγκυρος κώδικας.

Παράδειγμα κλήσης ​

bash
curl -X POST https://courierhub.gr/api/v2/orders \
  -H "Authorization: Bearer chub_YOUR_API_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "order_number": "#1001",
    "recipient": {
      "name": "Μαρία Παπαδοπούλου",
      "phone": "6941234567",
      "email": "maria@example.com",
      "address": "Ερμού 25",
      "city": "Αθήνα",
      "postal_code": "10563",
      "country": "GR"
    },
    "courier_id": 8,
    "payment_method": "cod",
    "shipping_cost": "3.50",
    "cod_cost": "1.50",
    "products": [
      { "name": "Κούπα κεραμική", "sku": "MUG-01", "unit_price": "12.90", "quantity": 2 }
    ]
  }'

Μετά τη δημιουργία ​

  • Το voucher εκδίδεται με POST /shipments, με order_id το id της παραγγελίας από την απάντηση (όχι το order_id ή το order_number της), ή από το περιβάλλον πελάτη του CourierHub, όπως για κάθε παραγγελία. Η έκδοση δεν ενημερώνει κανένα e-shop. Ακύρωση με DELETE /shipments/{voucher}.
  • Μόλις εκδοθεί voucher, η παραγγελία εμφανίζεται με has_shipment: true, το voucher στο shipments του GET /orders/{id} και στο GET /shipments, και webhooks shipment.* στέλνονται κανονικά.
  • Από εκείνη τη στιγμή η παραγγελία δεν αλλάζει ούτε διαγράφεται από το API (409 order_has_shipment).

Released under the MIT License.