Recurring Payment Intelligence

RPI is an extension on top of the core Tapix payment enrichment API. Due to that, before you begin with this guide, you should familiarize yourself with the basic knowledge from Getting started with Tapix tutorial and the respective guides for enriching card payment data or bank transfers.

Please be aware that Recurring Payments Intelligence is not automatically accessible and requires activation by the Tapix team. If you wish to obtain recurring payments, please contact support@tapix.io.

Recurring Payment Intelligence (RPI) appends a subscription object to your existing enrichment response. It works on both card transactions and SEPA bank transfers — no new endpoint, no new integration.

Available for:

  • Card endpoint /shops/findByCardTransaction, and its batch (/shops/findByCardTransactionBatch) and complete (/shops/complete/findByCardTransaction, /shops/complete/findByCardTransactionBatch) versions
  • SEPA endpoint /shops/findByBankTransfer/sepa, and its batch (/shops/findByBankTransferBatch/sepa) and complete (/shops/complete/findByBankTransfer/sepa, /shops/complete/findByBankTransferBatch/sepa) versions

Example response

Card transaction (findByCardTransaction):

Query:

/v6/shops/complete/findByCardTransaction?mcc=5818&city=CORK&posId=05197337&amount=1990&country=IE&clientId=CQYFCQADAQIHCQAFAAKHAW%3D%3D&currency=HUF&customId=1&merchantId=311183094888&description=APPLE.COM%2FBILL&transactionTimestamp=2026-09-03T16%3A11%3A59.000%2B02%3A00

Response:

{
    "result": "found",
    "handle": "$cJMDgvgdFKLwuqyizL0fV2",
    "shop": {
        "uid": "ouNTZWfHfDtAi1kBObK5D2",
        "type": "online",
        "tags": [
            "Software / Applications",
            "Electronics Goods",
            "Apple",
            "Shopping Online",
            "Subscription",
            "Online Digital Services"
        ],
        "merchant": {
            "uid": "GbZzrLP0MpfQXAzYXerPn",
            "name": "Apple",
            "logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/m/GbZzrLP0MpfQXAzYXerPn/l#dc7283e86cd9f17f412182ef416265ca0fab1003"
        },
        "category": {
            "name": "Digital Services",
            "logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/category/GPGTWAG23kdhMh6W469Wf4/l"
        },
        "url": "https://www.apple.com"
    },

    "subscription": {
        "automaticCharging": true,
        "clientServiceUid": "e73e605407c5b4b644677a",
        "frequency": "Monthly",
        "nextBillingDate": "2026-10-03",
        "nextAmountType": "Same"
    },
    "customId": "1"
}

SEPA transfer (findByBankTransfer/sepa):

Query:

/v6/shops/complete/findByBankTransfer/sepa?iban=DE69700700100111111100&name=SOS-KINDERD%C3%96RFER%20WELTWEIT%20HERMANN-GMEINER-FONDS%20DEUTSCHLAND%20E.V.&amount=15&country=null&clientId=93b660343b55a997cee4c4d2f2a77782cb10ccf43c54aab0c46fb27be5922cf5&currency=EUR&customId=1&paymentTimestamp=2026-09-09T10%3A01%3A56.000%2B02%3A00

Response:

{
    "result": "found",
    "handle": "bkQopQbzlVpHpK1BMdA553",
    "shop": {
        "uid": "bkQopQbzlVpHpK1BMdA553",
        "type": "account",
        "tags": [
            "Donation And Crowdfunding"
        ],
        "merchant": {
            "uid": "QdzQV18Z9E1TbL44Po2zvl@de",
            "name": "SOS Kinderdörfer",
            "logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/m/QdzQV18Z9E1TbL44Po2zvl/l#a81fa91b7181dfc3c40dc1a835c4a60853c2d4b9",
            "localizedNames": {
                "latin": "SOS Kinderdörfer"
            }
        },
        "category": {
            "name": "Professional Services",
            "logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/category/yMov9i37wbnBVXfQ6dg6uk/l"
        },
        "location": {
            "address": {
                "country": "DE"
            }
        }
    },

    "subscription": {
        "automaticCharging": true,
        "clientServiceUid": "a2f5799f5a48592179f035",
        "frequency": "Monthly",
        "nextBillingDate": "2026-10-12",
        "nextAmountType": "Same"
    },
    "customId": "1"
}

RPI works the same way for all transfer endpoints listed in the documentation.

Required request parameters

To learn what input data is required, and its ideal structure used to enrich the card / bank transfer payment data – refer to this link. Additionally, there are more necessary parameters for identifying recurring payments.

ParameterApplies toDrives
transactionTimestamp (card) / paymentTimestamp (SEPA)Both — requiredfrequency, nextBillingDate
amountBoth — requiredfrequency, nextAmountType
currencyBoth — requiredfrequency, nextAmountType
sourceIdCard onlyDetection, clientServiceUid (fallback identifier)
clientIdSEPA — required (no sourceId exists for transfers). Card — recommended.clientServiceUid (preferred identifier) — the only one that links the same person's card and transfer payments for one service into a single subscription.

Additional parameters that are optional and might improve the detection:

Cards
  • posEntryMode (good to have) — ISO 8583 Field 22 - Identifier of the method used to obtain the PAN. Example: 10
  • posTransactionStatusIndicator (good to have) — ISO 8583 Field 60.6 - Identifier of the POS Transaction Status Indicator. Example: R
  • ecommerceIndicator (good to have) — ISO 8583 Field 126 - Identifier of the Electronic Commerce/MOTO (Mail Order/Telephone Order) Indicator. Example: 02
SEPA
  • nextPaymentDate — The date of the next scheduled execution of the standing order. Must follow the ISO 8601 format (YYYY-MM-DD). Example: 2025-04-15
  • recurrenceType — Defines the nature of the payment instruction. Possible values: SINGLE (one-off), STANDING_ORDER (recurring), or DIRECT_DEBIT. Enum: "SINGLE" "STANDING_ORDER" "DIRECT_DEBIT"
  • remittanceInfo — ISO 20022 – Remittance Information. Free-text payment reference provided by the originator to the beneficiary. Example: Invoice 2023/09 #4581

Input data quality

Before turning on RPI in production it is heavily recommended to share historical data: 13 months minimum, 3 years ideal. Without it, we cannot identify the pattern and will only start creating the rules since you start calling the API. (This means that even though your client is paying for a service for a long time, these payments won't appear as a subscription until we see at least two payments.)

Authorisations vs. settled transactions: send settled/booked transactions for RPI. Sending both produces duplicate-looking payments and most severely degrades nextBillingDate. Either send only the settled transactions or implement a way how to distinguish between them. One option e.g. using rawParams where you write authorisation/settled_transaction. There are other ways, discuss it with the implementation manager at first.

sourceId must be stable in two ways. Across card reissue — the same value before and after a card is replaced (expiry, loss, theft). Across your integration — the same hashing method for the historical load and for production.

Response fields

Both endpoints append the same object — FindResultSubscription in the API reference:

  • automaticCharging — boolean. Automatically charged or manually paid.
  • clientServiceUid — string, ≤100 characters. Stable id for one client and one service (merchant + frequency). Same service at a different frequency gets a different id.
  • frequency — enum: Weekly, Monthly, Quarterly, Yearly, Other, Unknown.
  • nextAmountType — enum: Same, Approximate, Unknown.
  • nextBillingDate — date, YYYY-MM-DD. Not returned on invalidations and refreshes.

Edge cases

A SEPA transfer can come back "result": "unsolved" and still carry a full subscription object — detection does not depend on the shop being resolved:

Query:

/v6/shops/complete/findByBankTransfer/sepa?iban=DE63430609671294787500&name=B%C3%9CNDNIS%2090%20%2F%20DIE%20GR%C3%9CNEN%20KREISVERBAND%20HAMBURG-NORD&amount=55&country=null&clientId=189945b1886b376a80e4f97b84017add25389a26610b87a4539414c8545c31b5&currency=EUR&customId=1&paymentTimestamp=2026-09-15T10%3A09%3A52.000%2B02%3A00

Response:

{
    "result": "unsolved",
    "handle": "yc13853119ab71c9bfbd54f",

    "subscription": {
        "automaticCharging": true,
        "clientServiceUid": "c24b17792b3e585f768a70",
        "frequency": "Monthly",
        "nextBillingDate": "2026-10-16",
        "nextAmountType": "Approximate"
    },
    "customId": "1"
}

Do not filter out unsolved transactions before checking for subscription — you will lose real detections. These might include smaller merchants, e.g. insurances, local sports clubs or rent.

First-vs-second transaction detection

  • Single-purpose merchants (subscription-only services) — subscription, including frequency, from the first matching transaction.

Example of subscription-only merchant detection

merchanttransactionTimestampamountcurrencyautomaticChargingnextAmountTypefrequencynextBillingDatePayment rank
Netflix27.04.20264,99EURTRUESameMonthly27.05.20261.
Netflix27.05.20264,99EURTRUESameMonthly27.06.20262.
Netflix27.06.20264,99EURTRUESameMonthly27.07.20263.
Netflix27.07.20264,99EURTRUESameMonthly27.08.20264.
  • Mixed merchants (subscriptions and one-off purchases at the same merchant):
    • Detection normally begins from the second transaction in a series.
    • But where historical data already shows a series of recurring payments, the subscription is returned from the first transaction the client sees.
    • The subscription object is also returned on invalidations and refreshes, not only on new transactions — but without nextBillingDate in those responses.

Example of mixed merchant detection

MerchanttransactionTimestampamountcurrencyautomaticChargingnextAmountTypefrequencynextBillingDatePayment rank
Apple14.07.20257,99EUR1.
Apple21.07.20257,99EUR1.
Apple14.08.20257,99EURTRUESameMonthly14.09.20252.
Apple14.09.20257,99EURTRUESameMonthly14.10.20253.
Apple06.10.20252,99EUR1.
Apple14.10.20257,99EURTRUESameMonthly14.11.20254.
Apple06.11.20252,99EURTRUESameMonthly06.12.20252.

A brand-new subscription at a mixed merchant will not appear immediately. Expected behaviour, not a detection failure.

nextBillingDate — reading and displaying it

nextBillingDate should be treated as a prediction, not a commitment. Merchants shift charge dates around weekends, bank holidays, and their own billing quirks. A real example stated by Netflix

nextAmountType — reading and displaying it

  • Same — fixed recurring price. Streaming and media subscriptions, software licences, membership fees.
  • Approximate — amount moves between cycles. Usage-based utility bills, metered mobile/data plans, consumption-based cloud services.
  • Unknown — pattern is regular, amount can't be qualified. Display nothing for the forward amount.

Feedback API

Helps us to better understand the subscriptions.

Does not persist corrections per individual end user. A submitted correction is reviewed and, if adopted, becomes a rule-level change — not a personal override for that one customer. Store and apply per-user corrections yourself if you need that behaviour. Reference: POST /feedback.

Tapix | Recurring Payment Intelligence