Working with Payment Sources

Overview

In order for your customer to be able to make a payment, first they need to authorise their bank to transfer funds from their account to your account. This is known in their bank account as a 'Beneficiary'.

For some banks, creating a beneficiary can have a cool-down period of up to 24 hours, which is why we have separated the flow into two distinct parts so that users can complete future initiations without having to enter passwords and wait for cool-down periods.

📘

Please note: Setting up payments does not require actually making a payment from your end-user, in order to make functionality available as soon as possible to your customer, you can connect/create a Payment Source during initial onboarding.

Creating the Payment Source

On your Front-end, make a .connect() call to the LinkSDK to guide your user through the process of creating a beneficiary. For further information on integrating the LinkSDK into your platform please see the LinkSDK integration documentation at https://docs.leantech.me/docs/web. For the purposes of this guide we will be using Javascript as the language being used by the front-end.

// page.html
<button onClick={() => leanConnect(...params)}>Set up payments</button>

<!-- script.js -->
<script>
function leanConnect(customer_id) {
  Lean.connect({
    app_token: "YOUR_APP_TOKEN",
    permissions: ["payments"],
    customer_id: customer_id,
    payment_destination_id: "266733cc-6f46-4e87-af7e-9bb46b99601d", //this param is optional; if not sent, the default payment destination will be linked 
    sandbox: "true"
  })
}
</script>

When a customer completes the LinkSDK - please note, no details are shared directly from the SDK to your front-end. A Success, Error or Cancelled message can be returned from the SDK via a callback (depending on the platform you're integrating with, this is handled differently) in the following format:

{
    "status": "SUCCESS",
    "method": "CREATE_PAYMENT_SOURCE",
    "message": "Customer created Payment Source successfully"
}

The details of your newly created entity will instead be sent via a webhook to your backend services. Your front-end should therefore handle the success by making a call to your backend to refresh the data.

Payment Source webhooks

When a customer creates a Payment Source using the LinkSDK, your backend will receive two webhooks, one payment_source.created and one payment_source.beneficiary.created webhook.

For the purpose of this guide, please respond to the payment_source.created webhook with a 200 response and ignore it.

The payment_source.beneficiary.created webhook will look like this:

{
  "payload": {
    "id": "bda4dcee-e786-4a85-9032-737c06a27944",
    "customer_id": "a14943ad-ee75-45cd-a5aa-69ba76a359b5",
    "payment_source_id": "22e904e9-9c35-45b4-ad31-dec8270fadd0",
    "payment_destination_id": "9de0f453-6f54-4e18-956e-2008761b189f",
    "status": "AWAITING_BENEFICIARY_COOL_OFF",
    "payment_source_bank_identifier": "LEANMB1_SAU"
  },
  "type": "payment_source.beneficiary.created",
  "message": "A beneficiary was added for a payment source.",
  "timestamp": "2023-03-21T12:39:55.65440435Z",
  "event_id": "e2f7dd66-84a2-44bf-afe8-32922ae66833"
}

The key component here is the AWAITING_BENEFICIARY_COOL_OFF status. This status indicates that there is a cool down period before the account is chargeable. If the status is ACTIVE your customer can make a payment immediately.

Fetch the Payment Source

Using the payment_source_id in the payload from the payment_source.beneficiary.created webhook, fetch the newly created Payment Source and save it to your database:

Call:

curl -X GET 'https://sandbox.leantech.me/customers/v1/<customer_id>/payment-sources/<payment_source_id>' \
  --header 'Content-Type: application/json' \
  --header 'lean-app-token: YOUR_APP_TOKEN'

Response:

{
  "id": "d8d7a9b3-c401-49f6-81a4-386d8398aa2c",
  "customer_id": "6db94cb7-3a02-4a57-a03a-e2a92ce86406",
  "app_id": "2c9280887230f322017231b408cf0007",
  "bank_identifier": "LEANMB1",
  "beneficiaries": [
    {
      "id": "26891A75-9406-4E06-97BA-F4D6DA664F3C",
      "payment_destination_id": "266733cc-6f46-4e87-af7e-9bb46b99601d",
      "status": "AWAITING_BENEFICIARY_COOL_OFF",
      "beneficiary_cool_off_expiry": "2021-02-13T13:20:57.674299Z"
    }
  ],
  "accounts": [
    {
      "id": "9acde98e-9d19-495d-934c-b2ff966262c8",
      "account_id": "aaadbc4e-96a4-420f-ba01-597fa63502ee",
      "account_name": "CURRENT ACCOUNT",
      "account_number": "1015528734001",
      "iban": "AE340260001015528734001",
      "balance": null,
      "currency": "AED",
      "balance_last_updated": null
    }, {
      "id": "1457d23a-c1f8-4aee-bc6f-2a253b2e617f",
      "account_id": "69f22112-e95d-427e-8bd1-eb58b4db60ba",
      "account_name": "CURRENCY PASSPORT SAVINGS AC",
      "account_number": "0315528734002",
      "iban": "AE790260000315528734002",
      "balance": null,
      "currency": "USD",
      "balance_last_updated": null
    }
  ]
}

Note: The "balance" field under the accounts object has been deprecated.

Send a notification when your Customer's Payment Source becomes active

When a Payment Source's Beneficiary switches from AWAITING_BENEFICIARY_COOL_OFF to ACTIVE another webhook is sent to your server, notifying you that an update has been made.

You can use this webhook to drive Push Notifications to bring your customer back into your application to complete a purchase or top up an account.

{
  "payload": {
    "id": "bda4dcee-e786-4a85-9032-737c06a27944",
    "customer_id": "a14943ad-ee75-45cd-a5aa-69ba76a359b5",
    "payment_source_id": "22e904e9-9c35-45b4-ad31-dec8270fadd0",
    "payment_destination_id": "9de0f453-6f54-4e18-956e-2008761b189f",
    "status": "ACTIVE",
    "payment_source_bank_identifier": "LEANMB1_SAU"
  },
  "type": "payment_source.beneficiary.updated",
  "message": "A beneficiary was updated for a payment source.",
  "timestamp": "2023-03-21T12:59:42.928834676Z",
  "event_id": "6d1ea28d-f734-415b-8cd6-b1bb94c52775"
}

What’s Next