ReimbursementImprove this page

Fidel Reimbursement is an add-on product to Transaction tracking capability, that gives developers the ability to reimburse customers faster and more easily than ever before, by pushing cash directly onto linked cards.

Availability

Reimbursement supports both debit and credits cards by Visa and Mastercard in the US. Your account must be setup in the US to have access to the Reimbursement product.

Activation

If your account is setup in the US and you are using an older API version (reimbursement requires version 2021-09-28 or later) or haven't agreed to the North America Terms & Conditions (17 Jun 2021), you will be prompted to go through the Reimbursement product activation.

Reimbursement Activation

Credits

Before reimbursing cardholders you will need to buy Fidel Credits. To be able to make a reimbursement request you need to have enough credits in your balance to deduct the reimbursement amount. Credits currently support USD currency denominations only and must be purchased by bank transfer to FIDEL LIMITED’s beneficiary account using your unique reference code in the description. Find yours under the Credits view in the dashboard.

Fidel Credits are non refundable and non transferable. Take into consideration possible bank transfer delays that can take between 2-3 business days.

Credits view in the dashboard

Balance

Your credit balance is updated every time you purchase credits or spend by using Reimbursement. When sending a reimbursement request, the amount is immediately deducted from the balance. If the reimbursement goes to failed status, the amount is added again to the balance. Read more information on the credits balance endpoint.

Credits Balance Example

Balances are denominated in multiple currencies to support other countries in the future. Currently we support USD and in this example balances.USD value is $1000.

12345
curl -X GET \
  https://api.fidel.uk/v1/accounts/{accountId}/credits/balance \
  -H 'content-type: application/json' \
  -H 'fidel-key: {your secret key}'

credits-balance.json

123456789101112131415161718192021222324252627282930313233343536373839404142
{
    "items": [
        {
          "accountId": "61741c3-3dc9-45f5-8e7c-db1dd649afab",
          "balances": {
            "AUD": 0,
            "CHF": 0,
            "JPY": 0,
            "EUR": 0,
            "GBP": 0,
            "CAD": 0,
            "USD": 1000,
            "NZD": 0
          },
          "lastTotalAmount": {
            "AUD": 0,
            "CHF": 0,
            "JPY": 0,
            "EUR": 0,
            "GBP": 0,
            "CAD": 0,
            "USD": 1000,
            "NZD": 0
          },
          "lowCreditsNotificationSent": {
            "AUD": false,
            "CHF": false,
            "JPY": false,
            "EUR": false,
            "GBP": false,
            "CAD": false,
            "USD": true,
            "NZD": false
          }
        }
    ],
    "execution": 135.265058,
    "resource": "/v1/accounts/{accountId}/credits/balance",
    "status": 200
  }
}

Low Balance Notification

When a currency balance drops to 25% of the balance amount you had on your last purchase, lowCreditsNotificationSent is set to true and the following actions are then triggered:

  • notification email is sent to account users emails;

  • dashboard notification is shown;

  • credits.balance.low webhook is sent if you are listening on your end. Read below on how to set it up.

Low Balance Webhook

The credits.balance.low webhook notifies on the Low Balance Notification event that happens when the credits balance is running low. Use this webhook to automate credit purchases on your end without the risk of service disruption due to insufficient balance. See the example below with the webhook object triggered by the low USD balance:

credits-balance.json

12345678910111213141516171819202122232425262728293031323334
{
  "accountId": "61741c3-3dc9-45f5-8e7c-db1dd649afab",
  "balances": {
    "AUD": 0,
    "CHF": 0,
    "JPY": 0,
    "EUR": 0,
    "GBP": 0,
    "CAD": 0,
    "USD": 1000,
    "NZD": 0
  },
  "lastTotalAmount": {
    "AUD": 0,
    "CHF": 0,
    "JPY": 0,
    "EUR": 0,
    "GBP": 0,
    "CAD": 0,
    "USD": 1000,
    "NZD": 0
  },
  "lowCreditsNotificationSent": {
    "AUD": false,
    "CHF": false,
    "JPY": false,
    "EUR": false,
    "GBP": false,
    "CAD": false,
    "USD": true,
    "NZD": false
  }
}

History

In the Credits dashboard view you have access to your credit purchases in Purchased credits and credit spent in Reimbursements. Read more information on the credits history endpoint.

Credits history

Eligibility

The reimbursement request is done towards a cardholder transaction with the path parameter transactionId and it needs to meet the eligibility criteria that can be checked with the transaction boolean property reimbursementEligible. You must be using the API version 2021-09-28 or newer to have the property available in your transactions.

Eligibility has a true value when the transaction meets the following criteria:

  • Transaction currency is USD;

  • Transaction reimbursement is undefined or reimbursement.status is failed;

  • Transaction scheme is visa or mastercard;

  • Transaction status is cleared;

  • Transaction time date is newer than 90 days.

Finding Eligible Transactions by Card

Find eligible card transactions with cardId for a specific amount and currency. Optionally pass brandId to find transactions in a specific brand.

Transactions are sorted automatically in descending order by the best available, following the eligibility criteria, giving more emphasis on the transaction time and then amount. Read more information on the find eligible reimbursement transactions endpoint.

Reimbursement by Card

Eligible Transactions Example

Example amount set to 5, currency to USD and brandId to Star.

12345
curl -X GET \
  GET https://api.fidel.uk/v1/cards/{cardId}/transactions/reimbursement?amount={amount}&currency={currency}&brandId={brandId} \
  -H 'content-type: application/json' \
  -H 'fidel-key: {your secret key}'

transaction.json

123456789101112131415161718192021222324252627282930313233
{
  "count": 2,
  "items": [
    {
      // For the purpose of this example, only selected properties are shown
      "amount": 10,
      "cleared": true,
      "currency": "USD",
      "card": {
        // For the purpose of this example, only selected properties are shown
        "scheme": "visa",
      },
      "datetime": "2021-08-20T11:11:11",
      "reimbursementEligible": true
    },
    {
      // For the purpose of this example, only selected properties are shown
      "amount": 20,
      "cleared": true,
      "currency": "USD",
      "card": {
        // For the purpose of this example, only selected properties are shown
        "scheme": "visa",
      },
      "datetime": "2021-10-20T11:11:11",
      "reimbursementEligible": true
    }
  ],
  "resource": "/v1/cards/{cardId}/transactions/reimbursement",
  "status": 200,
  "execution": 26.392104
}

Request

Creating a request

After choosing the transactionId, the reimbursement amount must be equal to or lower than the transaction amount and the currency is determined by the transaction. Visa cards have a maximum reimbursement amount limit of USD $250. We currently support USD currency transactions. Optionally customise the description text that will show in the cardholder bank statement. Read more information on the create reimbursement endpoint.

Creating a reimbursement

Reimbursement Example

Example amount set to 2.55 and custom description to Earned Stars.

123456789
curl -X POST \
  https://api.fidel.uk/v1/transactions/{transactionId}/reimbursement \
  -H 'content-type: application/json' \
  -H 'fidel-key: {your secret key}' \
  -d '{
    "amount": 2.55,
    "description": "Earned Stars"
  }'

After the reimbursement request is received by the card scheme, the full transaction is returned with the newly created transaction.reimbursement object with pending status, and also a reimbursement.token string, representing the unique identifier for that reimbursement request.

transaction.json

12345678910111213141516171819202122232425262728
{
    "items": [
        {
            // For the purpose of this example, only selected properties are shown
            "amount": 10,
            "cleared": true,
            "currency": "USD",
            "card": {
              // For the purpose of this example, only selected properties are shown
              "scheme": "visa",
            },
            "datetime": "2021-08-20T11:11:11",
            "reimbursementEligible": false,
            "reimbursement": {
              "amount": 2.55,
              "created": "2021-09-30T11:11:11.000Z",
              "creditsTransactionId": "1250ab5a-0661-4a06-a40c-8514093a9241",
              "description": "Earned Stars",
              "status": "pending",
              "token": "6c01f956-1f0f-413f-a5db-d1fc8a59ef92",
            }
        }
    ],
    "execution": 120.856835,
    "resource": "/v1/transactions/{transactionId}/reimbursement",
    "status": 200
}

Lifecycle

When you request a reimbursement to an eligible cardholder transaction, we send the request to the card scheme in real time. For that reason, there is no way to stop or cancel your request after it has been sent.

Reimbursement status is set to pending while waiting for the card scheme to confirm the successful issued status, at which point funds normally hit the cardholder’ account. It takes between 48 to 72 hours for the issued status to be updated.

Reimbursement status

Status

Find the reimbursement status in the transaction reimbursement.status property:

  • pending: scheme is executing request;

  • issued: scheme executed request successfully;

  • failed: scheme request failed and transaction.reimbursement.error object is created. Retry is possible. See error list for more information.

Reimbursement by card

In some cases, you may want to reimburse a card (and not a specific transaction). However, as card networks allow reimbursements only on specific transactions, the reimbursement request needs to be based on a transaction. The POST https://api.fidel.uk/v1/cards/{cardId}/reimbursement endpoint helps you to find such a transaction for this case. You can simply define the cardId, and Fidel API will search for the most suitable transaction, and apply the reimbursement on that one.

The request to this endpoint would require an amount and a currency (and also other optional properties):

request.json

1234567
{
  "amount": 5,
  "currency": "USD",
  "description": "Earned Stars", //optional
  "brandId": "518c746f-fbf4-420a-8d37-c591adc39684" // optional
}

The endpoint would then respond with data that would include card and reimbursement data, etc.

response.json

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
{
  "items": [
    {
      "id": "3c0c4ed5-b821-4390-8a9e-e7c140ec8358",
      "accountId": "3693ac7e-3e2b-432c-8c60-2b786453ca9b",
      "programId": "6e38aa0c-b7ef-46bd-b1bd-c07c648d9cba",
      "datetime": "2021-08-20T11:11:11",
      "created": "2021-08-20T11:11:11.000Z",
      "updated": "2021-08-20T11:11:11.000Z",
      "auth": true,
      "cleared": true,
      "amount": 5,
      "currency": "USD",
      "wallet": null,
      "card": {
        "id": "bc538b71-31c5-4699-840a-6d4a08693314",
        "firstNumbers": "555500",
        "lastNumbers": "5001",
        "scheme": "visa",
        "metadata": {
          "customKey1": "customValue1",
          "customKey2": "customValue2"
        }
      },
      "brand": {
        "id": "9d136f2e-df99-4a08-a0a5-3bc1534b7db9",
        "name": "Starbucks",
        "logoUrl": null
      },
      "location": {
        "id": "7a916fbd-70a0-462f-8dbc-bd7dbfbea160",
        "address": "5th Avenue",
        "city": "New York",
        "postcode": "10016",
        "countryCode": "USA",
        "timezone": "America/New_York",
        "geolocation": {
          "latitude": 43.9168069,
          "longitude": -73.3044301
        },
        "metadata": {
          "customKey1": "customValue1",
          "customKey2": "customValue2"
        }
      },
      "offer": null,
      "identifiers": {
        "MID": "123456789",
        "mastercardTransactionSequenceNumber": "0000000000000",
        "mastercardRefNumber": "AABBCCDDE",
        "amexApprovalCode": "AA00BB",
        "visaAuthCode": "000000",
        "mastercardAuthCode": null
      },
      "reimbursementEligible": false,
      "reimbursement": {
        "amount": 2.55,
        "created": "2021-09-30T11:11:11.000Z",
        "creditsTransactionId": "1250ab5a-0661-4a06-a40c-8514093a9241",
        "description": "Earned Stars",
        "status": "pending",
        "token": "6c01f956-1f0f-413f-a5db-d1fc8a59ef92"
      }
    }
  ],
  "resource": "/v1/cards/bc538b71-31c5-4699-840a-6d4a08693314/reimbursement",
  "status": 200,
  "execution": 19.980616
}

For more info, please visit the API reference for this particular endpoint.

Automation

Automate reimbursement requests when creating an Offer by toggling the “enable automatic reimbursements” checkbox. This toggle will be available if the reimbursement product is active and the Offer’s country is the USA.

Automatic reimbursement with Offers

Reimbursements will be automatically requested whenever a transaction is both cleared and qualified for an Offer with offer.automatedReimbursement.enabled set to true. Optionally, it's also possible to include a Description for the Reimbursement using the offer.automatedReimbursement.description.

Read more information on the Offers product in the documentation page.

Tracking before issuing

Track if a transaction will get a reimbursement request by checking the transaction’s offer object:

transaction-with-offer.json

12345678910111213141516171819
{
  // For the purpose of this example, only selected properties are shown
  "amount": 10,
  "amount": 10,
  "cleared": true,
  "currency": "USD",
  "datetime": "2021-08-20T11:11:11",
  "reimbursementEligible": true,
  "offer": {
    "automatedReimbursement": true,
    "id": "7e55eeae-99d6-4daf-b8c4-ac9ca660e964",
    "cashback": 20,
    "message": [],
    "performanceFee": 3.2,
    "qualified": false,
    "qualificationDate": null
  },
}

The offer.automatedReimbursement states whether a reimbursement request will be attempted for that transaction or not. The reimbursement will have the same amount as the offer.cashback property and the same currency as currency. Transactions that already have a reimbursement object will not have any reimbursements requested automatically.

Transactions with expected automated reimbursement attempts are shown in the dashboard with a grey label on the reimbursements column.

Transactions with auto-reimbursements

Tracking after issuing

Automated reimbursement attempts have the same payloads as regular reimbursements requests and also include three new properties to provide the user with more information on how and why they were requested - automated, issuingBrandId, issuingOfferId.

The reimbursement.automated property states whether that reimbursement request was issued automatically. Automated reimbursements are those that were not triggered directly by the user (via API or dashboard).

The reimbursement.issuingBrandId and reimbursement.issuingOfferId properties are informative properties which only exist for automated reimbursements and inform the user of what context the reimbursement was requested in.

transaction-with-offer.json

1234567891011121314151617181920212223242526272829
{
  // For the purpose of this example, only selected properties are shown
  "amount": 10,
  "cleared": true,
  "currency": "USD",
  "datetime": "2021-08-20T11:11:11",
  "reimbursementEligible": true,
  "reimbursement": {
    "amount": 2.55,
    "automated": true,
    "created": "2021-09-30T11:11:11.000Z",
    "creditsTransactionId": "1250ab5a-0661-4a06-a40c-8514093a9241",
    "description": "Earned Stars",
    "issuingBrandId": "459170aa-7490-467d-bb4d-19b35139e325",
    "issuingOfferId": "7e55eeae-99d6-4daf-b8c4-ac9ca660e964",
    "status": "pending",
    "token": "6c01f956-1f0f-413f-a5db-d1fc8a59ef92"
  },
  "offer": {
    "automatedReimbursement": true,
    "id": "7e55eeae-99d6-4daf-b8c4-ac9ca660e964",
    "cashback": 20,
    "message": [],
    "performanceFee": 3.2,
    "qualified": false,
    "qualificationDate": null
  },
}

Failed automated reimbursements

Automated reimbursement requests can fail – e.g.: account does not have enough credits, transient issue or transaction is not reimbursement eligible (see Eligibility section). In these cases, they can be retried as described in the Retry section.

Webhook

When a reimbursement status is updated from pending to issued or failed the webhook named transaction.reimbursement.status is triggered. The webhook will send the full transaction object with the updated reimbursement.status. See the example below with the update to issued status:

transaction.json

123456789101112131415161718192021
{
  // For the purpose of this example, only selected properties are shown
  "amount": 10,
  "cleared": true,
  "currency": "USD",
  "card": {
    // For the purpose of this example, only selected properties are shown
    "scheme": "visa",
  },
  "datetime": "2021-08-20T11:11:11",
  "reimbursementEligible": false,
  "reimbursement": {
    "amount": 2.55,
    "created": "2021-09-30T11:11:11.000Z",
    "creditsTransactionId": "1250ab5a-0661-4a06-a40c-8514093a9241",
    "description": "Earned Stars",
    "status": "issued",
    "token": "6c01f956-1f0f-413f-a5db-d1fc8a59ef92",
  }
}

Errors

The reimbursement request and status update can fail for various reasons. Your application should handle these errors accordingly.

Retry

Reimbursement requests can be retried via API or dashboard.

Retry reimbursement

API Errors

These errors might be returned in the request endpoint.

HTTP Status CodeError CodeError Message
400reimbursement-account-network-inactiveAccount cannot issue reimbursement for card network
400reimbursement-account-not-enough-fundsAccount does not have enough funds for issuing reimbursement
404reimbursement-account-not-foundAccount does not exist
400reimbursement-already-createdTransaction reimbursement already created
400reimbursement-amount-above-limitReimbursement amount is above the allowed limit
400reimbursement-amount-greater-original-amountReimbursement amount is greater than original transaction amount
400reimbursement-invalid-transactionTransaction is invalid to issue reimbursement
500reimbursement-network-internal-errorNetwork responded with internal error
404reimbursement-transaction-not-foundTransaction does not exist
400reimbursement-unsupported-networkTransaction network not supported for reimbursement
400reimbursement-unsupported-currencyTransaction currency not supported for reimbursement
401reimbursement-not-activatedThe reimbursement product is not activated for this account
400reimbursement-time-limit-after-transactionSurpassed the time limit after the original transaction to issue a reimbursement
400reimbursement-visa-invalid-community-codeThe transaction community code is invalid
400credits-account-not-enough-fundsAccount does not have enough credits

API Error Example

reimbursement-request.json

123456789101112
{
    "error": {
        "code": "reimbursement-amount-greater-original-amount",
        "date": "2021-11-11T14:53:18.968Z",
        "message": "Reimbursement amount is greater than original transaction amount",
        "metadata": {}
    },
    "execution": 105.254359,
    "resource": "/v1/transactions/{transactionId}/reimbursement",
    "status": 400
}

Status Errors

These errors might be returned in the reimbursement status update to failed from the card scheme and sent to the transaction.reimbursement.status webhook.

Status CodeError CodeError Message
400reimbursement-issuing-mismatchReimbursements issued by network do not match with original request
404reimbursement-network-account-not-foundNetwork was unable to find bank account
404reimbursement-network-customer-not-foundNetwork was unable to find customer account
500reimbursement-network-invalid-accountNetwork responded bank account is invalid
500reimbursement-network-invalid-account-countryNetwork responded bank account country is invalid
500reimbursement-network-invalid-currencyNetwork responded the selected currency is invalid
400reimbursement-network-multiple-accounts-foundNetwork responded multiple bank accounts were found
500reimbursement-network-othersNetwork responded with an irregular issue
500reimbursement-request-failedFailed to submit reimbursement request to network

Status Error Example

transaction.json

12345678910111213141516171819202122232425
{
  // For the purpose of this example, only selected properties are shown
  "cleared": true,
  "currency": "USD",
  "card": {
    // For the purpose of this example, only selected properties are shown
    "scheme": "visa",
  },
  "datetime": "2021-08-20T11:11:11",
  "reimbursementEligible": true,
  "reimbursement": {
    "amount": 2.55,
    "created": "2021-09-30T11:11:11.000Z",
    "creditsTransactionId": "1250ab5a-0661-4a06-a40c-8514093a9241",
    "error": {
      "code": "reimbursement-network-account-not-found",
      "message": "Network was unable to find bank account",
      "status": 404
    },
    "description": "Earned Stars",
    "status": "failed",
    "token": "6c01f956-1f0f-413f-a5db-d1fc8a59ef92"
  }
}

API Reference

If you're looking to find out more about our Reimbursement API and how to use it with your application, please visit the Fidel API Reference.