Recurring payments, or how we improved the functionality of paid subscriptions in the Flutter application

The idea for writing this article was the interesting first experience of integrating recurring payments. The path went through shooting Google with questions, studying documentation, experiments, errors and communication with Tinkoff support service. This article brought together all the steps that were taken, outlined the subtleties and nuances that we encountered, and added specific examples of improvements.

What did we have and what needed to be done?

At the time of the start of improvements, there was already a combat Flutter application with integrated TinkoffSDK. The application had the opportunity to pay for a PRO account at one of three tariffs: for a month, for a year, forever. At the end of the paid period, the PRO account was disabled.

Initial flow:

  1. The user selects a tariff and proceeds to payment;

  2. The mobile application initiates the creation of an order on our server and receives the order ID;

  3. The mobile application opens a native payment window via TinkoffSDK and transfers order data to it: cost, description, order ID;

  4. The user fills in payment information and makes payment;

  5. Tinkov’s API knocks on our server with the transaction result and order ID;

  6. Depending on the payment status, the server assigns the user the selected tariff or payment error status;

  7. Once a day, the server disables subscriptions with an expired paid period.

Goals:

  1. Implement automatic debiting of funds when renewing a subscription;

  2. Give the user the opportunity to get acquainted with PRO features during a free trial period;

  3. Implement automatic debiting of funds at the end of the trial period.

Plan:

  1. Explore the topic of using recurring payments through Tinkoff;

  2. Improve the database structure;

  3. Improve the API;

  4. Improve the mobile application.

Domain Immersion

By means of Google and reading Tinkoff cash register documentation I managed to find out that one of the options for solving the problem is to use RebillId from the data that Tinkoff transmits in the notification after successful user authorization.

RebillId – identifier of the parent payment on the basis of which funds will be debited.

Default RebillId is not coming. To receive it, you must mark the user's first payment as a parent payment. This was the first improvement on the mobile application side. So that you receive notifications from Tinkoff RebillIdit is enough to pass in the order options “ when opening the native modal window TinkoffSDKrecurrentPayment: true

The next stages were the reworking of the interaction algorithm with TinkoffSDK on the side of the mobile application and the transfer of payment for the tariffs themselves to our server side. This is due to the fact that one of the business tasks is the implementation of a trial period with subsequent automatic payment. It is necessary to make the process for the user as linear and identical as possible, regardless of the chosen tariff. We decided to implement a separate process for linking a card using TinkoffSDK, and a separate process for registering a tariff through our server.

The process of linking a card and paying on paper looks like this:

  1. Before placing an order, we ask the user to link a card. To verify the authenticity of the card, write off and return 10₽;

  2. The application receives from our server an identifier for a special order type “Card Linking”;

  3. The mobile application opens the native TinkoffSDK modal window to pay 10₽;

  4. The user makes a payment;

  5. After the payment process is completed, a notification from Tinkoff is sent to the server;

  6. If successful, the server binds to the user RebillId And Pan (disguised card number for display to the user):

    a. Our server calls the method cancel for a refund 10₽;
    b. The user selects the required tariff and clicks “Apply”;
    c. The mobile application sends a request to our server to issue a tariff;
    d. Our server either activates the trial period, if it is provided for in the tariff and is available to the user, or initiates payment through Tinkoff.

The first revision of the system and the first nuances. Linking a user card

The terms of reference are described, let's get to work.

Added user payment information to the database. Added an API method for creating OrderId, we have improved Callback, through which Tinkoff interacts with our server. The application for linking the card has been improved.

We are testing. The money was taken from the card and they promised to return it. There are no errors. The card is linked. But alas, after a minute, ten and even an hour, the money was not returned to the card. Let's go find out.

Payment status saved in the database – REFUNDED. So the problem is not in the code. Open your Tinkoff personal account. This payment is on the list of refunds. In the payment details we see the acquiring commission and understand: this is not what we need.

There are two withdrawal modes in your Tinkoff personal account:

By default, the “Write off immediately” mode is selected. In this mode, the payment status, if successful, automatically changes from status AUTHORIZED to status CONFIRMED, funds are debited from the user's card and transferred to our account. The return in this case involves a commission and takes a long time.

The “Block on the buyer’s account” mode assumes that the payment remains in the status AUTHORIZED within 7 days. The user's funds remain blocked in the account. Our server confirms the payment method confirmdebiting funds from the user's account, or canceling the payment using the cancelby unlocking funds. After 7 days the payment status is AUTHORIZED is canceled automatically on the Tinkoff side. Canceling such a payment does not imply any commission and occurs instantly.

We are testing. There are no errors. The card is linked. The money left the card and came back immediately. The problem of linking the card is solved!

The next task is to use the saved RebillId make a payment on the side of our API without user interaction.

Making a payment on our server side, communicating with Tinkoff support

To make a payment without user participation on the side of our server, you need to call the method initthen call the method charge and transfer the previously saved RebillId. Method charge blocked by default. To unlock it, you need to write to Tinkoff support, go through approval and modify the system in accordance with the list of requirements.

List of requirements:

  1. Detailed description of services and their cost;

  1. Tariffs are stated in rubles and foreign currency (if applicable), the write-off amount and frequency are indicated;

  1. Notification of rate conversion (if applicable). For example: “conversion is carried out at the rate of the issuing bank at the time of write-off”;

  1. When making a payment and choosing a tariff, the buyer must understand that he is signing up for a subscription. This should be indicated on the website or there should be a technical option for choosing a subscription/recurring payments;

  1. Your offer should transparently describe the terms of auto payment: payments are regular and will be debited directly from the card once a week/month/year, etc.;

  1. Consent to the processing of personal data;

  1. Consent to store credentials for future transactions. The merchant must enter into an agreement with the cardholder that contains the following:

  • A shortened version of the stored credentials (for example, the last four digits of a credit card);

  • How the cardholder receives notification of any changes to the payment agreement;

  • How saved credentials will be used;

  • Agreement expiration date, if applicable.

  1. Subscription agreement (separate from the general offer!), which contains:

  • Transaction amount (including all taxes, fees and other expenses). If the exact amount is not available at the time the agreement is entered into, the agreement must contain an explanation of how the transaction amount will be calculated;

  • The type of currency used in the transaction;

  • Cancellation and return rules, indicating contact information for customer requests.

  1. You must place a checkbox in the field where you agree to the offer. Checkbox to set the client’s consent to the terms of the recurring payments offer and the personal data processing policy.

  • Consent in the checkbox should not be set by default;

  • The text must be written in a readable font;

  • The write-off amount and frequency must be indicated.

  1. You must send SMS and/or email notifications to clients about successful debits;

  2. The unsubscribe link must be posted:

The coordination of recurring payments for the first application took 5 iterations and lasted for several weeks. Tinkoff's requirements were supplemented and clarified. With the second application everything went faster and took one day.

We provided comments on each of the 11 points. Where required, a screenshot from the application was attached.

1, 2 points:

Point 3: We do not have conversion

4, 5 points:

6 point:

7 point:

8 point:

9 point:

Point 10: Notifications are not provided. This is stated in the offer

11 point:

Next steps:

  • updating the database to use the trial period,

  • API improvements for subscriptions,

  • improvement of the mobile application.

Some conclusions

As part of this task, we were able to dive deeper into the operation of payments in various modes. Find out how recurring payments work, what you should be prepared for in advance, and how to implement automatic subscription renewal.

In short, to enable recurring payments in the application, you need to:

  1. On the Tinkoff side:
    a. Agree with Tinkoff support to open the charge method;
    b. Switch the debit mode to “Block on the buyer’s account.”

  2. On the DB side:
    a. Provide storage structures RebillId And Pan linked payment data of the user.

  3. On the server side:
    a. Implement methods for creating an order for card binding;
    b. Implement methods for registration and payment of tariffs;
    c. Implement a method for unsubscribing;
    d. Implement a function for checking the status of a subscription running via CRON;
    e. Implement a callback to receive payment notifications from Tinkoff.

  4. On the mobile application side:
    a. Implement payment for the parent order to link the card;
    b. Connect API methods;
    c. Improve the application UI in accordance with Tinkoff support requirements.

Recurring payments are a fairly simple topic. But when you do this task for the first time, when connecting, nuances arise that take a lot of time. We would have been glad to find an article like this when we started implementing auto-renewal of subscription in our application. Now there is such an article. We hope it will be useful and allow you to save a single working hour.

Dima, Flutter developer, Progressive Mobile [ссылка удалена мод.]

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *