Storecards
Storecards are just like coupons a core concept of the wallet app platform. Member balance and points will be stored on a storecard. A storecard can be used to save points and can be used to pay for products.
The storecard model
The storecard model contains the information about a storecard itself. It also contains info on how it should be displayed in the apple wallet. The following properties are available:
Properties
- Name
title- Type
- string
- Description
The title of the storecard.
- Name
subtitle- Type
- string
- Description
The subtitle of the storecard.
- Name
organization- Type
- object
- Description
The organization object that belongs to the storecard, contains:
['identifier', 'name']
- Name
thumbnail_url- Type
- string|url
- Description
A valid url to the thumbnail image of a storecard.
- Name
primary_color- Type
- string
- Description
The primary color of the storecard.
- Name
text_color- Type
- string
- Description
The text color of the storecard.
- Name
balance_label- Type
- string
- Description
Currency type that should be displayed on the storecard while in the wallet.
- Name
date_label- Type
- string
- Description
Label that should be displayed for the passes expiration_date on the storecard while in the wallet (if provided).
- Name
description- Type
- string
- Description
The description of the storecard.
- Name
expires_at- Type
- timestamp
- Description
The expiration date of the storecard.
- Name
identifier- Type
- string
- Description
The unique identifier of the storecard.
- Name
image- Type
- string|url
- Description
The image of the storecard.
- Name
location_label- Type
- string
- Description
Label that should be displayed for the passes location on the storecard while in the wallet (if provided).
- Name
name_label- Type
- string
- Description
Label that should be displayed for the passes name on the storecard while in the wallet (if provided).
- Name
points_label- Type
- string
- Description
Label that should be displayed for the passes points on the storecard while in the wallet (if provided).
- Name
show_balance- Type
- boolean
- Description
Should the balance be displayed on the storecard while in the wallet.
- Name
show_brand- Type
- boolean
- Description
Should the location (brand) be displayed on the storecard while in the wallet.
- Name
show_name- Type
- boolean
- Description
Should the name be displayed on the storecard while in the wallet.
- Name
show_points- Type
- boolean
- Description
Should the points be displayed on the storecard while in the wallet.
- Name
show_start_date- Type
- boolean
- Description
Should the start date be displayed on the storecard while in the wallet.
- Name
show_status- Type
- boolean
- Description
Should the status be displayed on the storecard while in the wallet.
- Name
show_subtitle- Type
- boolean
- Description
Should the subtitle be displayed on the storecard while in the wallet.
- Name
show_title- Type
- boolean
- Description
Should the title be displayed on the storecard while in the wallet.
- Name
status_label- Type
- string
- Description
Label that should be displayed for the passes status on the storecard while in the wallet (if provided).
Note
Because a user can have access to multiple organizations we require a organization_id to be provided for most requests. We will also return an organization reference in each response.
List all storecards
This endpoint returns a list of all the storecards the currently authenticated user has access to.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.get- Type
- string
- Description
The scope required to access this endpoint.
Request
curl -X GET https://api.walletapp.co/storecards
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
Response
{
"message": "Request successful",
"data": [
{
"balance_label": "Euro",
"date_label": null,
"description": null,
"expires_at": null,
"identifier": "<storecard_id>",
"image": "<image_url>",
"location_label": "vestiging",
"name_label": "Name",
"organization": {
"name": "<organization_name>",
"identifier": "<organization_identifier>"
},
"points_label": "Points",
"primary_color": null,
"show_balance": 0,
"show_brand": 0,
"show_name": 1,
"show_points": 1,
"show_start_date": 0,
"show_subtitle": 0,
"show_title": 1,
"status_label": "Member",
"subtitle": "<subtitle>",
"text_color": null,
"title": "<title>"
},
...
]
}
Create a storecard
This endpoint allows you to create a storecard.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.store- Type
- string
- Description
The scope required to access this endpoint.
Request body
- Name
title- Type
- string|Required
- Description
The title of the storecard.
- Name
subtitle- Type
- string|Required
- Description
The subtitle of the storecard.
- Name
organization_id- Type
- string|Required
- Description
The organization id the storecard should be created for.
- Name
sponsor_url- Type
- string|Required
- Description
The webshop description of a storecard.
- Name
description- Type
- string
- Description
The description of the storecard.
- Name
thumbnail_url- Type
- string|url
- Description
A valid url to the thumbnail image of a storecard.
- Name
primary_color- Type
- string
- Description
A Hexadecimal color code for the primary color of the storecard (background color for the apple wallet pass).
- Name
text_color- Type
- string
- Description
A Hexadecimal color code for the text color of the storecard (text color for the apple wallet pass).
Request
curl -X POST https://api.walletapp.co/storecards
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"balance_label": "Euro",
"date_label": "<date_label>",
"description": "<description>",
"expires_at": "01-01-2022",
"location_label": "vestiging",
"name_label": "Name",
"organization_id": "<organization_id>",
"points_label": "Points",
"primary_color": "#ff00ff",
"show_balance": 1,
"show_brand": 1,
"show_name": 1,
"show_points": 1,
"show_start_date": 1,
"show_subtitle": 1,
"show_title": 1,
"status_label": "API LABEL",
"subtitle": "<subtitle>",
"text_color": "#FF22FF",
"title": "<title>"
}'
Response
{
"message": "Request successful",
"data": {
"balance_label": "Euro",
"date_label": null,
"description": "<description>",
"expires_at": "<expiration_date>",
"identifier": "<identifier>",
"image": null,
"location_label": "vestiging",
"name_label": "Name",
"organization": {
"name": "<organization_name>",
"identifier": "<organization_identifier>"
},
"points_label": "Points",
"primary_color": "#ff00ff",
"show_balance": 0,
"show_brand": 1,
"show_name": 1,
"show_points": 1,
"show_start_date": 0,
"show_subtitle": 1,
"show_title": 1,
"status_label": "API LABEL",
"subtitle": "<subtitle>",
"text_color": "#FF22FF",
"title": "<title>"
}
}
Inspect a storecard
The endpoint allows you to fetch a storecard by its identifier.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.get- Type
- string
- Description
The scope required to access this endpoint.
Route parameters
- Name
identifier- Type
- string
- Description
The id of the storecard you want to update.
Request
curl -X GET https://api.walletapp.co/storecards/:identifier
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
Response
{
"message": "Request successful",
"data": {
"balance_label": "Euro",
"date_label": null,
"description": "<description>",
"expires_at": "<expiration_date>",
"identifier": "<identifier>",
"image": null,
"location_label": "vestiging",
"name_label": "Name",
"organization": {
"name": "<organization_name>",
"identifier": "<organization_identifier>"
},
"points_label": "Points",
"primary_color": "#ff00ff",
"show_balance": 0,
"show_brand": 1,
"show_name": 1,
"show_points": 1,
"show_start_date": 0,
"show_subtitle": 1,
"show_title": 1,
"status_label": "API LABEL",
"subtitle": "<subtitle>",
"text_color": "#FF22FF",
"title": "<title>"
}
}
Update a storecard
This endpoint allows you to create a storecard.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.update- Type
- string
- Description
The scope required to access this endpoint.
Route parameters
- Name
identifier- Type
- string
- Description
The id of the storecard you want to update.
Request body
- Name
title- Type
- string
- Description
The title of the storecard.
- Name
subtitle- Type
- string
- Description
The subtitle of the storecard.
- Name
organization_id- Type
- string
- Description
The organization id the storecard should be created for.
- Name
sponsor_url- Type
- string
- Description
The webshop description of a storecard.
- Name
description- Type
- string
- Description
The description of the storecard.
- Name
thumbnail_url- Type
- string|url
- Description
A valid url to the thumbnail image of a storecard.
- Name
primary_color- Type
- string
- Description
A Hexadecimal color code for the primary color of the storecard (background color for the apple wallet pass).
- Name
text_color- Type
- string
- Description
A Hexadecimal color code for the text color of the storecard (text color for the apple wallet pass).
Request
curl -X PUT https://api.walletapp.co/storecards
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"balance_label": "Euro",
"date_label": "<date_label>",
"description": "<description>",
"expires_at": "01-01-2022",
"location_label": "vestiging",
"name_label": "Name",
"organization_id": "<organization_id>",
"points_label": "Points",
"primary_color": "#ff00ff",
"show_balance": 1,
"show_brand": 1,
"show_name": 1,
"show_points": 1,
"show_start_date": 1,
"show_subtitle": 1,
"show_title": 1,
"status_label": "API LABEL",
"subtitle": "<subtitle>",
"text_color": "#FF22FF",
"title": "<title>"
}'
Response
{
"message": "Request successful",
"data": {
"balance_label": "Euro",
"date_label": null,
"description": "<description>",
"expires_at": "<expiration_date>",
"identifier": "<identifier>",
"image": null,
"location_label": "vestiging",
"name_label": "Name",
"organization": {
"name": "<organization_name>",
"identifier": "<organization_identifier>"
},
"points_label": "Points",
"primary_color": "#ff00ff",
"show_balance": 0,
"show_brand": 1,
"show_name": 1,
"show_points": 1,
"show_start_date": 0,
"show_subtitle": 1,
"show_title": 1,
"status_label": "API LABEL",
"subtitle": "<subtitle>",
"text_color": "#FF22FF",
"title": "<title>"
}
}
Delete a storecard
The endpoint allows you to delete a storecard.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.delete- Type
- string
- Description
The scope required to access this endpoint.
Route parameters
- Name
identifier- Type
- string
- Description
The id of the storecard you want to update.
Request
curl -X delete https://api.walletapp.co/storecards/:identifier
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
Response
{
"message": "Request successful",
"data": "Storecard archived",
}
Restore a storecard
The endpoint allows you to restore a storecard.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.delete- Type
- string
- Description
The scope required to access this endpoint.
Route parameters
- Name
identifier- Type
- string
- Description
The id of the storecard you want to update.
Request
curl -X PATCH https://api.walletapp.co/storecards/:identifier
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
Response
{
"message": "Request successful",
"data": "Storecard restored",
}
Record a points transaction
Credit (positive points) or debit (negative points) a member's storecard by member UUID. The call is idempotent on reference: sending the same reference again does not change the balance and returns was_duplicate: true with the original transaction_id, so it is safe to retry after a timeout. A reference is unique per storecard; reusing it for another member, or with different amounts, returns 409.
The member's Wallet pass is refreshed after a successful change, and the transaction shows up in the points history in the dashboard.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
- Name
Idempotency-Key- Type
- string|optional
- Description
Optional. When sent it must equal
reference, otherwise the call is rejected with422.
Abilities
- Name
storecards.store- Type
- string
- Description
The scope required to access this endpoint.
Route parameters
- Name
identifier- Type
- string
- Description
The identifier of the storecard. It must belong to the organization of your token, otherwise
404.
Body parameters
- Name
member_id- Type
- string|Required
- Description
The member's UUID (
member_idas returned by the members endpoints). The member must have a pass on this storecard.
- Name
points- Type
- number|Required without balance
- Description
Signed points change. A debit that would take the card below zero is refused with
422(insufficient_points).
- Name
balance- Type
- number|optional
- Description
Signed balance change, for storecards that carry a balance. The same non-negative rules as the scanner apply (postpaid cards may go negative up to their limit).
- Name
description- Type
- string|Required
- Description
Shown in the points history (max 191 characters).
- Name
reference- Type
- string|Required
- Description
Your own unique id for this change, for example a receipt number (max 64 characters).
Errors
- Name
404- Type
- status
- Description
Storecard not found for your organization (
storecard_not_found) or member without a pass on it (member_not_found).
- Name
409- Type
- status
- Description
reference_conflict: the reference was used for another member or with different amounts.
- Name
422- Type
- status
- Description
Validation error,
insufficient_points,insufficient_balance, or the pass is blocked/disabled (pass_blocked,pass_disabled).
Request
curl -X POST https://api.walletapp.co/storecards/sc_8f3a1c/transactions
-H "Content-Type: application/json"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
-d '{
"member_id": "0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10",
"points": 25,
"description": "Receipt 4711",
"reference": "receipt-4711"
}'
Response (201 Created)
{
"data": {
"transaction_id": 1042,
"reference": "receipt-4711",
"was_duplicate": false,
"member_id": "0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10",
"points_delta": 25,
"balance_delta": 0,
"points": 125,
"balance": 0
}
}
Response on a retry (200 OK)
{
"data": {
"transaction_id": 1042,
"reference": "receipt-4711",
"was_duplicate": true,
"member_id": "0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10",
"points_delta": 25,
"balance_delta": 0,
"points": 125,
"balance": 0
}
}
Reverse a transaction
Reverses a transaction exactly once by writing a compensating transaction with the reference reverse-<original reference>. A second reversal is refused with 409 (already_reversed, including the id of the compensating transaction). A reversal itself cannot be reversed, and a credit cannot be reversed when the member already spent those points (422, insufficient_points).
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.store- Type
- string
- Description
The scope required to access this endpoint.
Route parameters
- Name
identifier- Type
- string
- Description
The identifier of the storecard.
- Name
transaction_id- Type
- integer
- Description
The
transaction_idreturned when the transaction was recorded, or by the list endpoint.
Request
curl -X POST https://api.walletapp.co/storecards/sc_8f3a1c/transactions/1042/reverse
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
Response (201 Created)
{
"data": {
"transaction_id": 1043,
"reference": "reverse-receipt-4711",
"was_duplicate": false,
"member_id": "0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10",
"points_delta": -25,
"balance_delta": 0,
"points": 100,
"balance": 0,
"reverses_transaction_id": 1042,
"reverses_reference": "receipt-4711"
}
}
Response on a second reversal (409)
{
"error": "already_reversed",
"message": "Transaction was already reversed",
"reversal_transaction_id": 1043,
"reversal_reference": "reverse-receipt-4711"
}
List transactions
Lists the transactions of a storecard, oldest first (ordered by transaction_id, so a poller can continue from the last id it saw). A transaction that touched both points and balance is returned as two rows with the same reference.
Required headers
- Name
Authorization- Type
- string
- Description
The token itself as a bearer token.
Abilities
- Name
storecards.get- Type
- string
- Description
The scope required to access this endpoint.
Query parameters
- Name
member_id- Type
- string|optional
- Description
Only the transactions of this member (UUID).
404when the member is unknown.
- Name
since- Type
- timestamp|optional
- Description
Only transactions created at or after this moment (for example
2026-10-01T00:00:00Z).
- Name
page- Type
- integer|optional
- Description
Page number, starting at 1.
- Name
per_page- Type
- integer|optional
- Description
Page size. Default 50, maximum 100 (larger values are capped).
Row fields
- Name
amount- Type
- number|null
- Description
Signed change (credits positive, debits and reversals of credits negative).
nullfor adjustments whose direction is not recorded.
- Name
kind- Type
- string
- Description
pointsorbalance.
- Name
is_reversal / reversed- Type
- boolean
- Description
Whether the row is a compensating row, and whether it has been reversed (
reversal_transaction_idthen holds the compensating row).
Request
curl -X GET "https://api.walletapp.co/storecards/sc_8f3a1c/transactions?member_id=0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10&since=2026-10-01T00:00:00Z&per_page=2"
-H "Accept: application/json"
-H "Authorization: Bearer <your_token>"
Response
{
"data": [
{
"transaction_id": 1042,
"member_id": "0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10",
"reference": "receipt-4711",
"type": "points_earned",
"kind": "points",
"amount": 25,
"description": "Receipt 4711",
"is_reversal": false,
"reversed": true,
"reversal_transaction_id": 1043,
"created_at": "2026-10-08T09:15:00+00:00"
},
{
"transaction_id": 1043,
"member_id": "0b7d5c1e-3f0a-4d51-9a64-2f5c1d8e7a10",
"reference": "reverse-receipt-4711",
"type": "points_used",
"kind": "points",
"amount": -25,
"description": "Reversal of receipt-4711",
"is_reversal": true,
"reversed": false,
"reversal_transaction_id": null,
"created_at": "2026-10-08T09:20:00+00:00"
}
],
"meta": {
"page": 1,
"per_page": 2,
"total": 2,
"last_page": 1
}
}
