Rappi Connect Integration Guide
What is Rappi Connect?
Rappi Connect enables retailers to receive orders placed by customers on our platform. These orders can then be produced by retailers' staff using the tools and processes they already use to handle e-commerce orders.
Rappi Connect instantly integrates new orders into retailers' systems and manages the exchange of event notifications between Rappi and retailers throughout an order lifecycle. Receiving scheduled orders immediately allows retailers to maximize their picking staffs' productivity by utilizing valley (low demand) hours.
Important
Every new feature released by the Rappi Connect team improves the UX in integrated stores. As a Rappi Connect retailer, you must be committed to implementing these features within 8 weeks of release.
Integration Checklist
To successfully implement Rappi Connect:
Understand our order lifecycle and events and how those events impact on user experience in the app.
Understand which of your internal order fulfillment events should be mapped to ours.
Understand the limitations of your ERP and/or picking system that might prevent the implementation of advanced order exception processes (and how you can overcome them).
Develop webhooks to receive order-related events from Rappi.
Notify Rappi of ALL order fulfillment events that occur in your operation.
The Order Lifecycle
The lifecycle of an order in Rappi Connect can be summarized in seven events. These order events must be exchanged between the retailer and Rappi in real-time.
Rappi Connect deals with two distinct events types:
internal event
events sent from Rappi to the partner webhookexternal event
events that Rappi expects to receive from partners
Rappi must receive ALL events marked with the tag external event
.
Base url for external events
is /api/cpgops-integrations/
Examples:
- /api/cpgops-integrations/orders/events
- /api/cpgops-integrations/orders/{orderId}/cancel
All events sent from Rappi will be marked with the tag internal events
.
- order_created
internal event
The user places an order in one of our apps. Rappi will POST every new order to your webhook. Whenever you're unable to accept an order for whatever reason, your response must adhere to our integration error responses. This is extremely important to guarantee the integration reliability and makes triggering internal recovery flows possible.
On a successful response, Rappi expects to receive the external order id from retailers. Any event exchange (in both directions) will always use Rappi's order_id (internal order id). Make sure to maintain a mapping of those identifiers to properly publish and ingest order events.
POST /orders
Response
HTTP status code 201
- order_integrated
external event
You successfully ingested the order into your picking system or ERP, and it's now available to be assigned to a picker.
- released_to_picker
external event
Your picker starts the shopping mission for one or more orders. Picking must be completed at least 30 minutes before our delivery promise to the user. The delivery promise is found in each new order pushed by Rappi to your webhook; under the request-body property
delivery.delivery_time
.
- invoice_created
external event
Your picker has completed the shopping mission, i.e., items have been packaged and invoiced. This event tells Rappi the order is ready to be picked up by a courier.
Rappi notifies couriers that a new order is available for delivery when the order has been invoiced by the retailer.
- courier_assigned
internal event
When a courier accepts a delivery, Rappi will
PUT
the courier information to your delivery information webhook.
PUT /orders/{orderId}/delivery
Response HTTP status code 204
- order_delivered
internal event
Rappi will notify retailers every successful delivery at their webhook.
POST /orders/{orderId}/finish
Response HTTP status code 204
note
It is vital to understand the entire lifecycle to:
- guarantee the user experience in integrated stores
- monitor, and respond to, operational issues
warning
Failing to regularly notify Rappi of external order events might trigger our bots to temporarily pause your stores, leading to a loss in Gross merchandise value (GMV) and frustrating users that look for those stores on our platform.
Integration Error Responses
Integration error responses are a subtopic of the order created event. Whenever retailers are unable to accept a new order, the reason for its rejection must be properly communicated with 4XX HTTP error code and details provided in the reason-specific schema.
Integration errors are organized around eight groups.
c1 | c2 | c3 |
---|---|---|
Range | Group | Description |
10-19 | service dependencies | internal use only |
20-29 | retailers outages or errors | internal use only |
30-39 | basic order details | Missing basic order information |
40-49 | product information | Inconsistent product information (catalog, stock, price) |
50-59 | user information | Missing or inconsistent customer information |
60-69 | user address information | Incomplete or inconsistent customer address |
70-79 | delivery information | Missing or inconsistent delivery/departure time information |
80-99 | reserved | |
90-99 | reserved | |
0 | uncategorized | Order is unacceptable due to an uncategorized issue |
The response for most integration errors will follow the basicSchema
, which simply provides the identified error code as provided in the table below.
Table of error codes applicable to synchronous order validations:
c1 | c2 | c3 | c4 |
---|---|---|---|
Topic | Error Code | HTTP Code | Response |
order-id-missing | 30 | 400 | Basic error schema |
order-id-duplicated | 31 | 409 | Error 31 Schema |
store-not-found | 32 | 400 | Basic error schema |
total-value-inconsistent | 33 | 400 | Basic error schema |
products-not-found | 40 | 400 | Error 40 Schema |
products-stock-out | 41 | 400 | Error 41 Schema |
products-price-difference | 42 | 400 | Error 42 Schema |
user-first-name | 50 | 400 | Basic error schema |
user-last-name | 51 | 400 | Basic error schema |
user-identification | 52 | 400 | Basic error schema |
user-email | 53 | 400 | Basic error schema |
user-phone-number | 54 | 400 | Basic error schema |
address-street-address | 60 | 400 | Basic error schema |
address-number | 61 | 400 | Basic error schema |
address-neighborhood | 62 | 400 | Basic error schema |
address-city | 63 | 400 | Basic error schema |
address-state | 64 | 400 | Basic error schema |
address-zip-code | 65 | 400 | Basic error schema |
delivery-time | 70 | 400 | Basic error schema |
departure-time | 71 | 400 | Basic error schema |
uncategorized | 0 | 400 | Uncategorized schema |
Error Responses
Basic error schema
order-id-missing
order-id-duplicated
store-not-found
total-value-inconsistent
user-first-name
user-last-name
user-identification
user-email
user-phone-number
address-street-address
address-number
address-neighborhood
address-city
address-state
address-zip-code
delivery-time
departure-time
Error 31 Schema
order-id-duplicated
Error 40 Schema
products-not-found
Error 41 Schema
products-stock-out
Error 42 Schema
products-price-difference
Uncategorized schema
uncategorized
Exceptions
Exceptions are any event that prevents orders from following their regular path. Causes may include:
- one of the SKUs in the order is no longer available;
- the retailer is temporarily unable to invoice orders; e.g., the power is down in a store or warehouse, and fulfillment is paused until power is restored. This would result in a cancellation.
Whatever the reason, exceptions must be handled properly. Note that a single out-of-stock SKU is not a valid exception. We're not supposed to cancel an entire order because one single SKU isn't available; the user must be informed of the exact reason that led to a cancellation.
Rappi expects any exception event to be posted to the order notification endpoint endpoint. As previously mentioned, this endpoint receives all external events from retailers. Therefore, review the respective schemas that apply.
Proper handling of exception events are of utmost importance for:
- notifying customers they'll be receiving a partial order,
- adjusting the total amount charged for the order, and
- preventing stockout SKUs from showing in the app.
Partial Orders
A partial order is an exception. Sending a partial order to a customer is an outcome triggered by one or more SKUs in the order being unavailable at the time of integration or during the picker shopping mission. EVERY Rappi Connect retailer must have the capability to process partial orders. This prevents cancellation of an entire order when a stock out is identified.
When reducing product units or entirely removing a product from an order, Rappi expects these events to be posted to the order event notification endpoint.
The schema that applies depends on whether you are reducing units or removing the product from the order:
Important
When using remove_product_units
or remove_product
you must send only one product per request. If you have to remove more than one product perform additional requests.
- remove_product_units
external event
POST /orders/events
You must notify this the order endpoint whenever a reduction event occurs, i.e., if you reduce the number of units of any product in the order due to not having enough inventory at hand.
- remove_product
external event
POST /orders/events
Alternatively, in the event of not having any stock for an SKU at hand, you must notify this endpoint to remove that product entirely from the order
- reschedule_order
external event
POST /orders/events
If there is any operational problem in the store, we allow the retailer to reschedule the order to avoid cancellation. When this happens, the retailer will make a request to the following endpoint:
Customer-Driven Modifications
A customer can issue modifications after the order is placed for partners. The allowed modifications are changing the delivery slot, adding products and removing products.
How does it work?
When there is an order modification, Rappi will send a PUT with the updated order to the partner with the respective modification reason and the same order_id in integer format. The modifications are the following:
- schedule_modification
internal event
In this case the order object can be exactly the same an the one created before. Nevertheless, the retailer must calculate the differences and make them reflect in their picking system.
- products_updated
internal event
The order object contains the updated order. The retailer must calculate the differences and make them reflect in their picking system.
Medical Prescriptions
Rappi Connect has some partners integrated from pharma who sell medications that need prescriptions. For the generic order integration, relevant information should be added to the products property in the order.
The medical_prescriptions property should be added to the order creation request to the retailer.
When Orders are Cancelled
A cancellation is an exception. A cancellation may happen at either end; an order may either be cancelled by:
- the customer in our apps, or
- a retailer when unable to fulfill that order.
Whatever the origin of a cancellation, the other party must be promptly notified.
Whenever an order is cancelled by a customer, Rappi will POST an a notification to your cancellation webhook:
POST /orders/{orderId}/cancel
When orders are cancelled by a retailer, Rappi must be notified and informed of the reason that led to order cancellation. Notifications must be posted to the endpoint. Please review the cancellation reasons table next and the schema associated with each of them.
c1 | c2 | c3 |
---|---|---|
Topic | Cancel Reason Code | Response |
store-not-found | 32 | Basic cancel schema |
products-not-found | 40 | Cancel reason 40 schema |
products-stock-out | 41 | Cancel reason 41 schema |
products-price-difference | 42 | Cancel reason 42 schema |
products-discontinued | 43 | Cancel reason 43 schema |
uncategorized | 0 | Cancel uncategorized schema |
Cancel Payloads
Basic cancel schema
store-not-found
Cancel reason 40 schema
products-not-found
Cancel reason 41 schema
products-stock-out
Cancel reason 42 schema
products-price-difference
Cancel reason 43 schema
products-discontinued
Cancel uncategorized schema
uncategorized
Handshake
Handshake is the event that guarantees that the order has been delivered to the right RT.
The handshake feature allows a retailer to have more security and reduce the risk of fraud at the time of delivering an order to an RT to carry out the address of the same.
Requesting the handshake
To start the handshake flow, the retailer must make the following request:
POST /v1/orders/{orderId}/handshake
Successfull response
Among the codes returned to the retailer in the codes property, only one of them is valid and it will arrive at the RT of the order through its mobile application. The generated codes will expire after the date indicated in the expires_at field. Once the codes expire, the handshake can be requested again, at which time new codes will be generated with a different expiration date.
What are the possible outputs when requesting the handshake
Order not found
If the order with which you want to start the handshake process is not found in the Rappi system, the following response will be obtained with status code 404:
Order doesn't belong to the retailer
If the order does not belong to the retailer making the request, the following response with status 403 is obtained:
RT not assigned
To start the handshake process it is necessary that an RT is assigned to the order, otherwise the following error with status 400 is obtained:
Handshake already started
If the request to generate codes and start the handshake process is made again when there are still unexpired codes, the following error with status code 400 is obtained:
Validating the handshake
To validate if the RT to which the order is to be delivered is the one that is truly assigned to it, it must choose the correct one from the possible codes. To validate if a code given by an RT is correct, the retailer must make the following request:
POST /v1/orders/{orderId}/handshake/validate
Request
If the code sent in the validation request is correct, a response will be obtained with status code 204 and without any body. When this happens, the retailer can deliver the order to RT.
If the selected code is incorrect, an error with status code 400 and content like the following is obtained:
When validation doesn't match
By making a mistake with the validation of the handshake process, the retailer will receive a new set of possible codes and the correct RT will again receive the valid code for their application. It should be noted that there is a limit of 4 validation attempts per order. It should also be noted that the response for the fourth failed validation attempt is slightly different, as it does not include a new set of codes or an expiration date:
When retries are exhausted
If all the handshake validation attempts for an order are exhausted, the response that will be obtained from both the endpoint to request handshake, and from the endpoint to validate a handshake code will be an error with status code 400 with the following content:
When handshake request doens't exist
It should also be considered that if it is a question of validating a code without having made a handshake request before, or if the codes have expired, the following error response with status code 400 is obtained:
In case of ending the number of tries of the handshake the order doesn't have to be cancelled but, on the other hand, is not possible to start the process again from scratch. If that happens, the RT will have to contact Rappi's support, explain the situation and have the order released by them.