Points Exchange API

Use these APIs to perform points exchange transactions and offer new exchange options to your customers.

Exchange

POST /transactions

The following types of of exchange options are currently supported by the qiibee API

All points_to_external_rewards requests have been migrated to exchange type. Depending on the value of brandB_token_id that's passed, determines the exact type of exchange.

To get the value of brandB_token_id, please check the Exchange partnerships endpoint.

This transaction involves two brands, Brand A (points to exchange from) and Brand B (points to exchange to). For these transactions to work, it is important that the exchange is allowed from Brand A to Brand B. This is always one way. Head over to the Loyalty Admin Dashboard to check if the exchange partnership is in effect. For more info, visit Exchange Currencies & NFTs - qiibee.

The value of the points credited, will depend on the offramp value of Brand A's points and the onramp value of Brand B's points. The exchange rate is calculated as follows

exchange rate = Brand A token offramp value ÷ Brand B token onramp value

The value of the cryptocurrency that is credited, will depend on the market rate of said currency at the time this API call is made. Note that exchange to crypto is not available in the sandbox API.

The following fields are optional:

  • exchange_rate_override: number - use this field to specify a different exchange rate from what you've configured.

    • eg. 1 point is 40 airline miles but you want to change it to 80 for a particular user based on their tier.

    • It will not overwrite the stored exchange rate

If you do not wish to persist membership info for users you can send it with every request but for a better customer experience, we encourage you to store it using the memberships APIs in the Users API section.

If you're trying to use this endpoint in the sandbox, use one of these FFP numbers when exchanging to Etihad Sandbox Points, since the FFP number will be validated.

  • 100014486294

  • 100014486283

If you try to exchange more points than the user currently has, you'll receive a 400. The points/miles to be received will be calculated as the floor of the value obtained after multiplying the points to be burned with the exchange rate. When exchanging to crypto, the floor is not applied to the amount of crypto to be received.

Note:

If you are a light integration user, please make sure that you have registered your webhook URL with us. Head over to Webhooks to learn more. We will call this URL when an exchange transaction has occurred so you can credit the points to your user.

Transaction reversal: In the event that an exchange transaction fails for any reason, qiibee will initiate a reversal for the failed exchange transaction. You can choose to notify your users regarding the failure via email. To setup the reversal email for your brand, please write to us at dashboard@qiibee.com.

Body:

  • amount - The amount of brand A points to be burned. Can be an integer or string but not decimal/fraction.

  • user_auth_id - The identifier by which a user is identified in your loyalty program.

{
    "transaction": {
        "user_auth_id": "87ydjs798ms-bnsi7gajn..."
        "type": "exchange",
        "brandA_token_id": 12,
        "amount": 10,
        "brandB_token_id": 13,
        "exchange_rate_override": 0.2,
        "brandB_membership_number": "1234567"
    }
}

Responses

  • Success: HTTP 202

  • Bad request: HTTP 400

    • Insufficient balance

    • User/Token does not exist

    • Exchange not allowed

    • Invalid membership number

Points to NFT

This endpoint is used when a user redeems their points for an NFT. The request body remains the same as above with a few differences. The responses will be the same. The points to burn is calculated as

points_to_burn = ceil(NFT value (onramp) ÷ loyalty point onramp value)

Body (all fields are mandatory):

  • reward_type : string - to indicate the type of transaction.

  • from_token_id: number - the token ID of your loyalty point.

  • to_token_id: number - the token ID of your NFT.

  • user_auth_id: string - the auth ID of the user performing the exchange.

Example request:

{
    "transaction": {
        "reward_type": "points_to_nft_exchange",
        "from_token_id": 1,
        "to_token_id": 387,
        "user_auth_id": "9f7326f7-ee-41f4-9c10-aa9f12"
    }
}

Exchange partnerships

GET /token-exchange-whitelist

This request returns the list of active exchange partnerships to the brands with whom you're connected. It contains the token IDs that you would need to pass in the request to perform exchange transactions.

The exchange limits can be updated in the Loyalty Admin Dashboard. You can use these to check if the points to be burned is within the specified limit.

To filter the exchange option by token types, send the token_to_types list as a query param.

Token types

  • erc20 is a regular points bank token

  • erc721 is an NFT token

  • external is a non points bank token

  • fiat represents fiat currencies

  • miles represents the miles tokens

  • crypto represents cryptocurrencies

  • donation represent donation campaigns

Responses

  • Success: HTTP 200 with data in the following format:

{
    "data": {
        [
            "id": 21,
            "from_token": {
                "id": "32768",
                "address": "033Bd49F3ace247112AA6D3d16d24L9Eb5533b17",
                "metadata": {},
                "name": "WORKING POINT TOKEN",
                "symbol": "TKN",
                "type": "erc20" | "external",
                "onramp": "24.2" | null,
                "offramp": "23.5" | null
            },
            "to_token": {
                "id": "32726",
                "address": "056Bd49F3ace247112AA6D3d16d24L9Vb5533b17",
                "metadata": {},
                "name": "WORKING POINT TOKEN 2",
                "symbol": "TKN",
                "type": "erc20" | "external" | "miles" | "crypto",
                "onramp": "24.2" | null,
                "offramp": "23.5" | null
            },
             "status": "active",
             "max_usd_exchange_limit": "100.000000000000000000",,
             "min_usd_exchange_limit": "0.010000000000000000",
             "timestamp": "2022-09-19T11:38:07"
         ]
    }
}

Transaction History

GET /transactions

This request returns paginated transaction history.

By default, it returns the last 100 transactions associated with your brand. The most recent transactions are returned first.

You can query transactions using the following query parameters:

  • limit: (optional) sets the required limit of transaction history to be requested.

    • Defaults: 100

    • Maximum: 100

  • offset: (optional) number of transactions to offset when getting the remaining transactions.

    • Default: 0

  • user_auth_id: (optional) Use this parameter to query transactions for a particular user of your brand. If not passed returns all the transactions for your brand. Can be used along with limit and offset.

  • types: (optional) Use this parameter to query transactions for specific loyalty event types. The events must be sent in a list.

    • Defaults: List of all loyalty event types

  • token_id: (optional) This will let you query the transactions for a specific token ID.

    • Defaults: All tokens that belong to the brand.

  • from_time: (optional) queries for transactions that begin from the specified datetime.

    • Defaults: The datetime at which the brand was created in the qiibee database.

  • to_time: (optional) queries for transactions until the specified datetime.

    • Defaults: The current datetime.

Time parameters

In the time parameters, the date and time must be expressed according to ISO 8601.

eg: The datetime for 06 June 2022 at 11:23:23 AM will be expressed as 2022-06-01T11:23:23Z

The params, limit and offset, work exactly as they’re used in SQL.

Token types

  • erc20 is a regular points bank token

  • erc721 is an NFT token

  • external is a non points bank token

  • fiat represents fiat currencies

  • miles represents the miles tokens

  • crypto represents cryptocurrencies

  • donation represent donation campaigns

Token countries

  • AAA represents that the token is operational worldwide.

Responses

  • Success: HTTP 200 with data in the following format:

{
    "data": {
        "limit": 1,
        "offset": 0,
        "total_tx_count": 25,
        "transactions": [
            {
                "amount_received": "1.00000",
                "brand": null,
                "brand_to": {
                    "brand_config": null,
                    "id": "test_brand2",
                    "locations": [],
                    "name": "Test Brand 2"
                },
                "code": null,
                "exchange_provider": "etihad" | "miles_and_more",
                "id": 706,
                "inserted_at": "2021-09-27T14:31:10",
                "loyalty_event_type": "credit_points",
                "points_burned": null,
                "reward_id": null,
                "status": "success",
                "token": {
                    "id": "3276728",
                    "address": "033Bd49F3ace247112AA6D3d16d24L9Eb5533b17",
                    "metadata": {},
                    "name": "WORKING POINT TOKEN",
                    "estimated_member_count_lower": 1000,
                    "estimated_member_count_higher": 5000,
                    "symbol": "TKN",
                    "type": "erc20" | "erc721",
                    "countries": <list_of_ISO3166_country_codes>,
                    "onramp": "24.2" | null,
                    "offramp": "23.5" | null,
                    "status": "active" | "paused" | "pending"| "stopped" | null
                },
                "token_to": {
                    "id": "3276726",
                    "address": "056Bd49F3ace247112AA6D3d16d24L9Vb5533b17",
                    "metadata": {},
                    "name": "WORKING POINT TOKEN 2",
                    "estimated_member_count_lower": 1000,
                    "estimated_member_count_higher": 5000,
                    "symbol": "TKN",
                    "type": "erc20" | "erc721",
                    "countries": <list_of_ISO3166_country_codes>,
                    "onramp": "24.2" | null,
                    "offramp": "23.5" | null,
                    "status": "active" | "paused" | "pending"| "stopped" | null
                },
                "tx_hash": "0x..xx26",
                "user": {
                    "auth_id": "9f7326f7-ee-41f4-9c10-aa9f12",
                    "country_ISO": "usa",
                    "email": "email@domain.com",
                    "first_name": "Jane",
                    "second_name": "Doe",
                    "id": "NH3HQ==-87b7-2bcd-46ac-b426-0bb81",
                    "language": "en",
                    "metadata": null | {
                        "opts_newsletter": true | false
                     }
                },
                "user_to": {
                    "auth_id": "9f7326f7-ee-41f4-9c10-aa9f12",
                    "country_ISO": "usa",
                    "email": "emai2l@domain.com",
                    "first_name": "John",
                    "second_name": "Doe",
                    "id": "NH3HQ==-8745-2bcd-46ac-b426-0bb81",
                    "language": "en",
                    "metadata": null | {
                        "opts_newsletter": true | false
                     }
                }

            }
        ]
    }
}

If there are no transactions, an empty transactions list will be returned. total_tx_count is the total number of transactions available for the given params.

  • Bad data: HTTP 404 with error message

    • eg. not found

Last updated