Only this pageAll pages
Powered by GitBook
1 of 38

Flash Payments Developer API

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Overview

Flash Payments Developer API documentation

General information

Complete API docs

High level feature overview

Instant local Australian deposit (aka pay-in)

You would get a dedicated Australian BSB and a Virtual Account Number (VAN).

Warning: The account number can only process local transfers, no SWIFT/RTGS.

Any funds deposited to that account would increase your Flash Payments balance. We preserve the provided payment reference of every deposit for your further utilisation. E.g. invoice number or else.

By default, only yourself is allowed to deposit to it. However, the third party deposits are also possible. Although, we would need to enable this setting for you separately.

Sometimes, banks can delay your deposit by up to 24 hours. This should be expected. But typically, deposits are reflected in your Flash Payments balance immediately.

Local Australian withdrawal (aka pay-out)

This API allows you to withdraw your Flash Payments balance. By default, only yourself is allowed to receive those funds. The third party withdrawals (aka payouts) are also possible. Although, we would need to enable this setting for you separately.

If your payout is a part of FX payments, we are legally obliged to use classic Australian payment system a.k.a. Direct Entry. It would take from 0 up to few hours to deliver such funds. Otherwise, payouts are delivered to the recipient instantly.

If a payout fails you will receive a webhook notification with a clear explanation of what went wrong. This is typically bank account number typos.

The payout remitter name is configurable. You can give us the remitter name as withdrawal.sender data property. This is especially useful for FX-linked payouts. If a Brazilian mama Katarina Oreiro sends money to her son in Australia, he will see his mom's name in the bank statement - "Payment from Katarina Oreiro".

Send or receive money internationally

You can send you Flash Payments balance internationally via our API and enjoy instant delivery to countries with local instant payment systems, e.g. Philippines. By the way, cash payments to Philippines are also supported.

Your code would need to pre-create both sender and recipient before creating a payment for them.

Depending on the recipient's country a payment can take from few minutes to few days. You would receive a webhook notification when a payment state changes.

In most cases you can send money to your Flash Payments balance. This can be automated. You will receive a webhook notification when we see you sending to Flash Payments from other countries.

Security

The API token you generate expires in 4 hours. You can always use logout GraphQL mutation to expire it earlier.

You can't reset your own password until we verify your identity.

Webhooks have cryptographic signatures.

IP address whitelisting feature is available from FlashConnect interface allowing login to our APIs from only preapproved addresses that you specify.

API rate limiting is in place to ensure stable performance of our service and prevent its potential abuse.

How to start

  1. Explain what kind of services you are looking from Flash Payments.

  2. We will examine your needs and explain how to get access to our UAT environment.

Important notes

Breaking changes

While we will endeavour to not introduce any breaking changes they might still occur in the future. In that case we will communicate about the upcoming changes via your registered email.

Flash Payments API is based because GraphQL is simpler and easier than REST API and more developer friendly. Although, the data you send and receive is all JSON.

Flash Payments API playground is located here:

This documentation website does not have full list of API fields and methods. This is intentional. The full list of the API calls you can performs and the data fields you can send/receive is listed in the (click "DOCS" on the right hand side).

You can search, visualise, or extract your data using our FlashConnect product:

If set, you would get a webhook (aka callback) notification about every deposit made to your VAN. Go to the to setup a deposit webhook.

You can manually reject unwanted deposits via the interface. The funds will be returned to the original sender bank account.

Payouts can also be done via the interface.

All the entities in our database (withdrawal, payment, sender, recipient) can hold your system's ID. See the externalId field in the .

The interface supports Google and One-Time-Password logins.

Contact with us via or by clicking the Intercom button on the bottom right of this page.

For more detailed instructions head to the page.

GraphQL
https://api.uat.flash-payments.com.au/
API Playground
https://connect.uat.flash-payments.com.au/
https://connect.uat.flash-payments.com.au/
https://connect.uat.flash-payments.com.au/
https://connect.uat.flash-payments.com.au/
API docs
https://connect.uat.flash-payments.com.au/
this page
Basics

Conversions

Convert between your multi currency balances

To convert between, say, AUD and EUR you should:

  1. request a tradeable quote with the applicability: CONVERSION, and

  2. use it whilst creating a conversion.

Get a quote ID:

{
  quote(
    input: { 
      fromCurrency: AUD
      toCurrency: EUR
      size: 10000
      currency: AUD
      tradeable: true
      applicability: CONVERSION
    }
  ) {
    id
    bid
    ask
    symbol
    timestamp
    inverted
    expireAt
  }
}
{
  "data": {
    "quote": {
      "id": "6711ec0e950ae23de886ebe5",
      "bid": 0.61104,
      "ask": 0.62077,
      "symbol": "USDAUD",
      "timestamp": "2024-08-13T07:54:54.993Z",
      "inverted": true,
      "expireAt": "2024-08-13T07:55:54.993Z"
    }
  }
}

Convert funds:

mutation {
  createConversion(
    input: {
      note: "for major client"
      externalId: "561402"
      quoteId: "6711ec0e950ae23de886ebe5"
      callbackUri: "https://example.com/my-webhook/endpoint/"
    }
  ) {
    success
    code
    message
    conversion {
      id
      fromCurrency
      toCurrency
      currencyPair
      fromAmount
      toAmount
      rate
      note
      status
      statusMessage
      callbackUri
      externalId
      createdAt
      updatedAt
    }
  }
}
{
  "data": {
    "createConversion": {
      "success": true,
      "code": "CREATED",
      "message": "Conversion successfully created",
      "conversion": {
        "id": "6711f0a7b549a701ebeb02ac",
        "fromCurrency": "EUR",
        "toCurrency": "AUD",
        "currencyPair": "AUDEUR",
        "fromAmount": 101,
        "toAmount": 159.81,
        "rate": 0.63199,
        "note": "for major client",
        "status": "PENDING",
        "statusMessage": "Awaiting execution",
        "callbackUri": "https://example.com/my-webhook/endpoint/",
        "externalId": "561402",
        "createdAt": "2024-10-18T05:22:47.433Z",
        "updatedAt": "2024-10-18T05:22:47.433Z"
      }
    }
  }
}

Basics

General information how to start using Flash Payments API

Assumptions

The examples below assume you are a verified customer of Flash Payments and have been enabled for API access.

GraphQL Playground

echo '{
  "query":
    "{
       quote(input: {
         fromCurrency: AUD, toCurrency: USD, size: 9.9, currency: AUD
       })
       {
         bid ask symbol timestamp inverted
       }
     }"
}' | curl -X POST 'https://api.uat.flash-payments.com.au' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'content-type: application/json' \
-d @-

All the responses are JSON and have at least one property data and optional property errors.

{
  "data": { ... },
  "errors": [ ... ]
}

Tip

In GraphQL Playground query editor press Cmd+Space or Ctrl+Space or Opt+Space or Alt+Space or Shift+Space to show context help and possible options.

Some of the GraphQL query parameters are required, others are optional. To understand if a variable/property is required you would need to check the API schema.

  • Browse through queries, mutations, input and output types. Find a variable/property which have an exclamation mark at the end. E.g. fromCurrency: FromCurrency!.

  • The exclamation mark denotes that the variable/property is mandatory.

Data cleansing is your responsibility

Do not ever send us "N/A" or "NA" or "NULL" or "null" or "nil" or any other dummy string values in any of the API fields.

The user-agent HTTP header

It is a good idea to always send custom user-agent HTTP header value when doing requests to Flash Payments API. Here is why:

  • In case of troubleshooting we will be able to trace and mitigate your support questions faster.

  • You might be blocked by our automated firewall if your user agent is something generic like curl, Java-http-client, python-requests, Ruby, etc.

429 Too many requests

Our API have smart monitoring. It might temporary block your IP address if it thinks you are abusing the system. There are many various scenarios when you can be blocked, but we won't going to disclose them at any point of time due to security reasons.

All the GraphQL queries can be sent via the or as a HTTP POST request to https://api.uat.flash-payments.com.au. Example:

Go to the and click the button "DOCS" on the right.

GraphQL Playground
GraphQL Playground

Query conversions

You can query all your past conversions

Retrieving all your conversions

{
  conversions {
    id
    fromCurrency
    toCurrency
    rate
    # there are many other properties
  }
}
{
  "data": {
    "conversions": [
      {
        "id": "6b04c62ec0bf606bf216ae21",
        "fromCurrency": "AUD",
        "toCurrency": "EUR",
        "rate": 0.71
      },
      {
        "id": "6b04c6bfc0bf606bf216af06",
        "fromCurrency": "AUD",
        "toCurrency": "USD",
        "rate": 0.70
      },
      {
        "id": "6b04c8e3c0bf606bf216b026",
        "fromCurrency": "EUR",
        "toCurrency": "AUD",
        "rate": 0.71
      }
    ]
  }
}

Retrieving some of your conversions

{
  # there are more query parameters available, see the API schema
  conversions(input: { statuses: CONVERTED, toCurrencies: [EUR USD] }) {
    id
    fromCurrency
    toCurrency
    # there are many other properties
  }
}
{
  "data": {
    "payments": [
      {
        "id": "6b04c62ec0bf606bf216ae21",
        "fromCurrency": "AUD",
        "toCurrency": "EUR"
      },
      {
        "id": "6b04c6bfc0bf606bf216af06",
        "fromCurrency": "AUD",
        "toCurrency": "USD"
      }
    ]
  }
}

Retrieving a single conversion

{
  # there are more query parameters available, see the API schema
  conversion(id: "6b04c62ec0bf606bf216ae21") {
    status
    createdAt
    fromAmount
    toAmount
    # there are many other properties
  }
}
{
  "data": {
    "conversion": {
      "status": "CONVERTED",
      "createdAt": "2024-08-13T05:45:28.698Z",
      "fromAmount": 1000,
      "toAmount": 710.01
    }
  }
}

Conversion statuses

The GraphQL schema defines statuses like this:

enum ConversionStatus {
    INITIALISED
    PENDING
    CONVERTED
    FAILED
    CANCELLED
}

The current status of your conversion.

  • INITIALISED - a conversion was created but nothing else happened to it.

    • Typically never happens via API.

  • PENDING - the conversion is in progress. The typical status of the conversion after you create it.

  • CONVERTED - means successfully converted. You balances were updated accordingly.

  • FAILED - an error has occurred with this conversion. Termporary statement.

  • CANCELLED - the conversion didn't happen and has been cancelled.

    • Usually done by Flash Payments operations team.

Recipients

CRUD queries for your payment recipients

We are legally obliged to collect the actual recipient details. Please, do not send us an intermediate organisation details such as exchanges, banks, gateways, etc.

  • recipient and recipients queries - read your address book.

  • createRecipient - creates a new record in the Flash Payments database.

  • updateRecipient - updates an existing recipient.

  • deleteRecipient - deletes an existing recipient.

Query single recipient

{
  recipient(id: "12341234123412341234") {
    accountIdType
    currency
    country
    email
    # there are many other properties
  }
}
{
  "data": {
    "recipient": {
      "accountIdType": "ACC NO",
      "currency": "USD",
      "country": "AU",
      "email": "john@example.com"
    }
  }
}

Query multiple recipients

{
  recipients(input: { currency: USD }) {
    accountIdType
    currency
    country
    email
    # there are many other properties
  }
}
{
  "data": {
    "recipients": [
      {
        "accountIdType": "ACC NO",
        "currency": "USD",
        "country": "AU",
        "email": "john@example.com"
      }
    ]
  }
}

Create a recipient

In addresses thesuburbfield is an Australian suburb. For other countries you should put the city (e.g. Manila or London) or any other small administrative area name.

If you find it technically challenging to submit all components of the recipients’s address, we would appreciate it if you could at least collect the recipients’s country along with a complete address string that includes the postcode and put them into the country and street fields, respectively. In this case, you can skip the postcode, suburb, and state fields, and the recipient record will still be created.

mutation {
  createRecipient(
    input: {
      firstName: "John"
      lastName: "Malkovich"
      dob: "1987-06-05"
      accountIdType: BSB
      currency: AUD
      bsb: "370370"
      accountNo: "12341234"
      email: "john@example.com"
      address: {
        street: "22 Woolooware Rd"
        suburb: "Woolooware"
        state: "NSW"
        country: AU
        postcode: "2230"
      }
    }
  ) {
    success
    code
    message
    recipient {
      id
      nickName
      accountIdType
      currency
      email
      # there are many other properties
    }
  }
}
mutation {
  createRecipient(
    input: {
      companyName: "Acme Pty Ltd"
      accountIdType: BSB
      currency: AUD
      bsb: "370370"
      accountNo: "123412340"
      email: "acme@example.com"
      address: {
        street: "22 Woolooware Rd"
        suburb: "Woolooware"
        state: "NSW"
        country: AU
        postcode: "2230"
      }
    }
  ) {
    success
    code
    message
    recipient {
      id
      nickName
      accountIdType
      currency
      email
      # there are many other properties
    }
  }
}

Update recipient

Please note the recipient'saccountIdTypecan't be changed

mutation {
  updateRecipient(
    id: "5ba89a6b35a2b327b81ffc3b",
    input: {
      nickName: "JohnM"
    
      firstName: "John"
      lastName: "Malkovich"
      accountIdType: BSB
      currency: AUD
      bsb: "370370"
      accountNo: "12341234"
      email: "john@example.com"
      address: {
        street: "22 Woolooware Rd"
        suburb: "Woolooware"
        state: "NSW"
        country: AU
        postcode: "2230"
      }
    }
  ) {
    success
    code
    message
    recipient {
      id
      nickName
      # there are many other properties
    }
  }
}
{
  "data": {
    "createRecipient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Recipient updated",
      "recipient": {
        "id": "5ba89a6b35a2b327b81ffc3b",
        "nickName": "JohnM"
      }
    }
  }
}

Delete recipient

mutation {
  deleteRecipient(id: "5ba89a6b35a2b327b81ffc3b") {
    success code message
  }
}
{
  "data": {
    "deleteRecipient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Recipient deleted"
    }
  }
}

Please, send us the final funds recipient. If sending to self then please provide your own details. See the DOCS in for other recipient details options.

Playground

Sending data as JSON

Here is how to send your data to us as JSON instead of embedding it into the GraphQL queries.

Most of the documentation examples shows you how to send data by embedding values into the GraphQL queries.

echo '{
  "query":
    "{
       quote(input: {
         fromCurrency: AUD, toCurrency: USD, size: 9.9, currency: AUD
       })
       {
         bid ask symbol timestamp inverted
       }
     }"
}' | curl -X POST 'https://api.uat.flash-payments.com.au' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'content-type: application/json' \
-d @-

We understand that such long query strings would be difficult to construct with code. Here is how to send query and data separately.

You need to send us the JSON object with two properties - "query" and "variables".

  • Declare the $input variable in the QraphQL "query" string. The technology also requires you to declare the type of your input(s). See the QueryInput in the example below.

  • Provide the "variables" object with the "input" property. The value of it must be a JSON object structured exactly as the QueryInput type.

Do NOT provide any other GraphQL types except the highest level input argument. Otherwise, you risk to experience production issues when we deploy schema changes.

If you construct the GraphQL query using a third party library/software then you risk to violate the above requrement. We recommend to not use any GraphQL libraries.

echo '{
  "query":
    "query ($input: QuoteInput!) {
       quote(input: $input) { bid ask symbol timestamp inverted }
     }",
  "variables": { 
    "input": { "fromCurrency": "AUD", "toCurrency": "USD", "size": 9.9, "currency": "AUD" }
  }
}' | curl -X POST 'https://api.uat.flash-payments.com.au' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'content-type: application/json' \
-d @-

Here is a screenshot of how a typical mutation looks in the GraphQL Playground:

Same request as cURL:

echo '{
  "query":
    "mutation ($input: RecipientInput!) {
      createRecipient(input: $input) { code message recipient { id } }
    }",
  "variables": {
    "input": {
      "firstName": "Test",
      "lastName": "Lastest",
      "currency": "PHP",
      "accountIdType": "PH_CASH",
      "mobile": "+63 9121231234",
      "phCashoutNetwork": "MLHUILLIER",
      "address": {
        "building": "12th Floor Centerpoint Building",
        "street": "Julia Vargas Avenue corner Garnet Street",
        "suburb": "Pasig",
        "state": "manila",
        "country": "PH",
        "postcode": "1605"
      }
    }
  }
}' | curl 'https://api.uat.flash-payments.com.au' \
-H 'authorization: Bearer YOUR_TOKEN' \
-H 'content-type: application/json' \
-d @-

Senders

CRUD queries for your payment senders

We are legally obliged to collect the actual sender details. Please, do not send us an intermediate organisation details such as exchanges, banks, gateways, etc.

  • sender and senders queries - read your address book.

  • createSender - creates a new record in the Flash Payments database.

  • updateSender - updates an existing sender.

  • deleteSender - deletes an existing sender.

Query single sender

Query multiple senders

Create a sender

In addresses thesuburbfield is an Australian suburb. For other countries you should put the city (e.g. Manila or London) or any other small administrative area name.

If you find it technically challenging to submit all components of the sender’s address, we would appreciate it if you could at least collect the sender’s country along with a complete address string that includes the postcode and put them into the country and street fields, respectively. In this case, you can skip the postcode, suburb, and state fields, and the sender record will still be created.

The date of birth (dob) is not required. However, if you don't have it then your transactions will trigger more compliance alerts, thus your payments will be processed much slower (hours or days instead of mere seconds). Also, we charge you more fees for manual labour you cause.

Update sender

Delete sender

Required fields

Different countries support different account types, transfer mechanisms, payment delivery methods.

Understand what minimal data you need to have to successfully transfer a payment

List all the available payment delivery methods

The response above means that if you want to send euros to Austria (AT) then you'd need a BIC (aka SWIFT) code and an IBAN.

List some of the delivery methods

The response above means that to send euros to France (FR) you have to have ether of:

  • BIC and an account number, or

  • BIC and an IBAN.

Payments

Convert your balance and send it as one FX payment instruction

Having a recipient ID you can now send money.

Query payments

Retrieving all your payments

Retrieving some of your payments

Retrieving a single payment

Send funds

To make a payment from AUD to another currency you need to execute the createPayment mutation as below.

Note that you must have enough AUD balance to make an outbound AUD payment.

Recipient - recipientId

We are legally obliged to collect the actual sender and beneficiary details. Please do not send us intermediate organisation details such as exchanges, banks, gateways, etc.

If sending from yourself, there's an option to use your company's Flash account details as sender by default. Please consider the examples below.

Sender - senderId or subClientId , or neither

To use subClientId as the sender for your payments, please execute the createPayment mutation as below.

If your company is the ultimate sender for an FX payment, you can skip both the senderId and subClientId. In this situation, we will use your company’s Flash account as the sender for the payment. Please note that a new sender record will not be created in this case.

Please execute the following createPayment mutation to use your company's Flash account details as sender.

We recommend against continuous polling for payment status changes. Instead, please use callbackUri.

Please note that toAmount (or fromAmount) and other fluctuating payment properties can change during payment execution.

Security note

Auto receive funds

Automatically receive and convert funds from other countries and currencies

Some customers can automatically receive funds from overseas. Meaning, if we detect an overseas deposit to the Flash Payments controlled bank account(s) then we can automatically create an inbound payment, convert funds, and top up your Flash Payments balance with AUD.

Note! In case of sub-clients, they must have full real world address. Don't skip any fields while creating those in our system. Also, you must send money from the bank account on your (or your sub-client's) name. Also, sometimes but not always, the payment must have the payment reference we told you. See below.

Here is how it looks step by step.

  1. We would need to enable the foreign currency auto-receiving feature for you.

    • The account number and payment reference depends on the currency and country you wish to deposit to. E.g. the EUR currency account is usually a British IBAN (starts with "GB").

  2. The Flash Payments would detect the account funding event and automatically create a EUR->AUD payment for you.

  3. You would receive at least two webhook notifications - payment_created and payment_complete.

  4. Your Flash Payments AUD balance would increase accordingly.

To find out the Funding Accounts via API please use the fundingAccounts query.

You should deposit your foreign currency to:

Institutions

CRUD queries for Institutions

Instructing Institution

Institution entity is a piece of information about the party who instructed you to make the withdrawal. This data is important for compliance within Australia. This is not the sender. If there is no other institution who has instructed this withdrawal, leave this blank and your own details will be used for compliance and auditing purposes.

Creating institutions

  • via Flash Connect (you can copy an ID of an existing Institution).

  • via API by invoking createInstitution mutation.

  • by providing instructingInstitution object into createWithdrawal mutation.

Please avoid creating multiple Institutions for the same organisation because they are used for compliance reporting and subject to review.

Before creating or updating an institution we will try to find an existing one by:

  • By instructingInstitution.externalId

  • By instructingInstitution.businessNumber AND instructingInstitution.address.country

  • By instructingInstitution.legalName AND instructingInstitution.address.country

Creating institution example

Authentication

Get your access token

Before doing any other API calls you have to obtain an auth token. It's a standard JWT token carrying the following payload:

The token lifetime is 4 hours at this time. We might change this value in the future.

Warning! You can't login more than once per second. That's a DOS attack prevention feature.

To be more future-proof it is recommended to parse the token payload and compare current time to the token's expiration time. JavaScript code:

This login mutation is a subject to change in the future.

Getting a token

  1. Find there the login mutation. Execute it to obtain your access token. For example: mutation { login(input: {email: "YOUR_EMAIL" password: "YOUR_PWD"}) {token message} }

  2. Click the "HTTP HEADERS" on the bottom and add this: {"authorization": "Bearer YOUR_TOKEN"}. Replace the YOUR_TOKEN with the token you just got.

  3. Execute any other queries.

Here is an example of the login query.

Statement

Understand every movement of your primary balance

The dates must be any ISO 8601 formatted dates.

The response dates are aways UTC. Timezones are always taken into account.

Balance

Query your account balances

Paste this query to the GraphQL Playground

The cleared is the Primary balance you see on the Flash Connect website.

The pending balance is typically not shown on the Flash Connect interface because it's rather short lived. If your Pending balance is not 0 then you can see it right next to the Primary balance.

If you omit the currencies input argument then the query would return all the currency balances you have. Contact us to enable more than just the default AUD currency.

Top up your UAT account balance

If you need to increase your UAT account balance please sign in to the Flash Connect website, open Deposits page, and click Send Test Deposit.

If receiving from yourself then please provide your own details. See the DOCS in for other sender details options.

You can all or some of your payments. If you are an organisation with multiple users then you have access to all their payments.

You can . But before you need to:

have a recipient ID (see to query your address book); otherwise

understand the supported delivery methods using the query and

You should and send us their ID.

If it is an intermediate, please see instead.

Please always send us the ultimate sender and recipient. If sending to yourself, please provide your own details. See the schema in for other recipient details options.

In the above createPayment example, you had to and use senderId as an input. Alternatively, if your account is configured to make FX payments on behalf of your , you may provide us with the sub-client ID, and the FX payment created will be linked to that sub-client. In this case, the subClientId will be used as the sender and will be reported to the government.

Callback (aka ) URI

The optional callbackUri will be invoked several times during the processing of a payment. These callbacks will usually occur soon (within several seconds) after the initial create payment call - but may be delayed in some cases. The example JSON payloads can be found on the .

The callback (aka ) endpoint URI can be invoked by anyone in the internet. Thus opening up a potential attack vector. See page to secure your data properly.

You, or your , would have a special bank account in, say, SEPA zone. Find the details below.

You, or your , would deposit money to it. Make sure to submit the exact payment reference we told you! Otherwise, your funds will be returned.

To find which foreign currency bank account you would need to deposit to, please go to the and find there the list of inbound currencies we support and the corresponding bank account numbers. It's called the "Funding Accounts" throughout the user interface.

Tip. You can simulate and test an international inbound payment with the FlashConnect tool in the UAT environment. Just go to the FX Payments page and click "SEND TEST INBOUND PAYMENT". Additionally, you can test an international inbound payment sent by your in the UAT. Just go to the Sub-clients page, find the sub-client, and click "SEND TEST INBOUND PAYMENT".

Your should deposit their foreign currency to:

Tip: Use this handy website to parse the token contents:

After we enable you, go to the playground, click "DOCS" on the right to explore the possibilities.

If using then click the "HTTP HEADERS" on the bottom left and paste there the following (replace the YOUR_TOKEN with the value you have just received form the above mutation):

This query returns the same data as the Download CSV button on the Account Statement page of the .

{
  sender(id: "59f2733f2519e236edab0efe") {
    email
    firstName
    lastName
    companyName
    address {
      country
    }
  }
}
{
  "data": {
    "sender": {
      "email": "john@example.com",
      "firstName": "John",
      "lastName": "Smith",
      "companyName": null,
      "address": {
        "country": "GB"
      }
    }
  }
}
{
  senders(input: { email: "john@example.com" }) {
    email
    firstName
    lastName
    companyName
    address {
      country
    }
    # there are other properties
  }
}
{
  "data": {
    "senders": [
      {
        "email": "john@example.com",
        "firstName": "John",
        "lastName": "Smith",
        "companyName": null,
        "address": {
          "country": "GB"
        }
      },
      {
        "email": "john@example.com",
        "firstName": null,
        "lastName": null,
        "companyName": "Acme Inc",
        "address": {
          "country": "US"
        }
      },
    ]
  }
}
mutation {
  createSender(
    input: {
      firstName: "Malcolm"
      lastName: "Jez"
      dob: "2000-01-01"
      email: "malcolm@example.com"
      mobile: "+61 4123456789"
      address: {
        street: "1 Test St"
        suburb: "London"
        state: "TST"
        country: GB
        postcode: "2000"
      }
      idDoc: {
        type: passport
        docNumber: "GB1234321"
        issuer: "His Majesty’s Passport Office (HMPO)"
        issueDate: "1990-01-01"
        expiryDate: "2045-01-01"
        country: GB
      }
    }
  ) {
    success
    code
    message
    sender {
      id
      nickName
      # there are many other properties
    }
  }
}
mutation {
  createSender(
    input: {
      companyName: "Acme Pte Ltd"
      businessNumber: "12345678912"
      email: "acme@example.com"
      mobile: "+61 4123456789"
      address: {
        street: "1 Test St"
        suburb: "London"
        state: "TST"
        country: GB
        postcode: "2000"
      }
      idDoc: {
        type: certificateOfRegistration
        docNumber: "GB-REG-987654321"
        issuer: "Companies House"
        issueDate: "1990-01-01"
        expiryDate: "2100-01-01"
        country: GB
      }
    }
  ) {
    success
    code
    message
    sender {
      id
      nickName
      # there are many other properties
    }
  }
}
mutation {
  updateSender(
    id: "5ca18312ace1db0af5784826"
    input: {
      firstName: "Malcolm"
      lastName: "Jez The Seconds"
      dob: "2000-01-01"
      email: "malcolm@example.com"
      mobile: "+61 4123456789"
      address: {
        street: "1 Test St"
        suburb: "London"
        state: "TST"
        country: GB
        postcode: "2001"
      }
      idDoc: {
        type: passport
        docNumber: "GB1234321"
        issuer: "His Majesty’s Passport Office (HMPO)"
        issueDate: "1990-01-01"
        expiryDate: "2045-01-01"
        country: GB
      }
    }
  ) {
    success
    code
    message
    sender {
      id
      # there are many other properties
    }
  }
}
{
  "data": {
    "updateSender": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sender updated",
      "sender": {
        "id": "5ca18312ace1db0af5784826"
      }
    }
  }
}
mutation {
  deleteSender(id: "5ca18d25ace1db0af5784893") {
    success code message
  }
}
{
  "data": {
    "deleteSender": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sender deleted"
    }
  }
}
{
  availableDeliveryMethods {
    country
    currency
    method
    requiredFields
  }
}
{
  "data": {
    "availableDeliveryMethods": [
      {
        "country": "AE",
        "currency": "AED",
        "method": "ACC_NO",
        "requiredFields": [
          "bic",
          "accountNo"
        ]
      },
      {
        "country": "AT",
        "currency": "EUR",
        "method": "IBAN",
        "requiredFields": [
          "bic",
          "iban"
        ]
      },
...
{
  availableDeliveryMethods(input: { country: FR, currency: EUR }) {
    country
    currency
    method
    requiredFields
  }
}
{
  "data": {
    "availableDeliveryMethods": [
      {
        "country": "FR",
        "currency": "EUR",
        "method": "ACC_NO",
        "requiredFields": [
          "bic",
          "accountNo"
        ]
      },
      {
        "country": "FR",
        "currency": "EUR",
        "method": "IBAN",
        "requiredFields": [
          "bic",
          "iban"
        ]
      }
    ]
  }
}
{
  payments {
    id
    fromCurrency
    toCurrency
    # there are many other properties
  }
}
{
  "data": {
    "payments": [
      {
        "id": "5b04c62ec0bf606bf216ae21",
        "fromCurrency": "AUD",
        "toCurrency": "EUR"
      },
      {
        "id": "5b04c6bfc0bf606bf216af06",
        "fromCurrency": "AUD",
        "toCurrency": "USD"
      },
      {
        "id": "5b04c8e3c0bf606bf216b026",
        "fromCurrency": "EUR",
        "toCurrency": "AUD"
      }
    ]
  }
}
{
  # there are more query parameters available, see the API schema
  payments(input: { statuses: CLOSED, toCurrencies: [EUR USD] }) {
    id
    fromCurrency
    toCurrency
    # there are many other properties
  }
}
{
  "data": {
    "payments": [
      {
        "id": "5b04c62ec0bf606bf216ae21",
        "fromCurrency": "AUD",
        "toCurrency": "EUR"
      },
      {
        "id": "5b04c6bfc0bf606bf216af06",
        "fromCurrency": "AUD",
        "toCurrency": "USD"
      }
    ]
  }
}
{
  # there are more query parameters available, see the API schema
  payment(id: "5b04c62ec0bf606bf216ae21") {
    status
    createdAt
    size
    # there are many other properties
  }
}
{
  "data": {
    "payment": {
      "status": "CLOSED",
      "createdAt": "2018-08-13T05:45:28.698Z",
      "size": 1000
    }
  }
}
mutation {
  createPayment(
    input: {
      fromCurrency: AUD
      toCurrency: USD
      size: 1000
      currency: AUD
      reason: BUSINESS
      sourceOfFunds: BUSINESS_FUNDS
      externalReference: "my ref 221b"
      senderId: "6092360ae40e2cfb52f85be1"
      recipientId: "5ba89a6b35a2b327b81ffc3b"
      externalId: "12344321"
      idempotencyKey: "12344321"
    }
  ) {
    success
    code
    message
    payment {
      id
      status
      size
    }
  }
}
{
  "data": {
    "createPayment": {
      "success": true,
      "code": "SUCCESS",
      "message": "Scheduled for immediate execution",
      "payment": {
        "id": "60711af8c078ba061f623531",
        "status": "OPEN",
        "size": 1000
      }
    }
  }
}
mutation {
  createPayment(
    input: {
      fromCurrency: AUD
      toCurrency: USD
      size: 1000
      currency: AUD
      reason: BUSINESS
      sourceOfFunds: BUSINESS_FUNDS
      externalReference: "my ref 221c"
      subClientId: "6092360bf40f2dgc52f85cf1"
      recipientId: "5ba89a6b35a2b327b81ffc3b"
      externalId: "12344321"
      idempotencyKey: "12344321"
    }
  ) {
    success
    code
    message
    payment {
      id
      status
      size
    }
  }
}
{
  "data": {
    "createPayment": {
      "success": true,
      "code": "SUCCESS",
      "message": "Scheduled for immediate execution",
      "payment": {
        "id": "60711bg8d078cb061g623531",
        "status": "OPEN",
        "size": 1000
      }
    }
  }
}
mutation {
  createPayment(
    input: {
      fromCurrency: AUD
      toCurrency: EUR
      size: 1000
      currency: AUD
      reason: BUSINESS
      sourceOfFunds: BUSINESS_FUNDS
      externalReference: "my ref 234"
      recipientId: "67d7d75ab8db0fdfccfb16b2"
      externalId: "0123443210"
      idempotencyKey: "0000012344321000"
    }
  ) {
    success
    code
    message
    payment {
      id
      status
      size
      sender {
         firstName
         lastName
         companyName
      }
    }
  }
}
{
  "data": {
    "createPayment": {
      "success": true,
      "code": "SUCCESS",
      "message": "Scheduled for immediate execution",
      "payment": {
        "id": "67d8e98caaa23286e1a1fd00",
        "status": "OPEN",
        "size": 1000,
        "sender": {
          "firstName": "John",
          "lastName": "Smith",
          "companyName": "Smith Consulting Pty Ltd"
        }
      }
    }
  }
}
{
  fundingAccounts(input: { currencies: [EUR, USD, HKD, CNY] }) {
    iban
    accountNo
    accountName
    accountAddress
    bic
    currency
    externalReference
  }
}
{
  "data": {
    "fundingAccounts": [
      {
        "iban": "GB91 BARC 2006 0565 4685 66",
        "accountNo": "65468566",
        "bic": "BARCGB22",
        "currency": "USD",
        "externalReference": "191127-99999"
      },
      {
        "iban": "GB05 BARC 2006 0574 7412 77",
        "accountNo": "74741277",
        "bic": "BARCGB22",
        "currency": "EUR",
        "externalReference": "191127-99999"
      },
      {
        "iban": null,
        "accountNo": "87135588",
        "bic": "BARCGB22",
        "currency": "CNY",
        "externalReference": "191127-99999"
      },
      {
        "iban": "GB87 BARC 2006 0546 9946 00",
        "accountNo": "46994600",
        "bic": "BARCGB22",
        "currency": "HKD",
        "externalReference": "191127-99999"
      }
    ]
  }
}
{
  subClients(input: { externalId: "991188227733" }) {
    id
    externalId
    fundingAccounts(input: { currencies: [EUR, USD, CNY] }) {
      iban
      accountNo
      accountName
      accountAddress
      bic
      currency
      externalReference
    }
  }
}
{
  "data": {
    "subClients": [
      {
        "id": "60a1e9e76eaedbf66964a323",
        "externalId": "991188227733",
        "fundingAccounts": [
          {
            "iban": "GB91 BARC 2006 0565 4685 66",
            "accountNo": "65468566",
            "bic": "BARCGB22",
            "currency": "USD",
            "externalReference": "210616-99999"
          },
          {
            "iban": "GB05 BARC 2006 0574 7412 77",
            "accountNo": "74741277",
            "bic": "BARCGB22",
            "currency": "EUR",
            "externalReference": "210616-99999"
          },
          {
            "iban": null,
            "accountNo": "87135588",
            "bic": "BARCGB22",
            "currency": "CNY",
            "externalReference": "210616-99999"
          },
        ]
      }
    ]
  }
}
mutation {
  createInstitution(
    input: {
      legalName: "Intermediate Institution Ltd"
      businessNumber: "A39477669937"
      address: {
        postcode: "2000"
        street: "203 Business Street"
        country: AU
        state: "NSW"
        suburb: "Sydney"
      }
    }
  ) {
    success
    code
    message
    institution {
      id
    }
  }
}
{
  "data": {
    "createInstitution": {
      "success": true,
      "code": "INSTITUTION_CREATED",
      "message": "Institution created",
      "institution": {
        "id": "65570da4f176682c5e412552"
      }
    }
  }
}
{
  ...

  "iat": 1620967717,
  "exp": 1621054117
}
const seconds = JSON.parse(Buffer.from(token.split(".")[1], "base64url")).exp;
if (Date.now() >= seconds*1000) {
  // get new token
}
mutation {
  login(input: { email: "you@example.com", password: "12345678" }) {
    token
    message
    code
    success
  }
}
{
  "data": {
    "login": {
      "token": "YOUR_TOKEN",
      "message": "OK",
      "code": "SUCCESS",
      "success": true
    }
  }
}
{
  "authorization": "Bearer YOUR_TOKEN"
}
{
  statement(input: { fromDate: "2023-08-28T00:00:00+03:00" }) {
    success
    code
    message
    fromDate
    toDate
    rows {
      debit
      credit
      # and many other fields
    }
  }
}
{
  "data": {
    "statement": [
      {
        "success": true,
        "code": "GENERATED",
        "message": "Statement generated",
        "fromDate": "2023-08-27T21:00:00Z",
        "toDate": "2023-08-28T21:00:00Z",
        "rows": {
          [
            {
              "debit": 123.45,
              "credit": 0
            }
          ]
        }
      }
    ]
  }
}
{
  balances(currencies: AUD) {
    currency
    cleared
    pending
  }
}
{
  "data": {
    "balances": [
      {
        "currency": "AUD",
        "cleared": 3860,
        "pending": 0
      }
    ]
  }
}

Deposit statuses

Deposit processing statuses

As soon as we see a deposit in a Flash Payments controlled Virtual Account Number (VAN) we create a deposit.

INITIALISED->REVIEWING→CONFIRMED

If you choose to reject that deposit it goes through refunding statuses:

INITIALISED->REVIEWING→CONFIRMED→REFUNDING→REFUNDED

The REVIEWING is an optional manual action by Flash Payments Compliance team. Occasionally we pick some transactions for extended AML/CT review. Most transactions do not ever get into the REVIEWING status.

If Flash Payments Compliance choose to reject that deposit it goes through following statuses:

INITIALISED→REVIEWING→REFUNDING→REFUNDED

Query withdrawals

Retrieving all your withdrawals

{
  withdrawals {
    id
    recipient { firstName lastName }
    # there are many other properties
  }
}
{
  "data": {
    "withdrawals": [
      {
        "id": "5b04c62ec0bf606bf216ae21",
        "recipient": {
          "firstName": "John"
          "lastName": "Smith"
        }
      },
      {
        "id": "5b04c6bfc0bf606bf216af06",
        "recipient": {
          "firstName": "John"
          "lastName": "Smith"
        }
      },
      {
        "id": "5b04c8e3c0bf606bf216b026",
        "recipient": {
          "firstName": "John"
          "lastName": "Smith"
        }
      }
    ]
  }
}

Retrieving some of your withdrawals

{
  # there are more query parameters available, see the API schema
  withdrawals(input: { statuses: CONFIRMED, maxCreatedAt: "2020-01-29" }) {
    id
    createdAt
    # there are many other properties
  }
}
{
  "data": {
    "withdrawals": [
      {
        "id": "5b04c62ec0bf606bf216ae21",
        "createdAt": "2020-01-17T07:21:20.247Z"
      },
      {
        "id": "5b04c6bfc0bf606bf216af06",
        "createdAt": "2018-08-13T05:45:28.698Z"
      }
    ]
  }
}

Retrieving a single withdrawal

{
  # there are more query parameters available, see the API schema
  withdrawal(id: "5b04c62ec0bf606bf216ae21") {
    status
    createdAt
    amount
    # there are many other properties
  }
}
{
  "data": {
    "withdrawal": {
      "status": "CONFIRMED",
      "createdAt": "2020-01-17T07:21:20.247Z",
      "amount": 1000
    }
  }
}

Playground
retrieve
create payments
Recipients
Playground
pre-create a sender
sub-clients
Webhook
webhook
Webhooks
Sub-client
Sub-client
FlashConnect
sub-client
sub-clients
jwt.io
https://api.uat.flash-payments.com.au/
GraphQL Playground
Flash Connect
availableDeliveryMethods
create a new recipient
pre-create recipients
Instiutions

Deposits

Explains how to accept deposits programmatically

After fully registering with us, you get a BSB and a dedicated Virtual Account Number (VAN).

Warning: The account number can only process local transfers, no SWIFT/RTGS.

Every deposit to this account would increase your Flash Payments balance.

The deposit data includes the payment reference (we call it externalReference in this API).

By default, only yourself is allowed to deposit. However, we can enable third party deposits feature for your account. This, effectively, makes your account number a local collection account.

Withdraw funds

Send money from your Flash Payments balances to Australian bank accounts or internationally per your approved use case.

To make a withdrawal, you need to execute the createWithdrawal mutation as below.

mutation {
  createWithdrawal(
    input: {
      amount: 1000
      currency: AUD
      externalReference: "invoice #123"
      recipientId: "5ba89a6b35a2b327b81ffc3b"
      senderId: "5eaf71a1cb328c56f94f9375"
      externalId: "12344321"
      idempotencyKey: "12344321"
    }
  ) {
    success
    code
    message
    withdrawal {
      id
      status
      amount
      currency
    }
  }
}
{
  "data": {
    "createWithdrawal": {
      "success": true,
      "code": "OK",
      "message": "Scheduled for immediate execution",
      "withdrawal": {
        "id": "60711af8c078ba061f623531",
        "status": "PENDING",
        "amount": 1000,
        "currency": AUD
      }
    }
  }
}

Payment reference - externalReference

Arbitrary text, which will be seen in the ultimate recipient's bank statement. E.g. "invoice #123". Will be eventually truncated to 18 ASCII chars if delivered via Australia's old (DE, Direct Entry) payment system. However, if you choose to use the real-time NPP network, then the maximum length is 280 chars.

Recipient - recipientId

Sender - senderId or subClientId , or neither

To use subClientId as the sender for your withdrawal, please execute the createWithdrawal mutation as below.

mutation {
  createWithdrawal(
    input: {
      amount: 1000
      currency: AUD
      externalReference: "invoice #1234"
      recipientId: "5ba89a6b35a2b327b81ffc3b"
      subClientId: "3fbj71b1dc328d56g94g9375"
      externalId: "12344321"
      idempotencyKey: "12344321"
    }
  ) {
    success
    code
    message
    withdrawal {
      id
      status
      amount
      currency
    }
  }
}
 {
  "data": {
    "createWithdrawal": {
      "success": true,
      "code": "OK",
      "message": "Scheduled for immediate execution",
      "withdrawal": {
        "id": "60711af8c078ba061f623531",
        "status": "PENDING",
        "amount": 1000,
        "currency: AUD
      }
    }
  }
}

We are legally obliged to collect the actual sender and beneficiary details. Please do not send us intermediate organisation details such as exchanges, banks, gateways, etc.

If sending from yourself, there's an option to use your company's Flash account details as sender by default. Please consider the example below.

If your company is the ultimate sender for a withdrawal, you can skip both the senderId and subClientId. In this situation, we will use your company’s Flash account as the sender for the transaction. Please note that a new sender record will not be created in this case.

Please execute the following createWithdrawal mutation to use your company's Flash account details as sender.

mutation {
  createWithdrawal(
    input: {
      amount: 500
      currency: AUD
      externalReference: "invoice #123"
      recipientId: "661e293b14a0e678c37fa327"
      externalId: "1234567890"
      idempotencyKey: "0987654321"
    }
  ) {
    success
    code
    message
    withdrawal {
      id
      status
      amount
      currency
      sender {
      firstName
      lastName
      companyName
      }
    }
  }
}
{
  "data": {
    "createWithdrawal": {
      "success": true,
      "code": "SUCCESS",
      "message": "Withdrawal was created",
      "withdrawal": {
        "id": "67cb69f2ee6c254315bb1c3d",
        "status": "INITIALISED",
        "amount": 500,
        "currency": "AUD",
        "sender": {
          "firstName": "John",
          "lastName": "Smith",
          "companyName": "Smith Consulting Pty Ltd"
      }
    }
  }
}

Instructing Institutions

An organisation that instructed you to make a withdrawal. This data is mandatory if you submit this withdrawal on behalf of another financial institution.

Using existing institutions instructingInstitutionId

This optional field refers to an existing Institution that was created earlier in the Flash Connect interface or via this API.

Create institutions on the fly using the instructingInstitution field

  • By instructingInstitution.externalId if present.

  • By instructingInstitution.businessNumber AND instructingInstitution.address.country

We recommend against continuous polling for withdrawal status changes. Instead, please use callbackUri.

Security note

Payment statuses

The GraphQL schema defines statuses like this:

enum PaymentStatus {
  INITIALISING
  OPEN
  CLOSED
  FAILED
  CANCELLED
}

The current status of your payment.

  • INITIALISING - a draft payment. It may or may not have all required information to be executed.

  • OPEN - the payment is in progress.

  • CLOSED - means successfully delivered.

  • FAILED - an error has occurred with this payment.

  • CANCELLED - the payment has not completed and has been cancelled.

    • Usually done by Flash Payments operations team.

Important to understand that the Payment.history is a transfer logs and is not related to payment status at all. Sometimes the history may contain half a dozen entries, however your payment will go through only two steps: OPEN and CLOSED.

Withdrawal statuses

Withdrawal processing statuses

  1. You create a withdrawal. Your balance goes down by the withdrawal amount plus fee. INITIALISED

    1. We might manually review the transaction. INITIALISED-> REVIEWING

    2. If review goes well it will become pending. REVIEWING→ PENDING

    3. Otherwise it gets cancelled. REVIEWING→ CANCELLED

  2. The transaction is sent to the recipient bank for processing. INITIALISED → PENDING

  3. PENDING →

    • CONFIRMED - the recipient bank has the money now. Does not mean the beneficiary account number was credited though. Mostly FINAL status. Except when bank decides to return the funds, the withdrawal gets refunded (see step 4).

    • FAILED - NOT FINAL status. Depending on the processing error we have three scenarios now.

      • REFUNDED - see step 4 below.

      • CANCELLED - manual action. Your balance goes up by the amount, Flash Payments keeps the fee. FINAL status.

      • PENDING - rare case - retrying. Sometimes it might work. Go to item 3.

  4. The recipient bank decided to return this transaction back to Flash Payments. CONFIRMED → FAILED → REFUNDED - usual way - automatic refunding. Your balance goes up by the withdrawal amount, Flash Payments keeps the fee. FINAL status.

The REVIEWING is an optional manual action by Flash Payments Compliance team. Occasionally we pick some transactions for extended AML/CT review. Most transactions do not ever get into the REVIEWING status.

Most common status transitions

Happy path

INITIALISED→REVIEWING→PENDING→CONFIRMED

Unhappy paths

Recipient bank accepts the payout but then returns it:

INITIALISED→PENDING→CONFIRMED→FAILED→REFUNDED

Recipient bank rejects the payout:

INITIALISED→PENDING→FAILED→REFUNDED

Flash Payments Compliance team rejects the payout:

INITIALISED→REVIEWING→CANCELLED

Testing/simulating unhappy paths

Typically, you want to adapt your system to handle the following common withdrawal scenarios:

1. Too long in the REVIEWING status

If your withdrawal is in this status this means that we are doing a manual review of it. It happens occasionally when you trigger our monitoring rules. Also, this means that we have sent your Compliance Team (or else) an email message requesting more information. You must respond. In other words, if there is a delay - it's on you. Because Flash Payments delivers all your transactions in real-time 24/7.

As a matter of fact, we have an automated address cleansing/validation layer where sender and recipient addresses will be checked again once the transaction is created. Our algorithm takes all address fields together, tries to make sense of them and verifies if such address actually exists. If the automated verification fails, the transaction will be marked as REVIEWING and sent to our Compliance team for manual verification. This means that transactions will be delayed and this can be avoided if the accurate address information is provided.

You can simulate the behaviour. Your externalReference must include this text: HALT_AML. For example: "testing HALT_AML attempt 2". The withdrawal will get stuck in REVIEWING forever.

2. Fails AML and gets cancelled

We checked the data you sent us for withdrawal. We didn't like it. So we cancel it immediately.

You can simulate the behaviour. Your externalReference must include this text: FAIL_AML. For example: "testing FAIL_AML attempt 4". The withdrawal will be cancelled next moment after you submit it.

3. Recipient bank rejects the money

An often scenario in Australian domestic payments system is when a local transaction went seemingly fine. However, few days later a recipient bank decides to return the money. There are multiple reasons for that. For example: account number does not exist, account was closed, account is of a wrong currency, etc.

You can simulate the behaviour. Your externalReference must include this text: FAIL_ACC. For example: "testing FAIL_ACC attempt 8". The withdrawal will be completed, and next moment failed and refunded.

Withdrawals

Disburse your money to Australian bank account(s)

If you are a fully verified customer you can payout to any bank account number in Australia. You'd need to:

Having a recipient ID you can now withdraw money.

Disable, Activate and Update sub-clients

You can disable and activate sub-clients. Deposits sent to a disabled sub-client will no longer be booked against your balance.

Disabling a sub-client

Activating a sub-client

Updating sub-clients

At this point, you can update the externalId property only because each sub-client has a set of linked domestic and international Virtual Account Numbers to send and receive funds.

Query deposits

Query all deposits

Query deposit by ID

Sub-clients

Generate Virtual Account Numbers for your clients for collection

The sub-client (aka merchant) feature allows you to create client accounts for deposit collection purposes. These virtual accounts can be issued to individuals, companies, or other organisations.

Note: This feature is OFF by default. Contact us if you want it.

Each sub-client will receive a dedicated BSB and virtual account number that you or your clients can use to accept and withdraw domestic AUD transfers within Australia.

Warning: This local account number can only process local transfers, no SWIFT/RTGS.

The account name is your sub-client's name. For companies - it's their tradingAsName or legalName. For individuals - it's their fullName (firstName + middleName + lastName).

If your Flash account has a multi-currency feature enabled, each of your sub-clients will also have access to virtual accounts in the selected currencies for which you hold balances.

Create sub-clients

There are two types of sub-clients: company and individual.

For every company registered as a sub-client, there must be one contact person for individual data submitted. Ideally, the contact person should be a company director or have a similar role. Therefore, if you are creating a sub-client of the company type, we require you to provide extra details:

  • legalName - company legal name

  • businessNumber - company business number (e.g. ABN in Australia)

If the above fields are not set, the sub-client will be created as individual type.

This action creates a real account number. If you ever submit fake, unreal, testing, or incorrect data - you will be immediately blocked from Flash Payments services.

Please add all possible precautions, processes, staff training, warning messages, and validation checks to your system(s) before creating a sub-client.

Please follow our latest requirements for the proper sub-client data submission:

  1. Provide properfirstNameandlastName

  2. Provide propermobilenumber

  3. Provide proper dob : the person must be under 65 years of age

  4. Provide proper residential address Including unit and street number. The sub-client address should correspond to your approved use case from the contract. By default, you're only allowed to have local Australian sub-accounts. Any non-Australian entities will undergo extended due diligence based on their location and industry relevance for Flash Payments.

  5. Provide properidDoc (type, docNumber, issuer (optional), issueDate (optional), expiryDate (optional), and country ) based on the sub-client contact person's address. For Australian residents, either a driver’s license or a passport is accepted. For non-Australian residents, only a passport is accepted as a document type.

The above personal data submission requirements should be as equally followed for the company contact person, with the exception of address property, which can be a company address in this case.

To create a sub-client, you need to execute the createSubClient mutation as below. You can find the description of each field in the GraphQL API schema.

Refund deposits

Return the funds back to the original sender

Refund deposit by ID

Query sub-clients

Available queries

Query for a single sub-client

Query for multiple sub-clients

Query for multiple sub-clients with filters

You can receive notifications via about every deposit.

We can also enable the feature. It allows you to programmatically create client accounts with dedicated BSB and account number for transactional purposes. You can give these bank account details to your clients to accept deposits. Once funds arrive, we will increase your account balance, and you will see a deposit with sub-client information linked to it.

To browse your deposits, you can use our FlashConnect tool:

Tip. You can simulate and test a deposit with the FlashConnect tool in the UAT environment. Just go to the Deposits page and click "SEND TEST DEPOSIT". Additionally, you can test a deposit sent by your in the UAT. Just go to the Sub-clients page, find the sub-client, and click "SEND TEST DEPOSIT".

You must have enough in your account for the chosen currency to make a withdrawal.

You should and provide us with their ID. The recipient's Australian account must be either BSB or PAYID (coming soon).

In the above createWithdrawal example, you had to first and use senderId as an input. Alternatively, if your account is configured to disburse funds on behalf of your , you may provide us with the sub-client ID, and the withdrawal created will be linked to that sub-client. In this case, the subClientId will be used as the sender and will be reported to the government.

If it is an intermediate, please see instead.

Please always send us the ultimate sender and recipient. If sending to yourself, please provide your own details. See the schema in for other recipient details options.

For more information please see .

Optional field that allows you to provide details without pre-creating one. Once passed, Flash Payments will create the Institution for you. Before creating an institution, we will try to find an existing one:

Callback (aka ) URI

The optional callbackUri will be invoked several times during the processing of a withdrawal. These callbacks will usually occur soon (within several seconds) after the initial create withdrawal call - but may be delayed in some cases. The example JSON payloads can be found on the .

The callback (aka ) endpoint URI can be invoked by anyone on the internet. Thus opening up a potential attack vector. See page to secure your data properly.

Typically never happens via API. Can be created via the under certain circumstances.

Please always provide accurate and information, including the full address, to prevent delays associated with manual compliance reviews.

You can all or some of your withdrawals.

You can . By default you can withdraw only to your personal Virtual Account Number (VAN).

have a recipient ID (see to query your address book); otherwise

understand the supported delivery methods using the query and

All sent to your sub-client Virtual Account Numbers (VANs) are booked on your (master-client's) corresponding account balances. Sub-clients can't have their own balances.

You can and on behalf of your sub-clients by providing the sub-client ID when you create withdrawals or payments. This sub-client record will then be used as the sender, linked to the transaction, and reported to the government.

Notifications via will provide important sub-client information as well.

Sometimes, we ask our partners to provide “instructing institution” information, but only if you are creating this VAN on behalf of another financial institution. More about institutions . You may provide the ID of the already created institution via the field instructingInstitutionId or as a full object via the instructingInstitution field.

Webhooks
sub-client
https://connect.uat.flash-payments.com.au/
sub-client
balance
Playground
Institutions
Institution
Webhook
webhook
Webhooks
Flash Payments app
sender
recipient
pre-create recipients
sub-clients
pre-create a sender
Instiutions
mutation {
  disableSubClient(id: "606128f24bf29139b2cf74ef") {
    success
    code
    message
    subClient {
      id
      status
    }
  }
}
{
  "data": {
    "disableSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully disabled",
      "subClient": {
        "id": "606128f24bf29139b2cf74ef",
        "status": "DISABLED"
      }
    }
  }
}
mutation {
  activateSubClient(id: "606128f24bf29139b2cf74ef") {
    success
    code
    message
    subClient {
      id
      status
    }
  }
}
{
  "data": {
    "activateSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully activated",
      "subClient": {
        "id": "606128f24bf29139b2cf74ef",
        "status": "ACTIVE"
      }
    }
  }
}
mutation {
  updateSubClient(
     id: "660fef8e1f3b5452bd6945ec"
     input: {
      externalId: "my_system_id_29f-ae0978b00d09e"
    }
  ) {
    success
    code
    message
    subClient {
      id
      status
      externalId
    }
  }
}
{
  "data": {
    "updateSubClient": {
      "success": true,
      "code": "SUCCESS",
      "message": "Sub-client was successfully updated",
      "subClient": {
        "id": "660fef8e1f3b5452bd6945ec",
        "status": "ACTIVE",
        "externalId": "my_system_id_29f-ae0978b00d09e"
      }
    }
  }
}
{
  deposits {
    id
    amount
    currency
    status
    statusMessage
    externalId
    externalReference
    subClient {
      id
      fullName
      status
      clientType
    }
    createdAt
    # more fields available, see API schema
  }
}
{
  "data": {
    "deposits": [
      {
        "id": "6053d4e0e3bc655e0598a742",
        "amount": 2000,
        "currency": "AUD",
        "status": "CONFIRMED",
        "statusMessage": "Transaction Confirmed",
        "externalId": "PR.1vcl",
        "externalReference": "FX1111",
        "subClient": null,
        "createdAt": "2021-03-18T22:32:01.010Z"
      },
      {
        "id": "6053d3319588389e1443587e",
        "amount": 40,
        "currency": "AUD",
        "status": "CONFIRMED",
        "statusMessage": "Transaction Confirmed",
        "externalId": "PR.1vci",
        "externalReference": "FX2121",
        "subClient": {
          "id": "5fb314cb9224595df522db61",
          "fullName": "John Doe",
          "status": "ACTIVE",
          "clientType": "INDIVIDUAL"
        },
        "createdAt": "2021-03-18T22:24:49.096Z"
      },
    ]
  }
}
{
  deposit(id: "6053d4e0e3bc655e0598a742") {
    id
    amount
    currency
    status
    statusMessage
    externalId
    externalReference
    createdAt
    # more fields available, see API schema
  }
}
{
  "data": {
    "deposit": {
      "id": "6053d4e0e3bc655e0598a742",
      "amount": 2000,
      "currency": "AUD",
      "status": "CONFIRMED",
      "statusMessage": "Transaction Confirmed",
      "externalId": "PR.1vcl",
      "externalReference": "KX23249",
      "createdAt": "2021-03-18T22:32:01.010Z"
    }
  }
}
mutation {
  createSubClient(
    input: {
      legalName: "Chineese Tradings"
      businessNumber: "330782000329701"
      firstName: "John"
      lastName: "Smith"
      email: "john.smith@example.com"
      mobile: "+61422832849"
      dob: "1979-05-12"
      address: {
        building: "25"
        street: "Xihu Road, Yuexiu District"
        suburb: "Guangzhou City"
        state: "Guangdong Province"
        postcode: "510030"
        country: CN
      }
      idDoc: {
        type: passport
        docNumber: "FF1948394"
        issuer: "Australian Passport Office (APO)"
        issueDate: "2000-01-01"
        expiryDate: "2045-01-01"
        country: AU
        
      }
      externalId: "991188227733"
    }
  ) {
    success
    code
    message
    subClient {
      id
      legalName
      businessNumber
      fullName
      clientType
      status
      primaryContact {
        firstName
        lastName
        email
        mobile
        dob
      }
      address {
        country
      }
      bsb
      accountNo
      externalId
      # more properties available, see API schema
    }
  }
}
{
  "data": {
    "createSubClient": {
      "success": true,
      "code": "SUBCLIENT_CREATED",
      "message": "Sub-client was successfully created",
      "subClient": {
        "id": "606d28675a2d931bc925fec2",
        "legalName": "Chineese Tradings",
        "businessNumber": "330782000329701",
        "fullName": "John Smith",
        "clientType": "INDIVIDUAL",
        "status": "ACTIVE",
        "primaryContact": {
          "firstName": "John",
          "lastName": "Smith",
          "email": "john.smith@example.com",
          "mobile": "+61 422 832 849",
          "dob": "1979-05-12"
        },
        "address": {
          "country": "CN"
        },
        "bsb": "802919",
        "accountNo": "1066419",
        "externalId": "991188227733"
      }
    }
  }
}
mutation {
  refundDeposit(
    id: "6053d4e0e3bc655e0598a742"
    input: { amount: 10, reason: "sent by mistake" }
  ) {
    success
    code
    message
  }
}
{
  "data": {
    "refundDeposit": {
      "success": true,
      "code": "REFUND_SENT",
      "message": "Refund initiated successfully"
    }
  }
}
{
  subClient(id: "606d28675a2d931bc925fec2") {
    id
    fullName
    legalName
    tradingAsName
    clientType
    status
    primaryContact {
      firstName
      middleName
      lastName
      email
      dob
      mobile
    }
    address {
      building
      street
      suburb
      state
      country
      postcode
    }
    postalAddress {
      building
      street
      suburb
      state
      country
      postcode
    }
    businessNumber
    bsb
    accountNo
  	externalId
    fundingAccounts(input: { currencies: [EUR, USD, HKD, CNY] }) {
      iban
      accountNo
      bic
      currency
      externalReference
    }
  }
}
{
  "data": {
    "subClient": {
      "id": "606d28675a2d931bc925fec2",
      "fullName": "ACME Corp",
      "legalName": "ACME Corp",
      "tradingAsName": null,
      "clientType": "COMPANY",
      "status": "ACTIVE",
      "primaryContact": {
        "firstName": "John",
        "middleName": null,
        "lastName": "Smith",
        "email": "john.smith@example.com",
        "dob": "1980-12-12",
        "mobile": "+61 422 832 849"
      },
      "address": {
        "building": "25",
        "street": "Moore St",
        "suburb": "Waterloo",
        "state": "NSW",
        "country": "AU",
        "postcode": "2017"
      },
      "postalAddress": {
        "building": "25",
        "street": "Moore St",
        "suburb": "Waterloo",
        "state": "NSW",
        "country": "AU",
        "postcode": "2017"
      },
      "businessNumber": "91383840265",
      "bsb": "802919",
      "accountNo": "1066419",
      "externalId": "991188227733"
    }
  }
}
{
  subClients {
    id
    fullName
    legalName
    clientType
    status
    businessNumber
    bsb
    accountNo
  	externalId
    # any other set of properties
  }
}
{
  "data": {
    "subClients": [
      {
        "id": "5fb314cb9224595df522db61",
        "fullName": "Richard Smith",
        "legalName": null,
        "clientType": "INDIVIDUAL",
        "status": "ACTIVE",
        "businessNumber": null,
        "bsb": "802919",
        "accountNo": "1963041",
        "externalId": null
      },
      {
        "id": "60612f00a4d7dd5c96e37676",
        "fullName": "ABC Capital",
        "legalName": "ABC Co",
        "clientType": "COMPANY",
        "status": "ACTIVE",
        "businessNumber": "839399923932",
        "bsb": "802919",
        "accountNo": "1914920",
        "externalId": null
      }
    ]
  }
}
{
  # more filters available, see SubClientQueryInput in API schema
  subClients(
    input: {
      clientType: INDIVIDUAL
      status: ACTIVE
      firstName: "John"
      lastName: "Smith"
      address: { country: AU }
    }
  ) {
    id
    fullName
    clientType
    status
    primaryContact {
      firstName
      lastName
    }
    address {
      country
    }
  }
}
{
  "data": {
    "subClients": [
      {
        "id": "5fb314cb9224595df522db61",
        "fullName": "John Smith",
        "clientType": "INDIVIDUAL",
        "status": "ACTIVE",
        "primaryContact": {
          "firstName": "John",
          "lastName": "Smith"
        },
        "address": {
          "country": "AU"
        }
      }
    ]
  }
}
retrieve
create withdrawals
Recipients
deposits
disburse funds
make FX payments
webhooks
here
availableDeliveryMethods
create a new recipient
Webhooks page
Webhooks page

Rejection codes

Transaction cancellation static codes and standard status messages

Below is the latest list of our supported rejection codes and standard status messages. Please note, while the rejection codes are unique, you might see the corresponding free text status messages customized by our Compliance team for more accuracy and clarity of the information exchange.

rejectCode
statusMessage

CANCELLATION_REQUESTED_BY_PARTICIPANT

The transaction is rejected upon request.

CANCELLATION_BY_RECIPIENT_FI

The transaction is rejected by recipient's financial institution.

COMPLIANCE_DECLINED

The transaction is rejected as it doesn't meet our compliance requirements.

FRAUD

The transaction is rejected due to a fraud.

SENDER_INADEQUATE_DATA

The transaction is rejected as the sender name details are missing or invalid.

RECIPIENT_INADEQUATE_DATA

The transaction is rejected as the beneficiary name details are missing or invalid.

SENDER_INVALID_ADDRESS

The transaction is rejected as the sender address details are invalid.

SENDER_INCOMPLETE_ADDRESS

The transaction is rejected as the sender address details are missing.

RECIPIENT_INVALID_ADDRESS

The transaction is rejected as the beneficiary address details are invalid.

RECIPIENT_INCOMPLETE_ADDRESS

The transaction is rejected as the beneficiary address details are missing.

RECIPIENT_ACCOUNT_CLOSED

The transaction is declined due to blocked or closed account.

RECIPIENT_INVALID_ACCOUNT_NUMBER

The transaction is declined due to missing or invalid account number.

RECIPIENT_INVALID_BANK_CODE

The transaction is declined due to invalid BSB number.

RECIPIENT_INVALID_ACCOUNT

The transaction is declined as the currency cannot be applied to the specified account.

DUPLICATE_TRANSACTION

The transaction is declined as duplicate.

DATA_ENQUIRY_TIME_ELAPSED

The transaction is rejected due to no response received within the specified time.

TECHNICAL_ISSUE

The transaction is declined due to technical issue.

Please note: status CANCELLED is a final status for any withdrawal. Please do not retry a withdrawal if it was rejected by our Compliance team or by a beneficiary financial institution.

Only those withdrawals rejected with codesTECHNICAL_ISSUE may be re-submitted as new transactions.

Ad hoc webhooks

How to secure your callback endpoints

We recommend API clients to generate and add ?signature=ASecretPerPaymentKey query to your callbackUri to make sure it's Flash Payments calling your webhook endpoint. For example:

https://my-webhooks.example.com/flash-payments?signature=oZaDlmfXbdXSKCnuWrvos2ImVBFX2Ru5

To avoid storing the signatures in a database we recommend generating them on the fly using a strong hash function or any kind of cryptography.

Example

This is just an example. Feel free to sign your URLs the way you want.

You would need to implement two functions.

  1. Function to generate "signature".

  2. Function to verify the "signature".

Generating signatures

Node.js pseudo code for creating transfers in Flash Payments API.

const secret = 'abcdefg';
function generateSignature(string) {
  return require('crypto')
    .createHmac('sha256', secret)
    .update(string)
    .digest('base64');
}

const signature = generateSignature(stringIdFromMyDatabase);
const callbackUri = 
  "https://my-webhooks.example.com/flashfx?signature=" + signature;
const externalId = stringIdFromMyDatabase;

// Use both callbackUri and externalId when creating transfers with Flash Payments API

The code above creates a callbackUri and externalId variables. Use both of them when creating a transfer in Flash Payments API.

Verifying signatures

Node.js pseudo code of the webhook endpoint HTTP request handler.

function myCallbackEndpointHandler(req, res) {
  const signature = req.query.signature;
  const stringIdFromMyDatabase = req.body.externalId;
  
  if (generateSignature(stringIdFromMyDatabase) !== signature) {
    console.error("Security warning! Webhook endpoint received bad data", req);
    res.sendStatus(500);
    return;
  }
  
  // proceed with the webhook processing
}

Regular webhooks

How to setup web hooks for your integration

Event notifications with webhooks

Flash Payments uses webhooks to notify your application when a transaction event happens in your account. This includes status update of your withdrawal, clearing of the incoming deposit, and more.

With webhooks, you can subscribe to the events of interest to trigger a subsequent action within your integration.

Building webhook endpoint

Each time a transaction event happens, we will send a HTTP POST request to your endpoint(s) that are subscribed to that event. The payload with event data is in the JSON format and can be used immediately. Every webhook endpoint must acknowledge the request, and as we strongly advise, verify the webhook signature.

Acknowledging request

To acknowledge the receipt of the event, your endpoint must return 2xx HTTP status code. All other response codes, including 3xx codes, indicate that you did not receive the event.

If we do not receive 200 HTTP status code, we will make up to 3 more request attempts. There is 6, 60 and 600 seconds delay between each delivery attempt respectively. If all request attempts fail, we mark webhook request as failed and will no longer try to deliver it.

Each webhook request has a flashfx-request-id header with a string that uniquely identifies a webhook event. For example, if there are multiple delivery attempts for the webhook event, each request will hold the same flashfx-request-id. This can be used to check if the webhook event was already processed by your application.

We advise that you acknowledge webhook request as early as possible.

Securing the request

To ensure that webhook was sent by Flash Payments and not a third party, we include the cryptographic signature in each request’s flashfx-signature header.

  1. Extract signature from the request header

  2. Compute HMAC with SHA256 function. Use your endpoint secret as key and JSON payload string as a message.

  3. Compare signature in the header to the computed signature.

Here is a Node.js pseudo code to generate and compare signatures

const secret = 'my-webhook-secret';
function generateSignature(string) {
  return require('crypto')
    .createHmac('sha256', secret)
    .update(string)
    .digest('base64');
}

And verifying signature

function myCallbackEndpointHandler(req, res) {
  const signature = req.headers['flashfx-signature'];
  const payload = req.body;
  
  if (generateSignature(payload) !== signature) {
    console.error("Security warning! Webhook endpoint received bad data", req);
    res.sendStatus(500);
    return;
  }
  
  // proceed with the webhook processing
}

Testing your endpoint

Subscribing to the events

Webhooks

Two types of the webhooks

The main triggers for all webhooks - are payment, withdrawal, deposit or conversion status changes. E.g. when a withdrawal goes from PENDING to CONFIRMED status.

There are two types of webhooks in Flash Payments.

    • You can lookup the history of all the HTTP requests and responses, their JSON bodies and headers.

    • If there is no response we will show you what exactly the problem is: DNS issue, networking issue, 5XX response, etc.

    • You can receive webhooks when a deposit lands to your Virtual Account Number (VAN).

Security

Cryptographic signature

Flash Payments webhook request IP address

All webhook HTTP requests would be coming from these IP addresses:

  • Development environment: 52.62.195.119

  • UAT environment: 52.64.185.170 and 13.210.129.208

  • Production environment: 52.62.138.234 and 52.65.3.195

Example payloads

Deposits

deposit_initiated
{
  "event": "deposit_initiated",
  "id": "603f0198770d6595e3c83e0d",
  "amount": 100,
  "totalFee": 1,
  "currency": "AUD",
  "externalReference": "2233445566",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "statusMessage": "Deposit initiated",
  "recipient": {
    "accountName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387"
  },
  "sender": {
    "accountName": "ACME Inc",
    "companyName": "ACME Inc",
    "bankName": "Bank ACME",
    "bankCountry": "AU"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
deposit_reviewing
{
  "event": "deposit_reviewing",
  "id": "603f0198770d6595e3c83e0d",
  "amount": 100,
  "totalFee": 1,
  "currency": "AUD",
  "externalReference": "2233445566",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "statusMessage": "Awaiting manual compliance",
  "recipient": {
    "accountName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387"
  },
  "sender": {
    "accountName": "ACME Inc",
    "companyName": "ACME Inc",
    "bankName": "Bank ACME",
    "bankCountry": "AU"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
deposit_cleared
{
  "event": "deposit_cleared",
  "id": "603f0198770d6595e3c83e0d",
  "amount": 100,
  "totalFee": 1,
  "currency": "AUD",
  "externalReference": "2233445566",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "statusMessage": "Deposit cleared",
  "recipient": {
    "accountName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387"
  },
  "sender": {
    "accountName": "ACME Inc",
    "companyName": "ACME Inc",
    "bankName": "Bank ACME",
    "bankCountry": "AU"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
deposit_cancelled
{
  "event": "deposit_cancelled",
  "id": "603f0198770d6595e3c83e0d",
  "amount": 100,
  "totalFee": 1,
  "currency": "AUD",
  "externalReference": "2233445566",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "statusMessage": "Cancelled by: john@example.com : ",
  "recipient": {
    "accountName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387"
  },
    "sender": {
    "accountName": "ACME Inc",
    "companyName": "ACME Inc",
    "bankName": "Bank ACME",
    "bankCountry": "AU"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
deposit_refunding
{
  "event": "deposit_refunding",
  "id": "603f0198770d6595e3c83e0d",
  "amount": 100,
  "totalFee": 1,
  "refundAmount": 99,
  "currency": "AUD",
  "externalReference": "2233445566",
  "refundReason": "Client refund request",
  "statusMessage": "Deposit refunded",
  "refundedAt": "2021-03-03T03:28:43.936Z",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "recipient": {
    "accountName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387"
  },
    "sender": {
    "accountName": "ACME Inc",
    "companyName": "ACME Inc",
    "bankName": "Bank ACME",
    "bankCountry": "AU"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
deposit_refunded
{
  "event": "deposit_refunded",
  "id": "603f0198770d6595e3c83e0d",
  "amount": 100,
  "totalFee": 1,
  "refundAmount": 99,
  "currency": "AUD",
  "externalReference": "2233445566",
  "refundReason": "Client refund request",
  "statusMessage": "Deposit refunded",
  "refundedAt": "2021-03-03T03:28:43.936Z",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "recipient": {
    "accountName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387"
  },
    "sender": {
    "accountName": "ACME Inc",
    "companyName": "ACME Inc",
    "bankName": "Bank ACME",
    "bankCountry": "AU"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}

Withdrawals

withdrawal_initiated
{
  "event": "withdrawal_initiated",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "currency": "AUD",
  "externalId": "12344321",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
withdrawal_reviewing
{
  "event": "withdrawal_reviewing",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "currency": "AUD",
  "statusMessage": "Awaiting manual compliance"
  "externalId": "12344321",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
withdrawal_pending
{
  "event": "withdrawal_pending",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "currency": "AUD",
  "statusMessage": "Sent to recipient bank"
  "externalId": "12344321",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
withdrawal_completed
{
  "event": "withdrawal_completed",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "currency": "AUD",
  "externalId": "12344321",
  "statusMessage": "Transaction Confirmed",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
withdrawal_failed
{
  "event": "withdrawal_failed",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "currency": "AUD",
  "externalId": "12344321",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
withdrawal_refunded
{
  "event": "withdrawal_refunded",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "refundAmount": 2000,
  "currency": "AUD",
  "externalId": "12344321",
  "refundReason": "No account or incorrect account number",
  "statusMessage": "Payout reversal",
  "refundedAt": "2021-03-04T15:21:11.920Z",
  "clearedAt": "2021-03-03T03:25:12.792Z",
  "recipient": {
    "displayName": "John Smith",
    "bsb": "012620",
    "accountNo": "89900998"
  },
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "John Smith",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}
withdrawal_cancelled
{
  "event": "withdrawal_cancelled",
  "id": "51711af8c078ba061f623531",
  "amount": 2000,
  "totalFee": 1,
  "currency": "AUD",
  "externalId": "12344321",
  "rejectCode": "CANCELLATION_REQUESTED_BY_PARTICIPANT", 
  "statusMessage": "The transaction is rejected upon request.",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}

Payments

currency_converted
{
  "event": "currency_converted",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "externalId": "12344321"
}
payment_complete
{
  "event": "payment_complete",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "externalId": "12344321"
}
payment_failed
{
  "event": "payment_failed",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "externalId": "12344321"
}
payment_cancelled
{
  "event": "payment_cancelled",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "externalId": "12344321"
}
payment_created
{
  "event": "payment_created",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 3500,
  "fromCurrency": "EUR",
  "toAmount": 2501.94,
  "toCurrency": "AUD",
  "subClient": {
    "id": "203af01936410fd5d5e3c8f14d",
    "fullName": "ACME Inc",
    "accountNo": "1839394",
    "bsb": "809387",
    "externalId": "111222333"
  }
}

Conversions

conversion_initialised
{
  "event": "conversion_initialised",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "rate": 0.41104,
  "externalId": "12344321"
}
conversion_pending
{
  "event": "conversion_pending",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "rate": 0.41104,
  "externalId": "12344321"
}
conversion_converted
{
  "event": "conversion_pending",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "rate": 0.41104,
  "externalId": "12344321"
}
conversion_failed
{
  "event": "conversion_pending",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "rate": 0.41104,
  "externalId": "12344321"
}
conversion_cancelled
{
  "event": "conversion_pending",
  "id": "60711af8c078ba061f623531",
  "fromAmount": 1000,
  "fromCurrency": "AUD",
  "toAmount": 411.04,
  "toCurrency": "EUR",
  "rate": 0.41104,
  "externalId": "12344321"
}

Reference data

  1. depositDetails - query the accounts you can send deposits to in order to increase your Flash Payments balance.

If your transaction is canceled by our Compliance team, the unique rejectCode and a corresponding standard statusMessage will be assigned to this transaction and sent to your application via proper webhook such as to be used for a subsequent integration action such as field mapping or reconciliation.

When , or you can provide us a webhook (callback) URI - callbackUri. We will call it when a payment or withdrawal status changes.

There are two steps to begin using webhooks. Building a custom endpoint on your server and registering it via the settings.

Before you can verify a signature, you need to retrieve your endpoint’s secret from webhook settings in the . Each registered endpoint has a unique secret that is used to sign a payload delivered to you on each event. Steps to verify signature:

To make sure your webhook endpoint is setup correctly, you can make a test HTTP request from the webhook settings. Click the "Send Test” button. You should receive a dummy request, which will need to be acknowledged the same way as your real webhook requests.

Webhook requests come with event data. You can see all available event types in the settings. To subscribe, select which events you would like to receive and specify your endpoint. Please note, your endpoint must adhere to the HTTPS protocol for security reasons.

- a URL would need to be saved to your settings. All types of events.

- you would need to provide a callback URL per payment/withdrawal while creating them. Only "payment", "withdrawal", and "conversion" events are supported.

The webhooks HTTP POST calls will follow all the (3XX codes).

All webhook HTTP requests carry a cryptographic signature. and do it slightly different though.

- query bank information to validate if we support your BSB, IBAN, BIC (aka Swift code).

- query countries/currency combinations we support and what the required bank account details are.

withdrawal_canceled
sending a payment
creating a local withdrawal
ordering a conversion
FlashConnect
FlashConnect
FlashConnect
FlashConnect
Regular webhooks
FlashConnect
Ad hoc webhooks
standard HTTP redirects
Ad hoc
regular webhooks
bankInfo
availableDeliveryMethods

Bank information

Ensuring bank details are correct

To validate BSB, BIC (aka SWIFT code) or IBAN use the bankInfo query.

The bankInfo query accepts only one of bsb, bic, or iban arguments. Otherwise, it will return an error.

The below sample queries will return null if the BSB, BIC, IBAN is not found.

{
    bankInfo(input: { bsb: "012622" }) {
        name
        address {
            building
            street
            suburb
            state
            country
            postcode
        }
    }
}
{
    bankInfo(input: { bic: "BARCGB22" }) {
        name
        address {
            building
            street
            suburb
            state
            country
            postcode
        }
    }
}
{
    bankInfo(input: { iban: "DE59500105178646768962" }) {
        name
        bic
        address {
            building
            street
            suburb
            state
            country
            postcode
        }
    }
}
{
  "data": {
    "bankInfo": {
      "name": "BARCLAYS BANK PLC",
      "bic": "BARCGB22",
      "address": {
        "building": null,
        "street": "1 CHURCHILL PLACE",
        "suburb": "LONDON",
        "state": null,
        "country": "GB",
        "postcode": "E14 5HP"
      }
    }
  }
}

Change log

History of changes to this API schema

2025-05-02

Removed (BREAKING)

Removed depositDetails query as deprecated and non-functioning since March 2024.

2025-01-24

Changed

Also, the first, last, and middle names are limited to 75 chars now.

Also, FQDN-like names will be rejected. Examples: "Aaron x.com", "Ben.eu", "Visit as at URL:example.com/about", etc.

2025-01-18

Added

2024-12-09

Added

2024-10-22

Added

  • New mutation createConversion. New queries conversion and conversions.

  • The FromCurrency enum used to have only one item AUD. Now there are 8: AUD CAD CHF EUR GBP NZD SGD USD.

  • New property for the Quote type: applicability. It indicates if the quote can be used for payments or conversions.

2024-10-11

Fixed

2024-10-01

Changed (BREAKING)

Improved validation of recipient, sender, withdrawal, institution related mutations. From now on email, companyName, legalName, businessNumber, externalReference must include only the ASCII characters.

2024-05-18

Removed (BREAKING)

Removed AccountIdType.PH_CASH, Recipient.phCashoutNetwork with RecipientInput.phCashoutNetwork and the corresponding enum type PhCashoutNetwork from the GraphQL schema. These were not working for more than a year.

2024-05-17

Removed (BREAKING)

Removed AccountIdType.RIPPLE, Recipient.rippleAddress with Recipient.destTag from the GraphQL schema. These were deprecated 2.5 years ago.

2024-04-16

Removed (BREAKING)

Removed Sender.isRipple and CurrencyIso3.XRP from the GraphQL schema. These were deprecated 2.5 years ago.

2024-03-13

Added

2024-02-05

Changed

2023-11-01

Added

2023-10-25

Removed (BREAKING)

  • Fields acceptingInstructionInstitutionSenderId and acceptingMoneyInstitutionSenderId were removed from the CreateWithdrawalInput.

Added

  • Instead instructingInstitutionId was added. (A new API for creating "institutions" is coming soon, but at the moment they can be created via the Flash Connect.)

2023-08-22

Added

    • Currently it returns exactly 1 day of data. We plan to make date range selection more flexible in the future.

2023-08-04

Changes

2023-07-28

Changes

  • Our system always allowed accountNo to have letter. However, our API forced digits only. So, from now on, when you use createRecipient, your accountNo can have both letters and digits.

2023-05-25

Changes

  • Improved mobile phone validation. Now if mobile starts with "00" it's treated as if it starts with "+".

  • Quote size accepts positive numbers only.

Changes (BREAKING)

  • The recipient.mobile and sender.mobile can accept only valid international phone numbers.

2023-03-15

Added

2023-03-03

Added

  • idempotencyKey to createPayment input.

  • idempotencyKey to createWithdrawal input.

2023-02-23

Added

2023-02-08

Removed (BREAKING)

  • Removed the auto-creation of id for embedded senders and recipients. This means that if you (or FlashFX system) have created withdrawals and payments without explicitly providing sender or recipient ID then from now on the sender.id or recipient.id will be null. But, if you create payments or withdrawals via this API then you will always have payment.sender.id or withdrwal.recipient.id.

2022-09-06

Added

  • Missing expireAt property to the Quote object returned by the quote query.

2022-09-02

Added

  • New REVIEWING status to deposit and withdrawal status enum.

    • REVIEWING : deposit/withdrawal is being manually checked (e.g. compliance) before proceeding.

2022-08-25

Added

    • Previously only the deposit_cleared was sent and customers had no idea we are holding (reviewing) the deposit.

    • The deposit_cleared will be sent immediately as we approve (clear) the deposits. So, no changes here.

2022-07-01

Added

  • New item in deposit and related webhooks:

    • recipient - deposit recipient information as specified by deposit sender for this transaction:

      • accountName

      • accountNo

      • bsb

  • New item in deposit.sender:

    • bankName

  • New mutation to refund deposits:

    • refundDeposit(id:ID! input:RefundDepositInput): RefundDepositReply

2022-04-22

Changes

  • Additional validation for dob field introduced for Senders, Recipients and Sub-clients to enforce the data is entered in YYYY-MM-DD format. The field will also allow for only the data after 1900-01-01 and individuals of 18 years of age or older.

2022-04-12

Changes

  • Added validation of address fields. From now on, any address submitted as a part of any transaction should only include ASCII characters.

2022-02-25

Changes

  • Added deposit.sender.accountName so that you can query who deposited money to your Virtual Account Number (VAN).

2022-02-14

Changes

2022-02-09

Changes

  • FundingAccount type has been extended to include all deposit details you need to bring money to Australia. Your account address can now be retrieved using accountAddress property along with name and address fields which identify the accepting financial institution associated with your account.

2022-01-12

Changes

  • lastName and firstName fields of Sender and Recipient objects can now be one symbol long to allow for initials. Please note that such single symbols have to be alphabetic.

2021-11-02

Changes

  • Occasionally Payment objects do not have sender or recipient properties. Thus these properties are now marked at "not required" (exclamation mark was removed) when querying payments.

  • We have added rate limiting. You can receive HTTP 429 error code and get temporary blocked if abusing the API too much.

2021-08-13

Changed (BREAKING)

  • Removed XRP currency form the list of supported currencies.

2021-07-22

Changed (BREAKING)

  • While creating sub-clients the address of the person/company was not required. It was a bug which was fixed. To create a sub-client you would also need their: street address, suburb/city, state/region, postcode, and country.

2021-07-14

Changes

  • Allow accountNo to be 4 digits long. Some old Japanese bank accounts could be just 4 digits.

2021-07-08

Added

  • The ability to query deposits, withdrawals, payments by the associated sub-client (subClientId).

  • The payments can also have sub-clients now. Added the Payment.subClient field.

2021-06-29

Added

  • The totalFee property to both Deposit and Withdrawal types as well as webhook payloads.

2021-06-22

Added

  • The bankInfo reference query. You can now validate your BSB for existence, check if we support your BIC, and retrieve BIC (aka SWIFT code) by IBAN.

2021-06-17

Added

2021-05-25

Changed

  • The senderId was always required when creating withdrawals via createWithdrawal. But now, if you provided the subClientId and didn't provide the senderId the sub-client becomes the sender, and will be reported to the government as the sender. However, you still must provide the senderId if your sub-client moves funds for other people/companies.

2021-05-17

Changed (BREAKING)

  • Replaced docIssuer, docType and docNumber fields from CreateSubClientInput with idDoc nested field instead.

2021-04-26

Changed

  • RecipientAccountIdType was fully duplicating the AccountIdType. Replace the former with the latter. This might break your auto-generated code in strongly typed languages. But won't change any API queries or responses. So, this change is not considered to be a breaking.

2021-04-16

Added

  • Added ability to disable and activate sub-clients

    • mutation disableSubClient(id: ID!): MutateSubClientReply

    • mutation activateSubClient(id: ID!): MutateSubClientReply

2021-04-12

Added

  • Added deposit queries

    • query deposits(input: DepositQueryInput): [Deposit]

    • query deposit(id: ID!): Deposit

  • Introduced sub-client feature – transactional virtual account numbers for AUD processing in Australia.

    • query subClients(input: SubClientQueryInput): [SubClient]

    • query subClient(id: ID!): SubClient

    • mutation createSubClient(input: CreateSubClientInput!): MutateSubClientReply

  • Deposit and withdrawal webhooks now include subClient object with sub-client information when present

2021-01-07

Removed (BREAKING)

These types and fields were never used by anyone for couple of years.

  • Removed enum DepositMechanism.

  • PaymentInput and ConfirmPaymentInput fields:

    • removed depositMechanism

    • removed depositReference

    • removed depositAmount

2020-12-16

Added

  • New item in BsbDepositDetails

    • accountName - Australian account name.

  • New item in Withdrawal

    • statusMessage - a human readable message of the current status reason, like processing error messages.

  • New item in Payment and PaymentInput

    • sourceOfFunds - mandatory field for some destinations.

  • New enum SourceOfFunds.

2020-10-14

Added

  • New items in both query type and mutation input Senders.

    • legalName

    • tradingAsName

    • businessNumber - differs by country, e.g. ABN in Australia.

    • acn - Australian Company Number. Should not be used for other countries.

2020-06-18

Changed (BREAKING)

  • Fixed typo in RecipientQueryInput field name. snaps -> cnaps

2020-05-04

Added

  • New compliance-related fields to the CreateWithdrawalInput input:

    • acceptingMoneyInstitutionSenderId - you must pre-create this Sender and submit every time if you are not the FI who collected the money for this withdrawal.

    • acceptingInstructionInstitutionSenderId - you must pre-create this Sender and submit every time if you were instructed by other FI to make this withdrawal.

2020-03-05

Changed (BREAKING)

  • Fixed typo in the WithdrawalStatus enum item. INITIALISING -> INITIALISED

2020-02-12

Added

  • callbackUri to Payment, Withdrawal, CreateWithdrawalInput. Now you can query the callback/webhook URI you have supplied earlier. Also, this allows you to receive webhooks when you create a withdrawal (aka local payout).

2020-02-11

Added

  • New items in RecipientQueryInput. This means that recipients can be searched by:

    • firstName

    • lastName

    • middleName

    • dob - date of birth

    • companyName

    • phCashoutNetwork

    • payid

    • bic

    • iban

    • aba

    • bsb

    • clabe

    • cnaps

    • sortCode

    • ifsc

    • accountNo

    • rippleAddress

    • externalId - ID in your system

2020-01-28

Added

  • Introduced Withdrawals - send money from your account (FlashFX digital wallet) to local banks.

    • query withdrawal(id: ID): Withdrawal

    • query withdrawals(input: WithdrawalQueryInput): [Withdrawal]

    • mutation createWithdrawal(input: CreateWithdrawalInput!): CreateWithdrawalReply

  • PHP currency support.

  • middleName property in recipients and senders.

  • PAYID recipient type for Australian local payments or withdrawals.

    • Recipient.payid new property.

  • PH_CASH recipient type for Philippines cash network payments.

    • Recipient.phCashoutNetwork new property.

  • You can now query your recipients by accountIdType property. For example: recipients(input: { accountIdType: PH_CASH })

Removed (BREAKING)

  • Removed the unused enum PaymentType. It has no sense and was deprecated a year ago.

    • Simultaneously removed properties Payment.paymentType, PaymentQueryInput.paymentTypes, PaymentInput.paymentType.

  • Removed the never used AccountIdType enum values: BPAY, FIN_BTN, INTERAC.

Quote

Quote the current bid and ask for a currency pair and size.

Consider requesting an indicative quote to understand the current currency trading rates before deciding to take action. Please be aware that market makers are not required to honor indicative quotes.

Paste this query to the GraphQL Playground to request an indicative quote

In contrast to an indicative quote, a tradable quote is guaranteed by the market maker.

Paste this query to the GraphQL Playground to request a tradable quote. It is important to consider the expireAt date and time, and preserve the id of a tradable quote for future createPayment and createConversion calls.

Improved validation rules for the following mutations: , , , , , and Affected fields: idDoc.docNumber idDoc.issuer legalName businessNumber legalName externalId. These fields allow only the ASCII characters now.

New fields have been added to the , , and mutations. You can now provide idDoc.country, idDoc.issueDate, and idDoc.expiryDate. The idDoc.issuer field now only stores additional information about the issuer, while idDoc.country holds the country code of the country that issued the document. To avoid creating a breaking change, we currently allow you to provide idDoc.country and/or idDoc.issuer. In the future, we plan to make idDoc.country a required field.

New mutation. You can change a sub-client's externalId now, but nothing else.

New the feature.

The bankInfo was not returning information about BICs and IBANs. It works now.

New introduced for rejected (aka cancelled) withdrawals. When withdrawals you can clearly see why using the new rejectCode and statusMessage. Available in the Withdrawal type and sent to your application via the webhook.

Improved to respond with appropriate error message when trying to change the recipient's accountIdType which is not allowed by design.

Added to the CreateWithdrawalInput.

query.

This query returns the same data as the Download CSV button on the Account Statement page of the . It explains every change of you primary balance.

Changed links from to domain. Old domain will continue working unit future notice.

Added the withdrawal_pending . Invoked after the transaction is sent to the recipient bank for processing.

Added for the withdrawal_pending .

New status - UNAPPROVED.

Fixed the withdrawal_reviewing . It was never sent before even though declared on the Flash Connect website.

Added for the withdrawal_reviewing .

Added corresponding event types: deposit_reviewing and withdrawal_reviewing.

New event type: deposit_initiated to notify that we received a deposit but not yet cleared it.

Additional validation for lastName, middleName and firstName introduced allowing only for latin alphabetical characters and special symbols:

The fundingAccounts and SubClient.fundingAccounts queries. It returns international bank account numbers you can deposit in order to bring money to Australia. See for more details.

Removed the long deprecated PaymentInput.recipient object. The only way to provide a recipient for a payment is via PaymentInput.recipientId. You would need to beforehand.

Conversions
query
static codes and standard status messages
get cancelled
withdrawal_cancelled
updateRecipient
statement
Flash Connect
flash-fx.com
flash-payments.com
webhook
example
webhook
sub-client
webhook
example
webhook
webhook
webhook
Auto receive funds
createWithdrawal
createPayment
createSender
updateSender
createInstitution
createSubClient
createSender
updateSender
createSubClient
updateSubClient
instructingInstitution
pre-create the recipient
{
  quote(
    input: { fromCurrency: AUD, toCurrency: USD, size: 10000, currency: AUD }
  ) {
    bid
    ask
    symbol
    timestamp
    inverted
  }
}
{
  "data": {
    "quote": {
      "bid": 0.61104,
      "ask": 0.62077,
      "symbol": "USDAUD",
      "timestamp": "2018-08-13T07:54:54.993Z",
      "inverted": true
    }
  }
}
{
  quote(
    input: { 
      fromCurrency: AUD 
      toCurrency: USD 
      size: 10000 
      currency: AUD 
      tradeable: true 
    }
  ) {
    bid
    ask
    symbol
    timestamp
    inverted
    expireAt
    id
  }
}
{
  "data": {
    "quote": {
      "bid": 0.61339,
      "ask": 0.63101,
      "symbol": "AUDUSD",
      "timestamp": "2025-03-04T01:53:08.829Z",
      "inverted": false,
      "expireAt": "2025-03-04T01:55:08.830Z",
      "id": "67c65d04e5086d18751617ba"
    }
  }
}
Institution explanation