This workflow is for customers that want to pass the KYC and AML off to Routefusion and partners.  This is the quickest way to get up and running with Routefusion in days not months.

Summary

This walk-through will show you how to implement the Routefusion API for products looking to deliver a 100% self-serve workflow to their customers to unlock cross-border payments. The implementation guide will take you through the execution of each workflow required will look like:

  1. Create a user account
  2. Submit user's KYB/KYC information for automated compliance review
  3. Poll for user verification status
  4. Create a user bank account
  5. Create a Beneficiary
  6. Create a Transfer
  7. Get a rate
  8. Finalize the Transfer

Authenticate

To authenticate to the Routefusion API you will need to send a bearer token in an Authorization header.

curl --location --request POST '<https://sandbox.routefusion.co/graphql>' \\
--header 'Content-Type: application/json' \\
--header 'Authorization: Bearer yourBearerToken' \\
--data '{ someQuery }'

Create a user account

First we are going to create a user account. This will initially create the user account on Routefusion which will enable the user to perform other actions.

mutation createUserAccount (
	$identifier: String!, 
	$company_identifier: String, 
	$email: String!, 
	$first_name: String, 
	$last_name: String, 
	$admin: Boolean, 
	$send_invite_email: Boolean
) {
   createUserAccount (
		identifier: $identifier,
		company_identifier: $company_identifier, 
		email: $email, 
		first_name: $first_name, 
		last_name: $last_name, 
		admin: $admin, 
		send_invite_email: $send_invite_email
	)
}

Submit user's compliance data

Now that the user has been created on Routefusion we need to submit the KYB/KYC information to initiate the compliance review. KYB, Know Your Business, and KYC, Know Your Customer, is just compliance jargon for data required by compliance to verify the user is who they say they are.

mutation createBusinessCompliance (
  $user_id: UUID!,
  $business_name: String,
  $contact_first_name: String!,
  $contact_last_name: String!,
  $address1: String!,
  $address2: String,
  $city: String,
  $state_province_region: String,
  $postal_code: PostalCode,
  $country: ISO3166_1!,
  $business_type: String!,
  $officer1: OfficerInput,
  $officer2: OfficerInput,
  $officer3: OfficerInput,
  $officer4: OfficerInput
) {
    createBusinessCompliance (
      user_id: $user_id, 
      business_name: $business_name, 
      contact_first_name: $contact_first_name, 
      contact_last_name: $contact_last_name,
      address1: $address1,
      address2: $address2,
      city: $city,
      state_province_region: $state_province_region,
      postal_code: $postal_code,
      country: $country,
      business_type: $business_type,
      officer1: $officer1,
      officer2: $officer2,
      officer3: $officer3,
      officer4: $officer4
    )
}

Poll for user status

Once you have submitted your user's compliance data it usually takes between 24 and 72 hours to get approval from compliance. You will want to poll us to make sure the user is approved by compliance before performing more actions. Looking for webhooks? We will have them by end of Q1!

query userAccount ($id: UUID!) {
    userAccount (id: $id) {
        id
        identifier
        email
        first_name
        last_name
        admin
        authenticated
        verified
        verification_submitted
        company_name
        locked
        locked_by
        locked_at
        created_at
        updated_at
        organization {
            id
            identifier
            admin
            restricted
            enabled
        }
    }
}

Create a user bank account

This is a reference to the user's bank account that will be the ultimate source of funds for payments from the user.

mutation createAccount (
  $user_id: UUID!
  $name_on_account: String!
  $swift_bic: SwiftBic
  $account_number: BankAccountNumber!
  $routing_code: BankRoutingCode
  $currency: ISO4217!
  $country: ISO3166_1!
  $name: String!
  $address1: String
  $address2: String
  $city: String
  $state_province_region: String
  $postal_code: PostalCode
) {
    createAccount (
      user_id: $user_id
      name_on_account: $name_on_account
      swift_bic: $swift_bic
      account_number: $account_number
      routing_code: $routing_code
      currency: $currency
      country: $country
      name: $name
      address1: $address1
      address2: $address2
      city: $city
      state_province_region: $state_province_region
      postal_code: $postal_code
		)
}

Create a beneficiary

Before the user is approved by compliance, they can create beneficiaries. This will reduce the overhead to making payments once the user is approved.

mutation createBeneficiary (
	$user_id: UUID!
  $type: BeneficiaryType!
  $email: Email!
  $currency: ISO4217!
  $phone: Phone
  $first_name: String
  $last_name: String
  $business_name: String
  $address1: String
  $address2: String
  $city: String
  $state_province_region: String
  $postal_code: PostalCode
  $country: ISO3166_1!
  $tax_number: TaxNumber
  $bank_account: BankAccountInput!
) {
    createBeneficiary (
			user_id: $user_id
      type: $type
      email: $email
      currency: $currency
      phone: $phone
      first_name: $first_name
      last_name: $last_name
      business_name: $business_name
      address1: $address1
      address2: $address2
      city: $city
      state_province_region: $state_province_region
      postal_code: $postal_code
      country: $country
      tax_number: $tax_number
      bank_account: $bank_account
		)
}

Create a transfer

Once the user is approved and they have created beneficiaries, they can create their first transfer!

A little more on transfers first

Initiating a transfer is broken out into multiple steps in order to support the workflow which best fits the experience you want to deliver to your clients.

First:  you will create a transfer, or transfer object.  Once you have created this, you can make changes to the transfer object, such as fetching a new rate, updating amounts, etc.  Once the transfer is ready, you will submit it and off to the races you will go.

Transfers contain payment data (amounts and currencies), beneficiary data (entity and banking information), and rate data (exchange rate information, also known as a quote)

mutation createTransfer (
  $user_id: UUID!
  $source_amount: String
  $destination_amount: String
  $account_id: UUID!
  $beneficiary_id: UUID!
  $purpose_of_payment: String!
  $reference: String
) {
    createTransfer (
      user_id: $user_id
      source_amount: $source_amount
      destination_amount: $destination_amount
      account_id: $account_id
      beneficiary_id: $beneficiary_id
      purpose_of_payment: $purpose_of_payment
      reference: $reference)
}

Update transfer

🚧

Get a rate

Once you have created a transfer, you can set a rate on the transfer which will lock in that rate for the transfer if you chose to finalize it.  Rates typically will hold for 30 seconds to 1 minute.  Once you lock in a rate and submit the transfer you have 24 hours to "fund" the payment if you are doing a push model.  If you are doing a pull model you do not need to worry about this.

mutation getRate (
	$transfer_id: UUID!, 
	$source_amount: String, 
	$destination_amount: String
) {
    getRate (
			transfer_id: $transfer_id, 
			source_amount: $source_amount, 
			destination_amount: $destination_amount
		)
}

Finalize transfer

Now that the transfer has the desired data you are ready to initiate the payment! Finalizing the transfer will initiate the transfer to the beneficiary's bank account. This will lock in the rate you previously set on the transfer in the Get a rate section.

mutation finalizeTransfer ($transfer_id: UUID!) {
    finalizeTransfer (transfer_id: $transfer_id)
}

You're done!

You nailed it! You have successfully sent your first payment with Routefusion 🙌

This will be a living document, and will continually be updated.  If you have any questions, please reach out and ask.  If you have any suggestions we would love to hear them!

engineering@routefusion.com