foodpanda logo
DocumentationAPI specification
Introduction
API

SFTP

FAQ#

Click below to jump to the topics:

How do I get the best out of the Pelican picking integration?#

  • READY_FOR_PICKUP and CANCELLED order statuses to be consumed by the webhook
  • Configurations: To secure your webhook configurations in Partner Portal, secrets can be utilised for the purpose it can be any string, we also accommodate basic authentication mechanism.
    • For example, if the webhook service uses partner as the username and randompassword as the password, then the value in Base64 encoding of partner: *randompassword, is cmFuZG9tcGFzc3dvcmQ=
    • Then the Authorization header field will appear as: Basic cmFuZG9tcGFzc3dvcmQ= (this needs to be added to the secret field in the Partner Portal)

What are the limitations of the Partner API/Orders (Pelican)?#

  • New orders created by customers on the Platform App are not forwarded to the webhook directly, only orders fulfilled and checkout by pickers are transmitted to the webhook with READY_FOR_PICKUP status
  • You can expect to receive only READY_FOR_PICKUP and CANCELLED as order status

How do I access the shop Integrations Plugin?#

  • All current Shops partners of any size can access the Shops Integrations plugin in Partner Portal, you will be given access by your account manager or during registration with us.
  • It is advised to limit the access to Shops plugins in Partner Portal to only those who need to perform a function for your business - this is because Partner Portal can contain sensitive information i.e. webhook configurations
  • Please reach out to your account manager if you do not know how to gain access to Partner Portal

What is Partner Portal and how do I get access?#

Partner Portal is a back office tool by which you can manage your stores. When you are onboarded to our platform our Account Management team will be providing you the access. Depending on your use privileges you can also manage the webhook and token configurations.

Following activities can be managed from Partner portal:

  • Integration configurations
    • Store operations
    • Create promotions
    • Update product availability & prices
    • Review orders across your stores
    • Identify issues and perform initial troubleshooting

What is the difference between "order_id", "external_order_id" and "order_code" and which one shall the Partner use for reconciliation purposes?#

order_id: 7384a9e4-c4e1-4820-873e-2cc637acec78– Unique identifier for order used in our backend services. If you want to query a single order using the GET endpoint you should use order_id

external_order_id: mxuv-2439-9sa5– platform order id, shown on Pelican device, external_order_id could be used in your reconciliation process

order_code: its an incremental value(resets after 9999) on orders used by riders for picking orders from store

How do I generate credentials to use Partner API/Orders?#

Please see the token management section here

How can I tell if an order was actually picked up after being cancelled? I need to know whether it should be treated as a final sale.#

Request to Account Manager to enable the post_pick_up field

How to identify the items with finite quantity and items with KG / weighted quantities in order payload?#

  • Each item in the order has pricing and original_pricing objects, & both objects have quantity field
  • pricing object contain picked quantity (adjusted by the picker) refer to the field Items.pricing.quantity
  • original_pricing object contains ordered quantity by the customer, refer to the field Items.original_pricing.quantity
  • For items with finite quantity, pricing_type will be UNIT, sharing both pricing and original_pricing objects. The pricing object contains the picked quantity by the picker. Items.pricing.quantity
{
"pricing": {
"pricing_type": "UNIT",
"unit_price": 0.69,
"vat_percent": 0,
"total_price": 0.69,
"quantity": 1,
"min_quantity": 0,
"max_quantity": 2
},
"original_pricing": {
"pricing_type": "UNIT",
"unit_price": 0.69,
"vat_percent": 0,
"total_price": 1.38,
"quantity": 2,
"min_quantity": 0,
"max_quantity": 2
},
}

For items with weight, pricing_type will be KG, sharing both pricing and original_pricing objects. The pricing object contains the actual picked/fulfilled weight(decimal value) by the picker i.e Items.pricing.weight. We also share quantity for weighted items however this will be default value 1 (can be ignored if you find it not useful)

{
"pricing": {
"pricing_type": "KG",
"unit_price": 0.69,
"vat_percent": 0,
"total_price": 0.69,
"quantity": 1,
"weight": 1.0,
"min_quantity": 0,
"max_quantity": 2
},
"original_pricing": {
"pricing_type": "KG",
"unit_price": 0.69,
"vat_percent": 0,
"total_price": 0.69,
"quantity": 1,
"weight": 1.0,
"min_quantity": 0,
"max_quantity": 2
}
}

Do we need to validate as client details from the client object provided in the order payload ?#

Depending on how you want store the orders of specific store you can use below field information to validate the store
store_id: xxxx, – Identifier of the store on Platform systems
external_partner_config_id: xxxx– if the Partner store/outlet has any internal identifier it must be mapped to this field. (Alert!:if you have SFTP integration, changing this configuration might affect SFTP updates, review from AM is required)

How can I use a testing environment for order management integrations?#

  • We have a sandbox environment which will be enabled automatically when a webhook is configured in the Partner Portal(Prerequisite: store POS integrations to be enabled & webhook should be configured in Partner Portal ).
  • Orders created from the sandbox environment can also be queried via GET endpoint.
  • You can support the AM by identifying a test store or onboarding a new test store that can be utilised for testing purposes before going Live.
  • The Sandbox environment will push simulated statues i.e. expect to receive RECEIVED, READY_FOR_PICKUP, CANCELLED and DISPATCHED statuses.
    – In production for Platform Picking or Picking integration scope i.e. with Pelican flow, order status are limited to only READY_FOR_PICKUP & CANCELLED

What is the difference between "sub_total" and "order_total" ? Which is the final order total Partner should consider?#

*sub_total: order items value includes tax & without discount
*order_total: final value that customers pay for the order, Partner can use order_total
sub_total to be utilised when you want to validate the total items value

What are the fields in the order payload and how can I use them?#

sample order payload

{
order_id: "807c225f-ac6d-445d-a074-ea960c892ca7",// used in GET endpoint
external_order_id: "qktu-ul1p", // visible on pelican
order_code: "546",
client: { //contains store information
id: "22438",
chain_id: "0aa64dc1-280b-4d1c-972a-28a15a14382a",
name: "qktu - chainname",
country_code: "tw",
store_id: "qktu",
external_partner_config_id: "462" //internal mapping for your stores
},
customer: { // customer information is masked
_id: "twxqg33o",
national_id: "",
tax_id: "",
first_name: "于**",
last_name: "**",
phone_number: "+88693****651",
delivery_address: {
country: "",
city: "",
street: "",
number: "",
latitude: 0,
longitude: 0,
company: "",
block: "",
building: "",
apartment: "",
entrance: "",
intercom: "",
floor: "",
suburb: "",
zipcode: "",
instructions: "",
formattedAddress: ""
}
},
comment: "",
items: [ // item level information
{
_id: "796ee50e-2cb5-41ec-8a06-4208fe15dcb3",
sku: "222316",
barcode: [
4710036604597
],
name: "#222316 | 靠得住冰爽棉28cm | 15 片 | #4710036604597",
pricing: { // contains information of fulfilled items
pricing_type: "UNIT",
unit_price: 85,
vat_percent: 0,
total_price: 170,
quantity: 2,
min_quantity: 0,
max_quantity: 2
},
original_pricing: { // contain information of item at order placement
pricing_type: "UNIT", // fo UNIT quatity hold information of any changes
unit_price: 85,
vat_percent: 0,
total_price: 170,
quantity: 2,
min_quantity: 0,
max_quantity: 2
},
container_deposit: 0,
discount: 0,
instructions: "",
status: "NOT_PROCESSED" // item level status
},
{
_id: "a5e42c90-351f-4c64-be7a-7dace4b96033",
sku: "146344",
barcode: [
4710098163773
],
name: "#146344 | 77脆可穀麥巧克力 | 36 g | #4710098163773",
pricing: {
pricing_type: "KG",–> // when pricing type is KG, weight field is availble in the pricing object, qunatity defualts to 1
unit_price: 7,
vat_percent: 0,
total_price: 14,
weight: 2.0,
quantity: 1,
min_quantity: 0,
max_quantity: 1
},
original_pricing: {
pricing_type: "KG",
unit_price: 7,
vat_percent: 0,
total_price: 14,
weight: 2.0,
quantity: 1,
min_quantity: 0,
max_quantity: 2
},
container_deposit: 0,
discount: 0,
instructions: "",
status: "NOT_PROCESSED" // item level status
}
],
order_type: "DELIVERY",
transport_type: "LOGISTICS_DELIVERY", // type delivery flow
payment: {
sub_total: 184, // sum of total items
order_total: 177, // amount paid by the customer contains fees,discounts
delivery_fee: 0,
service_fee: 2.39,
difference_to_minimum: 0,
discounts: [
{
name: "vh8o1buy",
value: -9.2
}
],
discount: -9.2,
container_charge: 0,
total_taxes: 8.32,
additional_fees: {
PriorityDeliveryFee: 0
},
type: "PAID"
},
cancellation: {
reason: "",
cancelled_by: "",
post_pickup: true // only visible for cancelled orders post order fulfilment
},
status: "CANCELLED", // order status
sys: {
created_at: "2023-09-01T07:41:17.733Z",
created_by: "Order Fulfilment",
updated_at: "2023-09-01T07:45:45.863Z",
updated_by: "Order Fulfilment",
webhook_status: ""
},
promised_for: "2023-09-01T08:06:11Z",
isPreorder: false
}

APITroubleshootingAPIOverview