Detect subscriptions

This guide will teach you how to use Minna Technologies API's to enable quick action entry points on your applications transaction overview. Depending on your subscription detection capabilities and preferences, how to match subscriptions to transactions can vary. More details on the different approaches can be found further in this guide. Once the detection is done the remaining implementation details should be similar.

Overall architecture

Batch process

Minna Technologies recommend that you fetch the service providers with rules using a batch process. Running the batch process once every 24 hours is sufficient to have the most up to date service providers and rules. The batch process should do subscription detection using rules against user transactions and store the required service provider data in a database.

Database storage

The database for enhanced transactions should be separate from the user transactions and joined together later before the user wants to view them. The following values need to be extracted from Minna Technologies API responses:

Field

Usage

serviceProvider.id

Required to initiate an action towards Minna Technologies

serviceProvider.name

Required to display name of service provider in the UI (Optional if already have identification capabilities)

serviceProvider.services[i].categoryNameText

Required to display the category the subscription belongs to in the UI (Optional if already have identification capabilities)

serviceProvider.actions

Required to determine in UI if any actions are available for each subscription

cancellation.id

Optional, only required for interacting with the Cancel API in other ways than fetching all cancellations. For example to allow the user to withdraw their cancellation requires a specific cancellation ID.

cancellation.status.cancellationStatus

Required to display the current state of action taken on a subscription (Ongoing/Successful/Failed)

cancellation.createdAt

Required to know how long to show the current status on a transaction in the UI

cancellation.lastUpdatedAt

Required to display the date of the latest status update for ongoing actions

cancellation.completedAt

Required to display the completed date of actions

a) Service provider sync

In the case that you have subscription identification capabilities. You should do a service provider sync and extract id, name and actions from matching service providers. These details are required to enable quick actions in your UI and to initiate an action. You can ignore "Fetch service provider rules" if you go with this approach.

b) Fetch service provider rules

In the case that you don't have subscription detection capabilities, Minna Technologies provides transaction matching rules. The Service providers API is used to fetch service provider data and transaction matching rules. The service provider response contains the field transactionMatching which includes rules.

For transactions matching a service provider you should extract the name, id, actions and services[i].categoryNameText and store the data together with the transaction. These details are required to enable quick actions in your UI and to initiate an action.

Transaction text rules

Matching using transaction text rules is done against the original transaction text description, such as the merchant name. The transaction text should be converted to lower case prior to matching.

{
  "transactionMatching": {
    "rules": [
      {
        "value": "prel netflix",
        "type": "TextStartsWith"
      },
      {
        "value": "google *netflix",
        "type": "TextEquals"
      },
      {
        "value": "*netflix*",
        "type": "TextMatchesRegex"
      }
    ]
  }
}

The following is an example of processing text based rules. Note this code is for demonstrational purposes and not optimized for performance.

public static boolean enhanceTransaction(Transaction transaction, ServiceProvider serviceProvider) {
  var rules = serviceProvider.getTransactionMatching().map(TransactionMatching::getRules).orElse(List.of());
  var lowerCaseText = transaction.getText().toLowerCase();

  var match = false;
  for (var rule : rules) {
    switch(rule.getType()) {
      case TextEquals:
        match = lowerCaseText.equals(rule.getValue().toLowerCase());
        break;
      case TextMatchesRegex:
        match = Pattern.compile(rule.getValue().toLowerCase()).matcher(lowerCaseText).matches();
        break;
      case TextStartsWith:
        match = lowerCaseText.startsWith(rule.getValue().toLowerCase());
        break;
    }
    if (match) return true;
  }
  return false;
}

public static List<EnhancedTransaction> enhanceTransactions(List<Transaction> transactions, List<ServiceProvider> serviceProviders) {
  var enhancedTransactions = new ArrayList<EnhancedTransaction>();

  for (var transaction : transactions) {
    var maybeServiceProvider = Optional.<ServiceProvider>empty();

    for (var sp : serviceProviders) {
      if (enhanceTransaction(transaction, sp)) {
        maybeServiceProvider = Optional.of(sp);
        break;
      }
    }

    enhancedTransactions.add(new EnhancedTransaction(transaction, maybeServiceProvider, Optional.empty()));
  }

  return enhancedTransactions;
}

Recipient rules

Matching using recipient rules is for direct debit transactions.

{
  "transactionMatching": {
    "rules": [
      {
        "value": "000-0000",
        "paymentMethod": "BankGiro",
        "type": "RecipientNumberEquals"
      },
      {
        "value": "000000-0",
        "paymentMethod": "PostGiro",
        "type": "RecipientNumberEquals"
      },
      {
        "value": "SE7280000810340009783242",
        "paymentMethod": "IBAN",
        "type": "RecipientNumberEquals"
      }
    ]
  }
}

Merchant identifier rules

Matching using merchant identifier rules is for credit card transactions. As these are unlikely to change, they provide a good way of matching a transaction to a service provider.

{
  "transactionMatching": {
    "rules": [
      {
        "value": "12345678",
        "identifierType": "VisaCardAcceptorId",
        "type": "MerchantIdentifierEquals"
      }
    ]
  }
}

Enable quick actions in UI

In the response from service providers there is a field named actions that you can use to determine to show a Quick action button on the transaction list element.

{
  "actions": {
    "cancel": "Cancellable",
    "improve": "Improvable"
  }
}

Additionally the cancel field can be one of these specific cases:

Value

Description

Cancellable

The Service Provider is cancellable through Minna's Cancellation Engine. Additionally, blocking future payments to this service provider might or might not be placed.

CancellableWithGuide

The Service Provider is cancellable through Minna's Cancellation Engine using Intelligent Guides.

Blockable

The Service Provider does not accept cancellations through Minna's Cancellation Engine. A block for future payments can be issued for this service provider.

a) Manage subscription

To enable a general Manage entry point either cancel or improve needs to exist in actions.

b) Direct action

To enable direct action entry points, the individual values in actions should be used to determine what entry points to list on the transaction list item.

Transaction overview

Minna recommends that you place quick actions on the transaction overview. Our research findings show that user engagement is significantly higher compared to on the transaction details. There are two recommended approaches to show a quick action entry point, either a generic Manage subscription or one or several direct actions such as Cancel it. Quick action entry points should only be visible on subscription related transactions within the last 30 days.

Manage subscription on transactionManage subscription on transaction

Manage subscription on transaction

Direct actions on transactionDirect actions on transaction

Direct actions on transaction

Transaction details

On the transaction details the quick actions are placed at the bottom. Compared to the transaction overview there is more available space here, which allows for several buttons with specific actions.

Actions on transaction detailsActions on transaction details

Actions on transaction details


Did this page help you?