Store-facing: Guide to Issuing Digital Receipts from Your Own App and Getting Webhook Notifications

developer webhook receipt api integration
About this guide
This guide targets the use case where a store or brand issues digital receipts from its own app and receives real-time notifications via Webhooks. It's for the case where a store sends receipts directly to its own customers (store.* scopes).

If you instead want to reference the purchase receipts of users already registered with Receipt Roller, across stores in a wallet app or similar, see the wallet app guide.

This guide walks through registering a developer app on ReceiptRoller, obtaining an access token via OAuth authentication, and then configuring a Webhook to receive receipt events in real time.

The main use case is when you want to provide digital receipts to your customers from your store's own app. You can deliver receipts under your own app's brand while leveraging ReceiptRoller's infrastructure.


Step 1: Register a developer app

  1. Log in to ReceiptRoller and open the dashboard of the business account you want.
  2. From the side menu, choose Developer → App list.
  3. Click the Create app button.
  4. Fill in the following.
    • App name: the name of your service, for example
    • Redirect URI: the URL that receives the OAuth authorization code (e.g. https://your-app.example.com/callback)
    • Scopes: select the scopes you need to receive receipts (see below)
  5. After creation, a Client ID and Client Secret are issued.
    The Client Secret is shown only once. Be sure to store it somewhere secure.

Scopes needed

When a store issues and references receipts for its own customers, the following scopes are needed.

Scope Purpose
store.orders.read Read order data
store.orders.write Update order status
store.products.read Read product information shown on receipts
store.customers.read Identify the customer a receipt is delivered to

Note: user.receipts.read and user.profile.read are for wallet-style apps where the customer links their own Receipt Roller account. They aren't needed when a store issues receipts itself.


Step 2: Obtain an access token via OAuth

Receipt Roller uses the OAuth 2.0 authorization code flow (with PKCE support).

1. Authorization request

Redirect the user to the following URL:

GET /oauth/authorize
  ?client_id=app_xxxxxxxxxxxxxxxx
  &redirect_uri=https://your-app.example.com/callback
  &response_type=code
  &scope=store.orders.read store.orders.write store.products.read store.customers.read
  &code_challenge=<S256 hash>
  &code_challenge_method=S256

2. Exchange the authorization code

Once the user consents, they're redirected back to redirect_uri with ?code=xxx appended. Exchange this code for an access token:

POST /api/v1/auth/token
Content-Type: application/json

{
  "grant_type": "authorization_code",
  "code": "xxx",
  "code_verifier": "<PKCE code verifier>",
  "client_id": "app_xxxxxxxxxxxxxxxx",
  "client_secret": "your-client-secret",
  "redirect_uri": "https://your-app.example.com/callback"
}

3. Response

{
  "access_token": "...",   // expires in: 1 hour
  "refresh_token": "...",  // expires in: 30 days
  "token_type": "Bearer",
  "expires_in": 3600
}

Send subsequent API requests with the Authorization: Bearer {access_token} header.


Step 3: Register a Webhook

With Webhooks, you can receive real-time notifications at a URL you specify whenever an event (such as order creation) occurs on Receipt Roller.

Registering from the UI

  1. Open the detail page of your developer app.
  2. Click the Add button in the Webhooks section.
  3. Register by choosing an HTTPS URL and the event types you want to receive.
  4. A signing secret is shown — it's shown only once. Be sure to save it.

Registering from the API

POST /api/v1/webhooks
Authorization: Bearer {access_token}
Content-Type: application/json

{
  "url": "https://your-app.example.com/hooks",
  "event_types": ["order.created", "order.updated"],
  "secret": "my-signing-secret"
}

Response on successful registration:

{
  "id": "wh_aBcDeFgHiJkLmNoP",
  "url": "https://your-app.example.com/hooks",
  "event_types": ["order.created", "order.updated"],
  "active": true,
  "created_at": "2026-04-14T09:00:00Z",
  "secret": "my-signing-secret"  // this value is returned only once
}

Available event types

Event Fires when
receipt.created A receipt is newly issued
receipt.updated A receipt is edited
receipt.deleted A receipt is deleted
order.created An order is newly created
order.updated An order's status changes
coupon.redeemed A coupon is redeemed
coupon.expired A coupon expires
customer.visited A customer check-in is recorded
test.ping For connection testing (sent manually)

Step 4: Receive and verify the Webhook

Requests sent from Receipt Roller include the following headers:

Header Content
X-RR-Signature sha256= + HMAC-SHA256 (signs the entire body)
X-RR-Event Event type (e.g. order.created)
X-RR-Delivery A unique ID per delivery (for idempotency checks)

How to verify the signature (C# example)

var secret = "my-signing-secret";
var rawBody = await Request.Body.ReadAllBytesAsync();
var expected = "sha256=" + Convert.ToHexStringLower(
    HMACSHA256.HashData(Encoding.UTF8.GetBytes(secret), rawBody));
var received = Request.Headers["X-RR-Signature"].ToString();

if (!CryptographicOperations.FixedTimeEquals(
        Encoding.UTF8.GetBytes(expected),
        Encoding.UTF8.GetBytes(received)))
{
    return Unauthorized(); // signature mismatch => invalid request
}

Payload format

{
  "id": "evt_a1b2c3d4e5f6",
  "event": "order.created",
  "timestamp": "2026-04-14T09:00:00Z",
  "organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "data": {
    "order_id": "ORD-20260414-ABCD",
    "organization_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "Pending"
  }
}

Returning a 2xx status is treated as a successful delivery.
On delivery failure, it's automatically retried up to 4 times: 1 minute, 10 minutes, and 1 hour later. If all 4 attempts fail, the Webhook is automatically disabled.


Step 5: Test the connection

After registering a Webhook, you can verify connectivity by sending a test:

POST /api/v1/webhooks/test/{webhook_id}
Authorization: Bearer {access_token}

Example response:

{
  "webhook_id": "wh_aBcDeFgHiJkLmNoP",
  "http_status": 200,
  "success": true,
  "delivered_at": "2026-04-14T09:00:01Z"
}

Check the delivery history:

GET /api/v1/webhooks/{webhook_id}/deliveries
Authorization: Bearer {access_token}

Summary

  1. Register a developer app and obtain a Client ID / Secret
  2. Select the scopes you need and obtain an access token via OAuth
  3. Register a Webhook endpoint and subscribe to events
  4. Verify the signature of received Webhooks and process the payload
  5. Confirm operation with a test send

If anything is unclear, also refer to the API documentation (/swagger).

Published: 2026-04-14 Updated: 2026-07-05