Developer Guide – Integrating with Delyva API

You are here:

For Store / Marketplace

In this case, the system owner will create an account with Delyva and have direct billing with Delyva, and all the merchants if there are more than one will be using the system owner’s account with Delyva.

For SaaS / Platform

In this case, the merchants or SaaS subscribers will create an account with Delyva and have direct billing with Delyva. SaaS platform owners will earn 1% of the order amount as revenue sharing by Delyva.

Recommended Settings For SaaS / Platform

In this case, there must be a settings/configuration page for the user to enter their API keys:

Delyva Settings

  • API Parameters
    • Company code: [text input]
    • Company ID: [text input]
    • User ID: [text input]
    • Customer ID: [text input]
    • Item Type: [dropdown: PARCEL/PACKAGE/BULKY]
  • Checkout Rates:
    • Enable/Disable [/]
    • Checkout Rates Adjustment
      • Adjustment type: [Mark-up / Discount]
      • Percentage rate: [Number: 0-100]
      • Flat rate: [Number:0-100]
      • *Checkout rate adjustment formula: [Delivery rate = service price + % rate + flat rate]
  • Free Shipping/Delivery when order total amount equal to or above (0=disable): [Number]

How to integrate with Delyva API?

API Documentation

You may refer to Delyva API Documentation – https://docs.api.delyva.com/.

Normally store or marketplace will be integrating with these endpoints:

  • Service > Price Quote API
  • Create Order > Create Order API
  • Create Order > Process/Confirm Order
  • Create Order > Get Order Details
  • Create Order > Cancel Order
  • Create Order > Print Label
  • Getting Delivery Order Status Updates via Webhook

 

Request API Header

{
“Content-Type”:”application/json”
“X-Delyvax-Access-Token”: <apiKey>.
}

Getting the API Keys

You can get the API keys in Delyva customer portal > Settings > API Integrations

delyva-api

  1. Sign up and Log on to Delyva customer portal
  2. Go to Settings > API Integrations
  3. Copy the API parameters: Company code, Company ID, User ID, Customer ID.
  4. Click Add a new key, enter any name and copy the generated API key “apiKey”.
  5. For webhook verification, you will need to use apiSecret. To get apiSecret, call GET /user and get user.apiSecret in the response.

Getting The List of Services & Delivery Rates

POST Price Quote

POST https://api.delyva.app/v1.0/service/instantQuote

{
“customerId”: 123, //mandatory
"origin": {
		"address1": "28 Jalan 5",
		"address2": "Taman Mesra",
		"city": "Kajang",
		"state": "Selangor",
		"postcode": "43000",
		"country": "MY",
		"coord": {
			"lat": "3.013478", 
			"lon": "101.779682"
		}	
},
"destination": {
		"address1": "F-11-19 Pacific Place",
		"address2": "Ara Damansara",
		"city": "Petaling Jaya",
		"state": "Selangor",
		"postcode": "47301",
		"country": "MY",
		"coord": {
			"lat": "3.11100853226846",
			"lon": "101.58726936290537"
		}	
},
"extId": "your-internal-vendor-id", //optional
"weight": {
		"unit": "kg",
		"value": 0.9000
},
“itemType”: <itemType> //optional eg PARCEl/PACKAGE/FOOD/BULKY,
"inventory": [ 
    { "weight": { "value": 1, "unit": "kg" },"dimension": { "unit": "cm", "width": 10, "length": 15, "height": 5 }, "quantity": 1 }, 
            { "weight": { "value": 0.5, "unit": "kg" }, "dimension": { "unit": "cm", "width": 10, "length": 15, "height": 5 }, "quantity": 1 } 
    ],
}

From the response, you will need to save selected service value – services[selected-service].serviceCompany.companyCode . You will use this value when creating the delivery order later on. Take note of the service-supported item types.

If your platform will be using instant delivery or same-day delivery services for address accuracy and to avoid any issues with the pick-up and delivery process, it is best if your system submits origin and destination coordinates (coord{lat,lng}). If your system does not have the coordinates, do not submit “coord” at all, and Delyva will geocode the address but it will not be as accurate, most of the time will only be building-level, or street-level accurate.

You can also filter by service type:

{
..
"serviceType":"INSTANT",
}

Service type available:

  • NDD:  Next Day Delivery Courier Services (Pick-up services)
  • NDD-DROP: Next Day Delivery Courier Services (Drop-off services)
  • COD-NDD: Next Day Delivery Courier Services with Collect Cash On Delivery Service (COD) (Pick-up services)
  • COD-NDD-DROP: Next Day Delivery Courier Services with Collect Cash On Delivery Service (COD) (Drop-off services)
  • INSTANT – Instant Delivery Courier Services (1-2 hours)
  • SD – Same-Delivery Courier Services (3-4 hours)
  • INTERNATIONAL – International Courier Services
  • MOTO – Motorcycle Transport Services

 

Create a Delivery Order

Once buyers have paid for the order, you may call POST Create Order API and set process: false, to create the delivery order as a draft.

POST Create Order API

POST https://api.delyva.app/v1.0/order

{
    "customerId": 123,
    "process": false, //if this is false, delivery order will be created as draft
    "serviceCode": <services[selected-service].serviceCompany.companyCode>,
    “source”: "your-system-code”, //add this source so we could identify this order coming from your system
    "extId": "your-internal-vendor-id", //optional
    "referenceNo": "your-internal-order-reference-number", //optional
    "note": "order-note",
    "waypoint": [{
        "type": "PICKUP", //this means origin / sender info
        "scheduledAt": "2020-12-24T12:00:00+0800",
        "note": "optional note to personnel at this waypoint",
        "inventory": [
            {
                "name": "Mee Kari",
                "type": <itemType>, //you can get available item type from selected service
                "price": {
                    "amount": "10.50",
                    "currency": "MYR"
                },
                "weight": {
                    "value": 1,
                    "unit": "kg"
                },
                "dimension": { "unit": "cm", "width": 10, "length": 15, "height": 5 },
                "quantity": 1,
                "description": ""
            },
            {
                "name": "Ayam Goreng",
                "type": <itemType>, //you can get available item type from selected service
                "price": {
                    "amount": "8.00",
                    "currency": "MYR"
                },
                "weight": {
                    "value": 0.5,
                    "unit": "kg"
                },
                "dimension": { "unit": "cm", "width": 10, "length": 15, "height": 5 },
                "quantity": 1,
                "description": ""
            }
        ],
        "contact": {
            "name": "Test Sender",
            "email": "[email protected]",
            "phone": "60124433300",
            "unitNo": "",
            "address1": "157, Jalan Ampang",
            "address2": "",
            "city": "Wilayah Persekutuan",
            "state": "Kuala Lumpur",
            "postcode": "55000",
            "country": "MY",
            "coord": { "lat": "3.013478", "lon": "101.779682" }
        }
    },
    {
        "type": "DROPOFF", //this means delivery / receiver info
        "scheduledAt": "2020-12-24T13:00:00+0800",
        "note": "optional note to personnel at this waypoint",
        "inventory": [
            {
                "name": "Mee Kari",
                "type": <itemType>, //you can get available item type from selected service
                "price": {
                    "amount": "10.50",
                    "currency": "MYR"
                },
                "weight": {
                    "value": 1,
                    "unit": "kg"
                },
                "dimension": { "unit": "cm", "width": 10, "length": 15, "height": 5 },
                "quantity": 1,
                "description": ""
            },
            {
                "name": "Ayam Goreng",
                "type": <itemType>, //you can get available item type from selected service
                "price": {
                    "amount": "8.00",
                    "currency": "MYR"
                },
                "weight": {
                    "value": 0.5,
                    "unit": "kg"
                },
                "dimension": { "unit": "cm", "width": 10, "length": 15, "height": 5 },
                "quantity": 1,
                "description": ""
            }
        ],
        "contact": {
            "name": "Mr Receiver",
            "email": "[email protected]",
            "phone": "60124433300",
            "mobile": "60124433300",
            "unitNo": "6-8",
            "address1": "MRT Sungai Jernih (SBK33)",
            "address2": "1, Kampung Sungai Kantan",
            "city": "Kajang",
            "state": "Selangor",
            "postcode": "43000",
            "country": "MY",
            "coord": { "lat": "3.11100853226846", "lon": "101.58726936290537" } 
        }
    }]
}

From the response, you will need to save order.id which you will be used in other API endpoints.

Take note, delivery order total weight will be taken into account of all inventory unit weight x quantity. Eg. Total weight = 0.5 kg x 4 pc = 2.0kg

If your platform will be using instant delivery or same-day delivery services, for address accuracy and to avoid any issues with the pick-up and delivery process, it is best if your system submits origin and destination coordinates ( coord{lat,lng}). If your system does not have the coordinates, do not submit “coord” at all, and Delyva will geocode the address but it will not be as accurate, most of the time will only be building-level, or street-level accurate.

Process/Confirm Draft Order

Once the merchant has prepared/packed the package, call POST Process/Confirm Order to process the delivery order. You may also call this API in advance with the scheduled date & time if you are sure the package will be ready by the scheduled date & time.

POST {{API_ENDPOINT}}/v1.0/order/<:orderId>/process
{
	"serviceCode": "",
	"originScheduledAt": "",
	"destinationScheduledAt": ""
}

Get the Tracking Number and Delivery Order Details

Use the order.id in Create Order API response to get tracking number / consignment number, call GET Get Order Details API > response “consignmentNo”.

GET {{API_ENDPOINT}}/v1.0/order/<:order_id>

You can also get driver information from this API response: order.personnel.

Cancel a Delivery Order

To cancel any order, call POST Cancel Order API.

POST {{API_ENDPOINT}}/v1.0/order/<:orderId>/cancel

Cancellation rule

  • For courier services, you can only cancel the delivery order before order.statusCode equals to 110 (Label has been printed). For cancellation after this status code, please contact Delyva customer support. This rule is set due to some merchants proceeding to send the package to the couriers even after the delivery order has been canceled.
  • For instant and same-day delivery services, you can only cancel the delivery order before order.statusCode equals to 200 (Driver has accepted the order). This is to respect drivers’ effort and time in performing their duties.

Print Delivery Label

To print a shipping label/consignment label/ airway bill (AWB), simply call GET Print label API.

GET {{API_ENDPOINT}}/v1.0/order/<:orderId>/label?companyId=<:companyId>

The API will generate a label in PDF format, you can also put a link in your system [Print label] and open a new tab to print the label.

Getting Order Status Updates

To get real-time delivery order status updates, please subscribe to

  • Subscribe to Webhook(s)
  • Webhook: order.created
  • Webhook: order.failed
  • Webhook: order_tracking.change
  • Webhook: order_tracking.update

If you decide to show real-time driver movement, you may embed this real-time map with ETA URL (display this only for orders with statusCode > 200 and < 700): https://my.delyva.app/customer/rmap?trackingNo=

Subscribe to Webhook

You can add your webhook URL in Delyva customer portal > Settings > Webhook.

Add webhook manually

You may programmatically subscribe to any of the webhook by calling the POST Subscribe API.

 

Order Tracking Status Updates

Example payload for order_tracking.update and order_tracking.change  https://gist.github.com/suhaimi-hz/8b20cfa4fd12686c6fda2ab94121934c

{
  companyId: '2cab0b07-7a5d-4971-aeba-5ffac537a455',
  orderId: '6264954f-014b-4fe9-b077-a8864511f518',
  customerId: 32,
  userId: '33aee880-003c-11ea-b96b-d53dda460f07',
  consignmentNo: '000002009ASD',
  statusCode: 400,
  statusText: 'In transit',
  description: 'In-transit by personnel',
  location: '-',
  driverId: 126,
  taskId: 2149,
  createdAt: '2021-01-11T16:10:48.237Z',
  id: 2641,
  coord: { lon: 101.7381374, lat: 3.1401939 },
  personnel:
   { name: 'Suhaimi Pic1',
     phone: '60137778595',
     vehicleName: '-',
     vehicleType: '-',
     vehicleRegNo: '-' },
  arrival:
   { distance: { value: 2232, unit: 'm' },
     duration: { value: 286, unit: 's' },
     accuracy: 1 },
  invoiceId: null
}

Example payload order.created / order.updated / order.failed (the same as GET Get Order Details response without “data”)

{
    "id": "ca3ad567-4e50-4f7e-bb86-3732a1f1acfd",
    "companyId": "9e0aed8a-5c67-42a4-82b6-e01bf7687f31",
    "userId": "c2f29360-f62d-11ea-ba2e-99a2a4722cf9",
    "customerId": 414,
    "serviceId": 297,
    "serviceCode": "NJVMY",
    "price": {
      "amount": 4.33,
      "currency": "MYR"
    },
    "revenue": {
      "amount": 1.19,
      "currency": "MYR"
    },
    "commission": {
      "amount": 3.14,
      "currency": "MYR"
    },
    "distance": {
      "unit": "km",
      "value": 2.42
    },
    "weight": {
      "unit": "kg",
      "value": 0.1
    },
    "cod": {
      "amount": 0,
      "currency": "MYR"
    },
    "consignmentNo": "DM003675M",
    "paymentTerm": "debit",
    "itemType": "PARCEL",
    "itemTypeId": 14,
    "dimension": {
      "unit": "cm",
      "width": 0,
      "height": 0,
      "length": 0
    },
    "statusCode": 110,
    "status": "ready",
    "createdAt": "2021-05-04T23:28:21.705Z",
    "updatedAt": "2021-05-06T13:59:27.793Z",
    "deletedAt": null,
    "failedReason": "",
    "promoCode": "",
    "vehicleId": null,
    "invoiceId": "a8fbec6b-8ccf-47e1-ae40-30ad5fd68b25",
    "discountPrice": "0.00",
    "discount": "0.00",
    "personnelId": null,
    "note": "",
    "extId": "",
    "extIdType": "",
    "serviceAddon": [],
    "rating": null,
    "ratingNote": "",
    "agentCommission": null,
    "billing": {
      "city": "-",
      "name": "-",
      "email": "[email protected]",
      "phone": "60123456789",
      "state": "Selangor",
      "mobile": "",
      "unitNo": "",
      "country": "MY",
      "address1": "-",
      "address2": "-",
      "postcode": "-"
    },
    "paymentMethodId": 0,
    "cancelledReason": null,
    "source": "api",
    "promoValue": "0.00",
    "cron": 0,
    "metadata": {},
    "personnel": null,
    "surcharge": "0.00",
    "commodityId": "",
    "pluginId": null,
    "requestPickup": false,
    "insurance": null,
    "waypoint": [
      {
        "id": "wp_nE5tscYM1VMWVgMwGzUbhP",
        "orderId": "ca3ad567-4e50-4f7e-bb86-3732a1f1acfd",
        "no": 1,
        "inventory": [
          {
            "name": "Parcel",
            "type": "PARCEL",
            "price": {
              "amount": 0,
              "currency": "MYR"
            },
            "action": "P",
            "weight": {
              "unit": "kg",
              "value": 0.1
            },
            "quantity": 1,
            "description": "-"
          }
        ],
        "contact": {
          "city": "Petaling Jaya",
          "name": "Ahmad",
          "coord": {
            "lat": "3.11283",
            "lon": "101.59857"
          },
          "phone": "60123456789",
          "state": "Selangor",
          "mobile": "60123456789",
          "country": "MY",
          "address1": "Ara Damansara",
          "postcode": "47301",
          "sortCode": "KV"
        },
        "type": "PICKUP",
        "description": "-",
        "status": "pending",
        "note": "-",
        "scheduledAt": "2021-05-04T23:28:21.723Z",
        "createdAt": "2021-05-04T23:28:21.723Z",
        "updatedAt": "2021-05-04T23:28:23.607Z",
        "deletedAt": null,
        "cash": {
          "amount": 0,
          "currency": "MYR"
        },
        "placeId": null,
        "actualScheduledAt": null,
        "startAt": "2021-05-04T16:00:21.723Z",
        "actualStartAt": null
      },
      {
        "id": "wp_rS2vgBusBQq9GLPztKUNmQ",
        "orderId": "ca3ad567-4e50-4f7e-bb86-3732a1f1acfd",
        "no": 2,
        "inventory": [
          {
            "name": "Parcel",
            "type": "PARCEL",
            "price": {
              "amount": 0,
              "currency": "MYR"
            },
            "action": "D",
            "weight": {
              "unit": "kg",
              "value": 0.1
            },
            "quantity": 1,
            "description": "-"
          }
        ],
        "contact": {
          "city": "Petaling Jaya",
          "name": "Ali",
          "coord": {
            "lat": "3.1102867",
            "lon": "101.5857838"
          },
          "phone": "60123456789",
          "state": "Selangor",
          "mobile": "60123456789",
          "country": "MY",
          "address1": "Pacific Place, Ara Damansara",
          "postcode": "47301",
          "sortCode": "KV"
        },
        "type": "DROPOFF",
        "description": "-",
        "status": "pending",
        "note": "-",
        "scheduledAt": "2021-05-04T23:33:22.288Z",
        "createdAt": "2021-05-04T23:28:21.723Z",
        "updatedAt": "2021-05-04T23:28:23.607Z",
        "deletedAt": null,
        "cash": {
          "amount": 0,
          "currency": "MYR"
        },
        "placeId": null,
        "actualScheduledAt": null,
        "startAt": "2021-05-04T23:30:22.288Z",
        "actualStartAt": null
      }
    ],
    "paymentMethod": "Credit"
 }

How to test your order tracking status updates webhook?

  1. Using the above samples of webhook payload, you can manually send the payload using Postman to your webhook URL.
  2. Download DelyvaX Driver App (only available in Android) and log in using the same development customer login. Notify us and we will activate you as a driver to update the status from driver acceptance to pick-up success to delivery successful.

 

Addons: Collect Cash On Delivery (COD) / Insurance Premium

  1. Send a normal price quote and get the list of services.
  2. Then, the customer/merchant selects a service with an add-on, then, send another Price Quote API request with the selected service code and add-on value.

Price Quote API

PriceQuote for COD (addon id: -1)

serviceAddon: [
		{id: -1, value: "500"}
]

PriceQuote for Insurance (addon id: -3)

serviceAddon: [
		 {id: -3, value: "400"}
]

PriceQuote for both Insurance & COD

serviceAddon: 	[
		{id: -1, value: "500"},
	 	{id: -3, value: "400"}
]

Create Order API

For insurance premium

Create Order API, add

insurance = { currency: "MYR",amount: 1000 }

 

For Cash On Delivery

Create Order API, add

cod = { currency: "MYR",amount: 1000 }

Bonus: Programmatically authenticate, generate API key and get latest customer’s wallet balance

  1. Authenticate
  2. Create API key
  3. Get the customer’s latest wallet balance

 

1. Authenticate

POST https://api.delyva.app/v1.0/auth/login

Sample request:

{
"companyCode": "<companyCode>",
"username": "<email>",
"password": "<password>"
}'

Sample response:

{
"data": {
"accessToken":
..
}
}

* Use data.accessToken as Bearer token when requesting #2 Create an API Key.

2. Create and get the API key

POST https://api.delyva.app/v1.0/auth/personalAccessToken

Request:

{"name":"<API key name>"}

—-
Response (Store token as API key and use it for any new request):

{
"companyId":"xx",
"id":"xx",
"token":"xx", <--- API key
"userId":"xx",
}

3. Price Quote API

GET https://api.delyva.app/v1.0/customer

Response:
{
'data':{
'walletBalance': 10.00
}
}
Was this article helpful?
Dislike 0