Skip to main content

Recurring payments

Recurring payments (sometimes called “standing orders”) are ideal to pay for subscriptions. With our solution, any merchant or product owner planning to offer paid subscriptions within their platforms can easily do so now, leaving all the low-level payments handling routine to Fena.

Currently almost all banks in the UK support weekly, monthly, quarterly and yearly frequencies for payments. Meaning merchants are free to set up standing orders to receive payments from their customers in any of these time intervals.

There are some specifics to consider when planning to integrate recurring payments from Fena into your platform:

  1. Standing orders are set up/initiated once by the end-user/bank account holder. After initiation all subsequent payments associated with that standing order are handled by the bank without intervention from Fena or account holder.
  2. Once an order is initiated with the bank Fena doesn’t have control over it. Meaning, our customers/merchants can’t change that order’s parameters, cancel it etc.
  3. On the other hand, end-users have full control over initiated standing orders. Meaning, they can change any parameter of their order (except for reference field) or cancel it. Currently, banks don’t notify third-party providers like us about these changes. So we developed our own mechanisms for tracking edge-cases. Details below.
  4. Most of the banks don’t make payments on weekends or bank holidays. So if your next payment is on the weekend, most probably you will get it on the nearest working day after that weekend. And most of the banks won’t accept your standing orders and will throw an error if you try to initiate order with the “first payment date” parameter set to Saturday/Sunday.
  5. “Reference” field is a crucial part of the standing orders flow in Fena and its uniqueness is important for our various services to function as expected. Because of this we are limiting customer-supplied Reference in the request payload to 12 characters but adding “-xxxxx” randomly generated suffix on our side. Therefore, banks are getting customer-supplied payload for standing order not with the Reference they have sent, but with the pre-processed value from our side. Hence, it’s recommended for our customers to show on their portals not the end-user inputted value for the "Reference" but what they are getting back from Fena side instead.

General flow

General flow for initiating standing order with Fena is pretty much the same as with any other payment types we support. First, customers need to POST /domestic-standing-order-consents to register their intent to make a recurring payment with the selected bank and to get back authorisation URI, to which their end-users should be redirected to approve the payment. Detailed API spec can be found here.

One optional but special parameter here is accountConsentId. It is an ID of account access consent for the bank account which you want to receive the recurring payments into. Put simply, if you want your end-user to pay you regularly into one of your bank accounts and you want to be notified by Fena about funds received, payments missed etc. (read more about notifications below), then you will want to give us access to your account so Fena is able to track the incoming payments. More about how it can be done, what account access consent mean, what you can do with it can be found here

Back to the standing order’s flow. Once the end-user authorises the payment on the bank’s side they are redirected back to Fena and we complete the initiation process with the bank. Once everything is done on our side we redirect end-users back to our customer’s platform. The redirect URI which is used in this case is either supplied with every call to create a standing order consent endpoint, which was explained above, or is set on a Fena account level, when you contact us and request access to Direct Banking integration API. Important, client_id and client_secret header values which customers need to supply with every call to standing order endpoints are also shared with you upon registration with Fena. Contact email, support@fena.co

Fena will send back a few parameters related to standing order as well in the form of query string when end-users are redirected to the customers portal. These are id, status, customerPaymentId and message. id is an identification number of the standing order on Fena side, status is one of the enum values we have standardised for the initiation process, usually initiation_pending, initiation_completed or initiation_failed. customerPaymentId is customer supplied arbitrary value, which usually is used to identify the standing order on customer’s side and message is human-readable text about the result of a payment initiation.

Webhooks

The webhook URI to which Fena sends webhook messages to, can be configured the same way as is the case with Redirect URI - either per-request basis or setting it on Fena account level upon registering with Fena.

Webhooks play a bit more of an important role in standing orders flow compared to our other payment types. If our customers give us access to their bank accounts with which they are planning to receive payments from standing orders, then we are able to track whether payments were actually received or missed. And upon getting these updates we are notifying our customers with webhook messages.

General structure of payload sent via webhook looks like this:

{
type: ‘domestic_standing_order’,
id: ‘b77a3df7-51b1-44ec-a56b-ffc32fbed49b’, // identifier for standing order
status: pending_payment | missed_payment | payment_made | partial_payment | unable_to_check | permanent_connection_loss,
amount: ‘1.25’, // amount of a payment in GBP
details: { … } // payment details
}

We have 6 statuses for standing order webhooks. First 4 of them relate to the actual payment record we are looking for in the bank account - meaning, whether we were able to identify payment and what parameters it had. missed_payment and payment_made are self-explanatory. pending_payment is for cases when we didn’t find payment in bank account but it’s a bank holiday or weekend. Most of the banks won’t process payments on those days so our lookup for that payment is pushed forward to the nearest working day. partial_payment is for cases when the payment was identified but its amount doesn’t equal to the amount which was registered while initiating the standing order. As was explained at the Specifics section, end-users are able to change standing order parameters (including amount) however they want and banks won’t notify us about these changes. So it is always a good idea to check the amount field of Fena’s webhook message. amount is present only when status is partial_payment. For all other cases, it’s null.

2 last statuses are for cases when Fena loses connection to customers bank account and is unable to track payments anymore. It can happen for technical reasons from the bank side, some edge cases on our side or just customers revoking the account access consent from their bank app. When Fena loses connection to the bank account we first send unable_to_check status. After trying 5 times without successful results we are sending permanent_connection_loss status and stop checking that bank account. Time-wise it lasts about 1.5 days as we are checking for payments 3 times a day.

Webhook details heavily depends on what status is sent. And to which bank our customer’s account belongs as different banks include different data about the payment we are fetching via their API. With payment_made and partial_payment statuses we are sending payment data we have fetched. It will be wrapped in the details.message object. The general structure of data can be found here as we are using the same /transactions API of the banks. So there will be single transaction data wrapped in details.message. For other statuses details.message is human-readable notification. For example, “Date is on Bank Holiday, no payment made on 07-04-2022T08:00:00+000Z”, in case of a pending_payment status.

Delayed standing order processing

When bank systems are overloaded, calls to create standing orders are not always processed immediately and hence we are getting initiation_pending status and streaming that back to our customers as a query string on end-users redirect back. Fena tracks all pending orders automatically and notifies customers once their statuses change, usually from initiation_pending to initiation_completed. We notify customers via webhook message to the same webhook uri that is configured on their Fena account or is associated with the given standing order.

General structure of webhook payload:

{
type: ‘domestic-standing-order-status’,
status: // new detected status of standing order,
comment: ‘detected standing order payment status update’,
data: { … } // order details
}

Critical: after receiving a webhook event for a standing order’s status update, always call our GET endpoint to double-check whether the webhook event originated from Fena. For UK banks it is GET domestic-standing-orders/{consentId}. consentId being a standing order identifier you have got back with authorization URI on your very first call to create standing order consent. Detailed API spec here. If the webhook originated from us then this endpoint will return the same status as was stated in the webhook event. Otherwise status returned from GET request takes precedence.