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

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.

Update Loyalty Check-in API

Void Loyalty Check-in API

Create Loyalty Check-in API

How To Send Menu Items to Punchh

Create Online Redemption API

Pending Points Feature Overview

Void Processed Redemption API

Copyright © 2025 PAR Technology Corporation. All rights reserved.
PAR Technology Corporation 8383 Seneca Turnpike, Suite 3 New Hartford, New York 13413 (315) 738-0600 legal@partech.com. PAR Tech is a leading global provider of software, systems, and service solutions to the restaurant and retail industries.
You may learn about its product offerings here.
Before using this application, please read the Limited License Agreement and the PAR Tech Terms of Use.