Introduction
This document describes the process to generate a signature and usage of Ryde Merchant Api (v1).
Requirements
API url, App Id and App secret key from Ryde to make the request
Auth Callback URL (Required).
Order Notification Webhook URL. (Required)
Both Endpoints should be separate.
Server IPs (Optional)
Generate Signature
-
Ryde will provide a shared secret to sign the request body.
-
All our endpoints are using HMAC_SHA256 signatures
-
Signature is included in the header of the request.
-
Automatically process asset paths, so that minified and concatenated releases can exist in different directories
-
Request body are sent as JSON format.
-
The JSON keys ordering must be the same as in the document when generating the signature and in the request body
Example:
let secret = test_sk_3ce043df-20df-4f2e-b13c-93f96ff1f308"; let payload = { appId: 'test_app_ab24ee9e-b006-4ad4-abe4-13ffb5ed9ca1' } let signature = crypto.createHmac('sha256', secret).update(JSON.stringify(payload)).digest('hex'); let response = await fetch("/v1/merchant/auth", { method: 'POST', headers: { 'x-signature': signature, 'Content-Type': 'application/json' }, body: payload };
Auth API
This API will be used to obtain the Auth Code.
Ryde will provide:
- Secret Key
- APP ID
Sign the body with a secret and generate a signature.
Signature is included in the header of the request under the key x-signature.
Request body are sent as JSON format.
Merchant must provide a Callback URL.
This API will be used to obtain the Auth Code.
After validation, Ryde will generate an Auth Token and send it to the Merchant's Callback URL. .
This Token is valid for the X interval. (e.g 1 day)
API Path
POST => /v1/merchant/auth
Request
{
"headers": {
// Data Type => String (Required)
// Refer Generate Signature Section
"x-signature": "88df4e29-1dce-430f-9aa2-0656956cf3e3"
},
"body": {
// Data Type => String (Required)
// Provided by Ryde Team
"appId": "app_asd1231ad1231"
}
}
Response
{
// All APIs Follow Standard HTTP Status Code Responses. e.g 200 (Success), 400 (Bad Request) etc.
// Data Type => Boolean
// true => Success, false => Failed
"status": true,
// Data Type => String
// HTTP Status Code => 200, msg => 'Ok'
// HTTP Status Code => 400, msg => 'Bad Request'
// HTTP Status Code => 401, msg => 'Unauthorised'
// HTTP Status Code => 500, msg => 'Internal Server Error'
"msg": "Ok"
}
Callback API Request
// AUTH API Callback Request "headers": { "content-type": "application/json" }, "body": { // Data Type => String // Valid for X hours (e.g 24hrs) "token": "Bearer 3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac" }
Request RydeSEND Fare
Request fare based on pickup and delivery details
API Path
POST => /v1/merchant/service/rydesend/price
Request
{
"headers": {
// Data Type => String (Required)
// Refer Generate Signature Section
"x-signature": "b9e4d81a-30cb-4795-9026-77b3f115a331",
// Data Type => String (Required)
// Token received through Auth Callback
"authorization": "Bearer 3f3d0113-1350-4ade-aac8-6f2ddb9b4111"
},
"body": {
"scheduleAt": "2022-09-01T14:30:00.00Z",
"serviceType": "CAR",
"stops": [
{
"address": "531A Upper Cross St, Singapore 051531",
"coordinates": {
"lat": 1.2849756,
"lng": 103.8460415
}
},
{
"address": "1 Old Parliament Ln, Singapore 179429",
"coordinates": {
"lat": 1.2896931,
"lng": 103.8507292
}
},
{
"address": "107 North Bridge Rd, Singapore 179105",
"coordinates": {
"lat": 1.2907171,
"lng": 103.8503252
}
}
]
}
}
Response
"data": { "quotationId": "d3f11390c60a4dd1874cb14f594a11c2", "scheduleAt": "2022-09-13T07:18:38.00Z", "expiresAt": "2022-09-13T07:23:39.00Z", "stops": [ { "stopId": "ChIJa147K9HX3IAR-lwiGIQv9i4", "coordinates": { "lat": 1.3188848, "lng": 1103.8263779 }, "address": "1 Robin Rd, Singapore 258176" }, { "stopId": "ChIJzzgyJU--woARcZqceSdQ3dM", "coordinates": { "lat": 1.3188848, "lng": 103.8263779 }, "address": "1 Robin Rd, Singapore 258176" } ], "price": { "total": 20.2, "currency": "SGD" } }
Create Booking API
This API will be used to create a RydeSend Delivery Request.
API Path
POST => /v1/merchant/service/rydesend/book
Request
{
"quotationId": "d3f11390c60a4dd1874cb14f594a11c2",
"sender": {
"stopId": "ChIJa147K9HX3IAR-lwiGIQv9i4",
"floor": "01", // optional
"unit": "32", // optional
"name": "Jonh",
"phone": "+6582828282",
"remarks": "this is a note" // optional
},
"recipients": [
{
"stopId": "ChIJzzgyJU--woARcZqceSdQ3dM",
"floor": "01", // optional
"unit": "32", // optional
"name": "Jonathon",
"phone": "+6580808080",
"remarks": "this is a note" // optional
}
],
"metadata": {
"orderId": "zxcawdfasdfa",
"restaurantName": "ABC"
}
}
Request
"data": { "orderId": "f070bd30-a2af-43bc-bbf1-d98e4dfa78b8", "price": { "total": 20.2, "currency": "SGD" }, "shareLink":"https://share-web-view-prod.rydesharing.com/?code=70a58410f378fea2bd3aed2c5a2294c9" }
Cancel Booking API
-
This API will be used to cancel a RydeSend Delivery Request.
-
Booking will not be canceled if the trip has started.
API Path
POST => /v1/merchant/service/rydesend/price
Request
{
"headers": {
// Data Type => String (Required)
// Refer Generate Signature Section
"x-signature": "b9e4d81a-30cb-4795-9026-77b3f115a331",
// Data Type => String (Required)
// Token received through Auth Callback
"authorization": "Bearer 3f3d0113-1350-4ade-aac8-6f2ddb9b4111"
},
"body": {
"orderId": “3f3d0113-1350-4ade-aac8-6f2ddb9b4111”
}
}
Response
{
// Response
// All APIs Follow Standard HTTP Status Code Responses. e.g 200 (Success), 400 (Bad Request) etc.
// Data Type => Boolean
// true => Success, false => Failed
"status": true,
// Data Type => String
// HTTP Status Code => 200, msg => 'Ok'
// HTTP Status Code => 400, msg => 'Bad Request'
// HTTP Status Code => 401, msg => 'Unauthorised'
// HTTP Status Code => 403, msg => 'Forbidden'
// HTTP Status Code => 500, msg => 'Internal Server Error'
}
Webhook Order Notifications
Webhook allows merchant to receive all the activities occur to order (accepted, expired, completed,...). In order to make the webhook secure and merchant application assure that the webhook comes from an authoried system, the webhook request will include the “X-Ryde-Signature” with the value is the encrypted string as the method is following the previous session
Expired
-
All unmatched bookings will be expired in 10 mins from the booking time.
-
Ryde will send the following status to webhook.
{
"headers": {
"content-type": "application/json"
},
"body": {
// Data Type => String
// Unique Trip Id
"orderId": "3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac",
// Data Type => String
"status": "expired"
}
}
Matched
When the driver accepts the booking, Ryde will send the following status.
{
"headers": {
"content-type": "application/json"
},
"body": {
// Data Type => String
// Unique Trip Id
"orderId": "3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac",
// Data Type => String
"status": "accepted",
// Data Type => String
// For tracking and status updates of the trips
"trackingUrl": "https://share-web-view.rydesharing.com/?code=1b8ad339650a788ad641b8081d263334:e32ffb3b17eae16feec7a9a7b4a0a51c43c19b0bed7",
// Driver Details => JSON
"driverDetails": {
// Data Type => String (Required)
"name": "Happy juice",
// Data Type => String (Required)
// We only support SG numbers at the moment
"mobileNumber": "98765432",
// Driver Details => JSON
"vehicleDetails": {
"type": "car",
"model": "toyota innova"
}
},
}
}
Driver Arrived
This status will be sent when the driver arrives at the delivery pickup location.
{
"headers": {
"content-type": "application/json"
},
"body": {
// Data Type => String
// Unique Trip Id
"orderId": "3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac",
// Data Type => String
"status": "driverArrived"
}
}
Trip Started
This status will be sent when the driver starts the trip.
{
"headers": {
"content-type": "application/json"
},
"body": {
// Data Type => String
// Unique Trip Id
"orderId": "3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac",
// Data Type => String
"status": "tripStarted"
}
}
Trip Completed
This status will be sent when the driver delivers to the last stop / destination.
{
"headers": {
"content-type": "application/json"
},
"body": {
// Data Type => String
// Unique Trip Id
"orderId": "3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac",
// Data Type => String
"status": "completed",
// Data Type => String
"deliveryProof": "https://unsplash.com/photos/BFdSCxmqvYc"
}
}
1st - 5th Delivery Drop Off
-
This status will be sent for the 1st to 5th Delivery Dropoff.
-
For the 6th Delivery Dropoff, Ryde will send Completed status (refer to Completed Status)
{
// AUTH API Callback Request
"headers": {
"content-type": "application/json"
},
"body": {
// Data Type => String
// Unique Trip Id
"orderId": "3dbfde78-a6fa-4b69-a7f9-53ba1ed0d5ac",
// Data Type => String
// 1st delivery => firstDropoff
// 2nd delivery => secondDropoff
// 3rd delivery => thirdDropoff
// 4th delivery => fourthDropoff
// 45h delivery => fifthDropoff
"status": "firstDropoff",
// Data Type => String
"deliveryProof": "https://unsplash.com/photos/BFdSCxmqvYc"
}
}
HTTP Status Code
| HTTP Status Code | Description |
|---|---|
200 |
Indicate it is a success request. Response body will be defined on each api. |
400 |
Bad request. Some of the information passed is invalid. |
401 |
Unauthorized. Unable to authenticate the request. |
403 |
Forbidden |
404 |
Not found. |
406 |
Not acceptable. |
500 |
Server internal error. |