NAV Navbar
  • Returning Bacs Credits (ARUCS)
  • Returning Bacs Credits (ARUCS)

    This guide explains how to use the Form3 API to return an inbound Bacs Direct Credit payment based on the Automated Return of Unapplied Credits Service (ARUCS).

    We will first go over the mechanics of credit returns in Bacs. Then follows a step-by-step guide on how to send a Direct Cebit return with the Form3 API including a code example.

    About ARUCS and Returning Bacs Direct Credits

    The ARUCS service handles the return of Bacs Direct Credits in case of an error or when the credit can not be applied. The most common reasons include a deceased account holder or the account having been transferred.

    If you discover that an inbound Direct Credit cannot be applied, you have to return it using ARUCS. Using the Form3 API, you can do this by creating a Payment Return resource and sending it by creating a Payment Return Submission resouce.

    Note that the Payment Return resource needs to reference the original Payment resource, so you can only issue returns for payments that have been received through the Form3 API.

    Bacs Direct Credit returns follow Bacs' 3-day cycle just like any other Bacs payment. Although you will receive the notice of the inbound payment on day 2 of the Bacs cycle, you will not be able to issue the return until day 3 when the payment is entered. As soon as the return is submitted, a new 3-day cycle begins, meaning the return payment will arrive at the original debtor no earlier than on day 5 of the original payments' Bacs cycle.

    Bacs Cycle

    Automatic Returns

    This tutorial focuses on manual returns. Form3 automatically returns inbound payments on your behalf in case it receives a payment to an account number that is not registered together with your sort code with Form3.

    When this happens, a Payment Admission resource and a Payment resource are created just like for any payment. The status attribute of the Payment Admission resource will say failed and the status_reason attribute will specify the reason as unknown_accountnumber.

    Below is an example of a failed inbound payment with the Payment resource, as well as the related Payment Admission resource.

    Failed payment due to unknown account number

    "data": {
        "type": "payments",
        "version": 0,
        "id": "3e099d9c-3c59-4be7-8298-1c2121c4d931",
        "organisation_id": "2ffed0e3-876a-cb70-06b1-a27dd0884449",
        "attributes": {
            "amount": "23.40",
            "beneficiary_party": {
                "account_name": "James Bond",
                "account_number": "12345678",
                "account_number_code": "BBAN",
                "account_with": {
                    "bank_id": "654321",
                    "bank_id_code": "GBDSC"
                },
                "address": [
                    "1 Clarence Mew",
                    "Horsforth",
                    "Leeds Ls18 4EP"
                ],
                "country": "GB"
            },
            "currency": "GBP",
            "debtor_party": {
                "account_name": "Jane Bond",
                "account_number": "87654321",
                "account_number_code": "BBAN",
                "account_with": {
                    "bank_id": "123456",
                    "bank_id_code": "GBDSC"
                },
                "address": [
                    "2 Alexandra Crescent",
                    "Ilkley",
                    "LS29 9ER"
                ],
                "country": "GB"
            },
            "numeric_reference": " 0001",
            "end_to_end_reference": "00151519632ZCBBBJQ",
            "scheme_transaction_id": "123",
            "payment_scheme": "BACS",
            "processing_date": "2018-12-10",
            "reference": "05761374/001",
            "scheme_payment_type": "Credit",
            "scheme_processing_date": "0001-01-01",
            "unique_scheme_id": "008630DD"
        },
        "relationships": {
            "direct_debit_admission": {
                "data": [
                    {
                        "attributes": {
                            "admission_datetime": "2018-12-07T00:45:48.016Z",
                            "status": "failed",
                            "status_reason": "unknown_accountnumber"
                        },
                        "id": "b00ced15-4e84-4c60-8a33-b9d22e1d76bb",
                        "organisation_id": "2ffed0e3-876a-cb70-06b1-a27dd0884449",
                        "type": "payment_admissions",
                        "version": 0
                    }
                ]
            },
            "payment_return": {
                "data": []
            },
            "payment_reversal": {
                "data": []
            }
        }
    }
    


    Note that this payment never actually reached you, despite there being a Payment resource. The resource is only created for bookkeeping purposes.

    If a payment gets returned although the account number is valid, make sure you have registered this account number with Form3. See here to learn how to do that.

    Contras

    Bacs uses contras to sum up return transactions for the originator account. This means that when sending one or more Direct Credit returns, you will receive a contra on Bacs day 4. Because a contra "counters" the Direct Credit return, it is modeled in the API as a Direct Debit resource and a Direct Debit Admission resource. Note that although the contra appears as a regular transaction, no funds are transferred with it.

    Since Bacs is a bulk processing system, transactions are sent to Bacs in batches and a contra record is generated for each batch of Direct Credit returns. Form3 batches and sends transactions to Bacs a few times a day, so a contra can cover any number of Direct Credit returns between just one and all that have been submitted in a day. This includes automatic returns that have been created by Form3 on your behalf (see above).

    A contra will sum up all Direct Credit returns in a batch. For example, if you have created three Direct Credit returns with an amount of 10.00 each and Form3 has created an automated return with an amount of 15.00, the contra amount would be 45.00.

    In contrast to a regular Direct Debit, the beneficiary and debtor account of a contra is identical and points to your main settlement account that you have registered with Bacs.

    You can distinguish a contra from a regular Direct Debit by looking at the reference attribute of the Direct Debit resource. For a contra, it will contain the value               BACS (the word BACS preceded by 14 spaces).

    Below is an example of a Direct Debit resource for a contra:

    Direct Debit resource and admission for a contra

    {
      "data": {
        "type": "direct_debit",
        "version": 0,
        "id": "896257de-5811-47cb-9d62-e67e4c7eddc5",
        "organisation_id": "cbb1a063-ffda-4e07-8471-5e6696c8a849",
        "attributes": {
          "amount": "2345.00",
          "beneficiary_party": {
            "account_name": "ABCD",
            "account_number": "12345678",
            "account_number_code": "BBAN",
            "account_with": {
              "bank_id": "123456",
              "bank_id_code": "GBDSC"
            },
            "address": null
          },
          "clearing_id": "100026",
          "currency": "GBP",
          "debtor_party": {
            "account_name": "ABCD",
            "account_number": "12345678",
            "account_number_code": "BBAN",
            "account_with": {
              "bank_id": "123456",
              "bank_id_code": "GBDSC"
            },
            "address": null
          },
          "numeric_reference": "0001",
          "payment_scheme": "BACS",
          "processing_date": "2018-12-05",
          "reference": "              BACS",
          "scheme_payment_type": "DirectDebit",
          "unique_scheme_id": "12345678"
        },
        "relationships": {
          "direct_debit_admission": {
            "data": [
              {
                "attributes": {
                  "admission_datetime": "2018-12-04T15:37:12.809Z",
                  "status": "confirmed",
                  "status_reason": "accepted"
                },
                "id": "a0007046-961e-4225-89b3-055459b35b88",
                "organisation_id": "cbb1a063-ffda-4e07-8471-5e6696c8a849",
                "type": "direct_debit_admissions",
                "version": 0
              }
            ]
          },
          "direct_debit_return": {
            "data": []
          },
          "direct_debit_reversal": {
            "data": []
          }
        },
      }
    }
    


    Note that contras are also issued for Direct Debit returns (ARUDD). In that case, the Form3 API models them as a Payment and Payment Admission resource. See here for more information on ARUDDs.

    Step by Step Guide

    Now we'll walk you through each step of creating and sending an ARUCS return. Code examples are provided to illustrate the steps. You will:

    The code example is written in Python using the requests package to access the Form3 API. Each code snippet is a standalone Python program, but make sure to paste the required data for each program at the top. The snippets are tested with Python 3.5, but most likely will also work with other Python versions.

    Prerequisites

    Before getting started, make sure you have the following things ready to follow along:

    Subscribe to Payment Admission and Contra Events

    You can use Form3's Notification API to be notified when inbound transaction or other messages arrive. Create a subscription for a event type and a record type to be notified through a webhook or SQS queue when this event occurs for a type of resource.

    See this tutorial to learn how to create a subscription and receive notifications.

    Payment Admissions

    When an inbound payment arrives, Form3 creates a Payment resource and a Payment Admission resource. In order to be notified when this happens, subscribe to the creation of Payment Admission resources:

    Contras

    Contras for Direct Credit returns are modeled as Direct Debit and Direct Debit Admission resources. To be notified when a contra arrives, create a subscription for the creation of Direct Debit Admission resources:

    Receive a Payment

    In order to return a payment, you need to receive that payment first. For this tutorials, we're using Form3's transaction simulator to receive a payment we can return. The simulator allows you to trigger an inbound payment by sending a payment with an amount of 600.00.

    Upon acceptance of the trigger payment, the simulator issues a payment with the same values as an inbound payment.

    Send a Trigger Payment

    To send a trigger payment, first create a Payment resource. Note the following key attributes:

    Take a look at this tutorial and example to learn how to create a Payment resource.

    Finally, to send the trigger payment, create a Payment Submission resource. See here to learn how.

    Get the Incoming Payment

    Upon successful delivery of the trigger payment, the transaction simulator will generate a Payment Admission resource to indicate an inbound payment. Since you subscribed to the creation of Payment Admissions above, check your webhook or SQS queue for a notification that an admission has been created.

    You can find the Payment resource referenced in the relationship section of the Payment Admission resource, either directly or by performing a GET request on the ID of the resource in the payment.data.id field.

    Note that the admission_datetime field of the Payment Admission is adjusted to fit the 3-day Bacs cycle and thus shows the date of the next working day.

    Notification for a Payment Admission resource

    {
      "id": "959a1153-36b8-473e-a1f7-aae6fc34c1ae",
      "organisation_id": "c969013c-76da-43f1-978b-059260a9eb4a",
      "event_type": "created",
      "record_type": "payment_admissions",
      "data": {
          "attributes": {
            "admission_datetime": "2018-11-01T16:16:14.838Z",
            "status": "confirmed",
            "status_reason": "accepted"
          },
          "relationships": {
            "payment": {
              "data": [
                {
                  "type": "payments",
                  "id": "3b9750f9-f2b3-4d27-9a59-f6cf932af287"
                }
              ]
            }
          }
        }
      }
    }
    


    Use the payment ID to retrieve the inbound payment resource through the GET /transaction/payments/{payment_id} call. The payment data should look similar to this:

    Payment resource of the inbound payment

    "data": {
        "type": "payments",
        "id": "3b9750f9-f2b3-4d27-9a59-f6cf932af287",
        "version": 0,
        "organisation_id": "c969013c-76da-43f1-978b-059260a9eb4a",
        "attributes": {
            "amount": "600.00",
            "beneficiary_party": {
                "account_name": "MRS RECEIVING TEST",
                "account_number": "71268996",
                "account_number_code": "BBAN",
                "account_type": 0,
                "account_with": {
                    "bank_id": "400302",
                    "bank_id_code": "GBDSC"
                }
            },
            "clearing_id": "112233",
            "currency": "GBP",
            "debtor_party": {
                "account_name": "MR SENDING TEST",
                "account_number": "87654321",
                "account_number_code": "BBAN",
                "account_with": {
                    "bank_id": "XXXXXX",
                    "bank_id_code": "GBDSC"
                }
            },
            "numeric_reference": "0001",
            "scheme_transaction_id": "13495393740104154",
            "unique_scheme_id": "12345678",
            "payment_scheme": "BACS",
            "processing_date": "2018-10-30",
            "reference": "D/1234567890123456",
            "scheme_payment_type": "Credit"
        }
    }
    

    Return the Payment

    To return a Bacs Direct Credit payment, create a Payment Return resource and send it by creating a Payment Return Submission resource.

    Bacs credit returns have to adhere to the 3-day Bacs processing cycle. Although you will receive the payment information on Bacs day 2, Form3 will hold any submitted return transactions until Bacs day 3 of the original inbound payment's cycle.

    Since the transaction simulator issued the inbound payment for the next working day, you won't be able to submit the return until that day. Creating a Return Submission before the day mentioned in the admission_datetime attribute of the Payment Admission of the payment you want to return will result in a failed delivery for the return.

    Create the Return Payment

    To create a Payment Return resource, use the POST /v1/transaction/payments/{payment_id}/returns API call. Note that the call requires the ID of the original Payment resource in the payment_id URL parameter.

    The resource itself requires just one attribute when used with Bacs: return_code represents the reason for the return. It has to be a valid ARUCS return reason code, see here for a list of allowed codes. In this example, we're using 0, which translates to "Refer to payer".

    Payment return resource example

    {
      "data": {
        "id": "4e76b75e-552b-4377-a165-0e5dfa9d9cc5",
        "type": "returns",
        "organisation_id": "c969013c-76da-43f1-978b-059260a9eb4a",
        "attributes": {
          "return_code": "0"
        }
      }
    }
    

    Create the Return Submission

    Finally, send the return by creating a Payment Return Submission resource with POST v1/transaction/payments/{payment_id}/returns/{return_id}/submissions.

    Keep in mind that you won't be able to submit the return until the admission date of the payment you want to return.

    Payment return submission resource example

    {
      "data": {
        "type": "return_submissions",
        "id": "2650e374-1075-4cb2-8f4a-70d6b63d0280",
        "version": 2,
        "organisation_id": "c969013c-76da-43f1-978b-059260a9eb4a",
        "attributes": {
          "status":"delivery_confirmed",
          "status_reason":"Accepted without qualification",
          "scheme_status_code": "",
          "scheme_status_code_description": "",
          "settlement_date": "2018-10-31",
          "settlement_cycle": 1,
          "redirected_bank_id": "400300",
          "redirected_account_number":"12345678",
          "submission_datetime": "2018-10-30T14:11:48.055Z",
          "limit_breach_start_datetime": "",
          "limit_breach_end_datetime": "",
          "transaction_start_datetime": "2018-10-30T14:11:50.055Z"
        },
        "relationships": {
          "payment": {
            "data": [
              {
                "type": "payments",
                "id": "20b1f7a2-83c7-45d3-a6e3-0a75b14b9f7f"
              }
            ]
          },
          "payment_return": {
            "data": [
              {
                "type": "returns",
                "id": "4e76b75e-552b-4377-a165-0e5dfa9d9cc5"
              }
            ]
          }
        }
      }
    }
    


    This Python example creates a return transaction for an existing inbound payment:

    Return transaction example

    import math, requests, time, uuid
    
    ### Replace these variables with your own data! ###
    client_id = 'YOUR CLIENT ID HERE'
    client_secret = 'YOUR CLIENT SECRET HERE'
    organisation_id = 'YOUR ORGANISATION ID HERE'
    payment_id = 'ID OF THE ORIGINAL PAYMENT HERE'
    
    base_url = 'https://api.staging-form3.tech/v1'
    
    # Generate IDs
    return_id = uuid.uuid4()
    print("Return ID: %s" % return_id)
    
    submission_id = uuid.uuid4()
    print("Submission ID: %s" % submission_id)
    
    # Obtain authentication token
    print("Obtaining bearer token...")
    auth_payload = "grant_type=client_credentials"
    auth_url = '%s/oauth2/token' % base_url
    auth_headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    auth_request = requests.auth.HTTPBasicAuth(client_id, client_secret)
    
    auth = requests.request('post', auth_url, data=auth_payload, auth=auth_request, headers=auth_headers)
    auth_token = auth.json().get('access_token')
    
    # Create the return resource
    print("Creating Payment Return resource...")
    return_url = "%s/transaction/payments/%s/returns" % (base_url, payment_id) 
    return_payload = """
    {
      "data": {
        "id": "%s",
        "type": "returns",
        "organisation_id": "%s",
        "attributes": {
        "return_code": "0"
        }
      }
    }  
    """ % (return_id, organisation_id)
    
    return_headers = {
        'authorization': "bearer " + auth_token,
        'accept': "application/json",
        'content-type': "application/json",
        'cache-control': "no-cache"
        }
    
    payment_return = requests.request("POST", return_url, data=return_payload, headers=return_headers)
    print(payment_return.text)
    
    # Create the submission resource
    print("Creating Payment Return Submission resource...")
    submission_url = "%s/transaction/payments/%s/returns/%s/submissions" % (base_url, payment_id, return_id)
    submission_payload = """
    {
      "data": {
        "id": "%s",
        "type": "return_submissions",
        "organisation_id": "%s"
      }
    }
    """ % (submission_id, organisation_id)
    
    submission_headers = {
        'authorization': "bearer %s" % auth_token,
        'accept': "application/json",
        'content-type': "application/json",
        'cache-control': "no-cache",
        }
    
    submission = requests.request("POST", submission_url, data=submission_payload, headers=submission_headers)
    print(submission.text)
    

    Track the Return Payment

    You can follow the path of your return transaction through the system by fetching the submission resource: GET v1/transaction/payments/{payment_id}/return/{return_id}/submissions/{submission_id}

    The following attributes can be helpful to determine the status of the return transaction:

    Here's how you can fetch the submission resource to check the status attributes:

    Track the return submission status

    import requests
    
    ### Replace these variables with your own data! ###
    client_id = 'YOUR CLIENT ID HERE'
    client_secret = 'YOUR CLIENT SECRET HERE'
    payment_id = 'A VALID PAYMENT ID HERE'
    return_id = 'A VALID RETURN ID HERE'
    submission_id = 'A VALID SUBMISSION ID HERE'
    
    base_url = 'https://api.staging-form3.tech/v1'
    
    # Obtain authentication token
    print("Obtaining bearer token...")
    auth_payload = "grant_type=client_credentials"
    auth_url = '%s/oauth2/token' % base_url
    auth_headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    auth_request = requests.auth.HTTPBasicAuth(client_id, client_secret)
    
    auth = requests.request('post', auth_url, data=auth_payload, auth=auth_request, headers=auth_headers)
    auth_token = auth.json().get('access_token')
    
    get_subm_url = "%s/transaction/payments/%s/returns/%s/submissions/%s" % (base_url, payment_id, return_id, submission_id)
    get_subm_headers = {
        'authorization': "bearer %s" % auth_token,
        'cache-control': "no-cache",
        }
    
    get_subm = requests.request("GET", get_subm_url, headers=get_subm_headers)
    
    print(get_subm.text)
    


    You now know how to send a Bacs Direct Credit return. See our other Bacs tutorials to learn more about: