| Previous Topic | Next Topic |
|---|---|
| Online Ordering Module 6: Check-in |
Online Ordering API Certification Tutorial - Module 7: Updating/Voiding Transactions
Goal
Update the details of a transaction or cancel the transaction if “Pending Check-ins” is enabled.
Prerequisites
-
You must have read the Online Ordering Module 6: Check-in and Online Ordering Module 5: Redemptions tutorials.
-
You should confirm with your Punchh representative that “Pending Check-ins” is properly configured in the Punchh platform for the business.
Use Cases and Context
Unlike the POS implementation, there is no receipt details call for online ordering. Instead, you can update a transaction within the pending points window by enabling the Pending Points feature and then sending an Update Loyalty Check-in API call. If you want to cancel a transaction within the pending points window, send a Void Loyalty Check-in call. Here are some common use cases:
-
After completing a transaction, the store must give a discount to the guest on an item, resulting in the receipt amount changing from $10 to $8, for example. The online ordering system updates the details for the transaction via an Update Loyalty Check-in API call to reflect the discount. If the guest is a loyalty guest, the loyalty earnings of the guest will decrease as the user will be granted points on $8 instead of $10 for the transaction.
-
A loyalty guest wants to cancel a transaction after the online order has been processed. The transaction can be canceled within the pending points window using the Void Loyalty Check-in call. Any points earned for the transaction by the guest are reversed, and if the guest redeemed an offer, the offer is returned to the guest’s account by voiding the redemption.
Applicable API Endpoints
| Endpoint Name/Path | Relevant Request Parameters | Relevant Response Parameters |
| Update Loyalty Check-in PUT {server-name}/api/auth/checkins/online_order |
client access_token transaction_no external_uid receipt_datetime subtotal_amount receipt_amount channel store_number The required parameters under the Menu Items object: - item_name - item_qty - item_amount - menu_item_type - menu_item_id - menu_family - menu_major_group - serial_number |
points first_name last_name The Checkin object shows the rewards of the user: - bar_code - created_at - external_uid - checkin_id - pending_points - pending_refresh - points_earned |
| Void Loyalty Check-in DELETE {server-name}/api/auth/checkins |
client external_uid |
N/A |
Example Code
Update Loyalty Check-in
The following code examples demonstrate how to send an Update Loyalty Check-in request. You must have the Pending Points feature enabled on the Punchh platform in order to use this endpoint. Please reach out to your Punchh representative for information about enabling the Pending Points feature.
curl --location --request PUT 'https://server-name-goes-here.punchh.com/api/auth/checkins/online_order' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-pch-digest: SIGNATURE_GOES_HERE' \
--header 'Authorization: ACCESS_TOKEN_GOES_HERE' \
--header 'User-Agent: Punchh/OnlineOrder/1.0/Web/BrowserVersion/OS_Type' \
--data-raw '{
"client": "CLIENT_GOES_HERE",
"transaction_no": "1111111111",
"external_uid": "1111-1111-1111-1111",
"receipt_datetime": "2022-09-16T07:42:03-00:00",
"store_number":"001",
"menu_items": [
{
"item_name": "Pizza with Pepperoni Topping",
"item_qty": 1,
"item_amount": 10.99,
"menu_item_type": "M",
"menu_item_id": "3001",
"menu_family": "Pizza",
"menu_major_group": "Pizza",
"serial_number": "1.0"
},
{
"item_name": "Pepperoni Topping",
"item_qty": 1,
"item_amount": 0.99,
"menu_item_type": "M",
"menu_item_id": "3002",
"menu_family": "Pizza Topping",
"menu_major_group": "Pizza",
"serial_number": "1.1"
},
{
"item_name": "Discount",
"item_qty": 1,
"item_amount": 0.99,
"menu_item_type": "D",
"menu_item_id": "4001",
"menu_family": "Discount",
"menu_major_group": "Discount",
"serial_number": "2.0"
},
{
"item_name": "Breadsticks",
"item_qty": 1,
"item_amount": 5.99,
"menu_item_type": "M",
"menu_item_id": "5001",
"menu_family": "Appetizer",
"menu_major_group": "Sides",
"serial_number": "3.0"
}
],
"subtotal_amount": 12.97,
"receipt_amount": 12.97,
"channel": "online_order"
}'
import json
from http_client import send_request
def update__loyalty_checkin():
path = "/api/auth/checkins/online_order"
http_verb = "PUT"
menu_items = [{"item_name": "Pizza with Pepperoni Topping", "item_qty": 1, "item_amount": 10.99, "menu_item_type": "M", "menu_item_id": "3001", "menu_family": "Pizza", "menu_major_group": "Pizza", "serial_number": "1.0"}, {
"item_name": "Pepperoni Topping", "item_qty": 1, "item_amount": 0.99, "menu_item_type": "M", "menu_item_id": "3002", "menu_family": "Pizza Topping", "menu_major_group": "Pizza", "serial_number": "1.1"}, {
"item_name": "Breadsticks", "item_qty": 1, "item_amount": 5.99, "menu_item_type": "M", "menu_item_id": "5001", "menu_family": "Appetizer", "menu_major_group": "Sides", "serial_number": "3.0"}]
receipt_amount = 0
for item in menu_items:
if item["menu_item_type"] == "M":
receipt_amount += item["item_amount"]
if item["menu_item_type"] == "D":
receipt_amount -= item["item_amount"]
body = json.dumps({
"client": "CLIENT_GOES_HERE",
"receipt_amount": receipt_amount,
"subtotal_amount": receipt_amount,
"store_number": "001",
"menu_items": menu_items,
"receipt_datetime": "2022-09-16T07:42:03-00:00",
"external_uid": "1111-1111-1111-1111",
"transaction_no": "111111111"
})
response = send_request(path, http_verb, body)
print(f"Response: {response}")
update_loyalty_checkin()
class UpdateLoyaltyCheckin
require_relative 'generate_signature.rb'
require_relative 'http_client.rb'
require 'json'
# Client for the environment that you are pointing the request to
CLIENT = "CLIENT_GOES_HERE"
PATH = "/api/auth/checkins/online_order"
HTTP_VERB = "PUT"
MENU_ITEMS = [{ item_name: "Pizza with Pepperoni Topping", item_qty: 1, item_amount: 10.99, menu_item_type: "M", menu_item_id: "3001", menu_family: "Pizza", menu_major_group: "Pizza", serial_number: "1.0" }, { item_name: "Pepperoni Topping", item_qty: 1, item_amount: 0.99, menu_item_type: "M", menu_item_id: "3002", menu_family: "Pizza Topping", menu_major_group: "Pizza", serial_number: "1.1" }, {item_name: "Discount", item_qty: 1, item_amount: 0.99, menu_item_type: "D", menu_item_id: "4001", menu_family: "Discount", menu_major_group: "Discount", serial_number: "2.0"}, {item_name: "Breadsticks", item_qty: 1, item_amount: 5.99, menu_item_type: "M", menu_item_id: "5001", menu_family: "Appetizer", menu_major_group: "Sides", serial_number: "4.0"}]
def self.update_checkin
receipt_amount = 0
MENU_ITEMS.each do |item|
if item[:menu_item_type] == "M"
receipt_amount += item[:item_amount]
end
if item[:menu_item_type] == "D"
receipt_amount -= item[:item_amount]
end
end
body = {client: CLIENT, receipt_amount: receipt_amount, subtotal_amount: receipt_amount, store_number: "001", menu_items: MENU_ITEMS, receipt_datetime: "2022-09-16T07:42:03-00:00", external_uid: "1111-1111-1111-1111", transaction_no: "1111111111", channel: "online_order"}.to_json
response = HttpClient::send_request(PATH, HTTP_VERB, body)
end
end
UpdateLoyaltyCheckin.update_checkin
Void Loyalty Check-in
The following code examples demonstrate how to send a Void Loyalty Check-in request. You must have the Pending Points feature enabled on the Punchh platform in order to use this endpoint. Please reach out to your Punchh representative for information about enabling the Pending Points feature.
curl --location --request DELETE 'https://server-name-goes-here.punchh.com/api/auth/checkins' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-pch-digest: SIGNATURE_GOES_HERE' \
--header 'Authorization: ACCESS_TOKEN_GOES_HERE' \
--header 'User-Agent: Punchh/OnlineOrder/1.0/Web/BrowserVersion/OS_Type' \
--data-raw '{
"client": "CLIENT_GOES_HERE",
"external_uid": "1111-1111-1111-1111"
}'
import json
from http_client import send_request
def void_loyalty_checkin():
path = "/api/auth/checkins"
http_verb = "DELETE"
body = json.dumps({
"client": "CLIENT_GOES_HERE",
"external_uid": "1111-1111-1111-1111"
})
response = send_request(path, http_verb, body)
print(f"Response: {response}")
void_loyalty_checkin()
class VoidLoyaltyCheckin
require_relative 'generate_signature.rb'
require_relative 'http_client.rb'
require 'json'
# Client for the environment that you are pointing the request to
CLIENT = "CLIENT_GOES_HERE"
PATH = "/api/auth/checkins"
HTTP_VERB = "DELETE"
def self.void_checkin
body = {client: CLIENT, external_uid: "1111-1111-1111-1111"}.to_json
response = HttpClient::send_request(PATH, HTTP_VERB, body)
end
end
VoidLoyaltyCheckin.void_checkin
Workflow
Punchh allows updating or voiding a transaction using the Update Loyalty Check-in call or the Void Loyalty Check-in call only if the pending points setting is enabled in the Punchh platform for the business. The pending points window begins when the receipt is generated, but the points enter the "points pending for approval" state when the Create Loyalty Check-in call is made. When the points actually get approved depends on the time-based configuration settings in the Punchh platform, which determine the duration of the pending points window (for examples, see Pending Points Feature Overview). The Update Loyalty Check-in call or the Void Loyalty Check-in call must be made within the pending points window. Contact your Punchh representative for more information about this Punchh platform configuration.
Updating a Transaction
You can update a Create Loyalty Check-in call by sending an Update Loyalty Check-in API call within the pending points window. When you send the Update Loyalty Check-in API call, you must use the same transactional identifiers in the request (external_uid and transaction_no), but reflecting the latest changes. For example, the Update Loyalty Check-in call might have an extra menu item and increased taxes and payment. The online ordering system needs to send the menu items to Punchh in the format prescribed in How To Send Menu Items to Punchh. API developers are responsible for sending the Menu Items object exactly how Punchh specifies in that topic. There is no flexibility in the way menu items are sent in the Update Loyalty Check-in API call. As long as you use the same transaction number and external UID in the Update Loyalty Check-in call and make the call within the pending points window, Punchh will update the transaction in the system. If the guest is a loyalty guest, the call will change the loyalty earnings accordingly.
Voiding a Transaction
After completing a transaction, the Void Loyalty Check-in API endpoint can be used to cancel a loyalty check-in within the pending points window. You must use the external_uid in the request. Transactions can be voided only within the pending points window (usually within 24 hours). In the case of loyalty guests, voiding a transaction cancels the check-in. If any loyalty points are deducted through redemption, the points are returned to the guest account by voiding the redemption, and any points earned during the check-in by the guest are reversed.
Best Practices
-
Once a transaction is voided/canceled, you must re-submit the transaction.
-
There is currently no proper way to reconcile a guest's points after the pending points window has expired or if the Pending Points feature is not enabled. Therefore, ensure that the order is finalized prior to making the Create Loyalty Check-in call.
Related Topics
How To Send Menu Items to Punchh