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.


GET/storecards

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

GET
/storecards
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>"
        },
        ...
    ]
}

POST/storecards

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

POST
/storecards
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>"
    }
}


GET/storecards/:identifier

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

GET
/storecards/:identifier
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>"
    }
}

PUT/storecards/:identifier

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

PUT
/storecards
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/storecards/:identifier

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

DELETE
/storecards/:identifier
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",
}

PATCH/storecards/:identifier

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

PATCH
/storecards/:identifier
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",
}

POST/storecards/:identifier/transactions

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 with 422.

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_id as 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

POST
/storecards/:identifier/transactions
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
    }
}

POST/storecards/:identifier/transactions/:transaction_id/reverse

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_id returned when the transaction was recorded, or by the list endpoint.

Request

POST
/storecards/:identifier/transactions/:transaction_id/reverse
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"
}

GET/storecards/:identifier/transactions

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). 404 when 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). null for adjustments whose direction is not recorded.

  • Name
    kind
    Type
    string
    Description

    points or balance.

  • Name
    is_reversal / reversed
    Type
    boolean
    Description

    Whether the row is a compensating row, and whether it has been reversed (reversal_transaction_id then holds the compensating row).

Request

GET
/storecards/:identifier/transactions
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
    }
}