Split Funding Flow

This document is to give an overview how a partner/merchant would want to go about split funding its merchants/clients. The examples below show 1 payment coming in, and 2 payments being paid out with some of the initial payment staying in the original merchants account. This model can still work for any number of people/companies being paid out.


  1. Customer makes a payment to Merchant A using a Bank Card or via an ACH transaction. Based off the SDK credentials used to process the payment, that money will settle to whatever settlement account is configured on that merchant.
  2. After the merchant batches for the day you will know how much money is going to be settled into that account (timing on actually settling into the account depends on when the merchants batch time is and funding schedules).
  3. Using that same Merchant's credentials, you will then want to run ACH Credits for each desired amount (calculated by the partner's software not Base Commerce) to the people(s) or companies which need to be paid out.



Ex.

  1. Bob makes a $100 credit card payment to Merchant A.
  2. At the end of the day the merchant batches, so they have a total of $100 that will settle into Merchant A's account (exact timing on settlement of funds and being available in the merchants account, based on the merchants funding schedule).
  3. Using Merchant A's SDK credentials, an ACH SDK Credit transaction is created for 20% to pay out Sally, and then a second transaction is created to pay out 30% to Merchant B.
    1. To pay these people out there are two options on how to get the money into Sally's and Merchant B's accounts.
      1. A vault record could be created before hand with their bank information, then when processing the ACH Credit payment, just set the vault record's token on the BankAccountTransaction. This is the preferred method then you do not need to store the customers bank information for future use since Base Commerce will.
      2. The bank account info for Sally and Merchant B could be entered each time on the BankAccountTransaction of where the money will be split to.
  4. Sally will then get $20, Merchant B will get $30, and then the remaining $50 will stay in Merchant A's settlement account.









Sample code

/**
 * This is a very basic example of how to do "split funding"
 * There is minimal error handling/checking and this is solely meant to be used as an example to get an understanding of the process flow.
 */
public static void splitFundingTechDocExample() throws BaseCommerceClientException {
 
    //set variables for the tokens you will use later to process the split payments under
    String s_sally_token = "";
    String s_merchant_b_token = "";
    int n_bobs_transaction_id = 0;
 
    //Add vault record for user (Sally) who will be paid out later once the merchant settles
    BankAccount o_ba_sally = new BankAccount();
    o_ba_sally.setName("Sally");
    o_ba_sally.setAccountNumber("111111111");
    o_ba_sally.setRoutingNumber("011001962");
    o_ba_sally.setAlias("Sallys Wells Fargo Checking Account");
    o_ba_sally.setType(BankAccount.XS_BA_TYPE_CHECKING);
 
    BaseCommerceClient o_client = new BaseCommerceClient(XS_USERNAME, XS_PASSWORD, XS_KEY);
    o_client.setSandbox(true);
    o_ba_sally = o_client.addBankAccount( o_ba_sally );
    if( o_ba_sally.isStatus(BankAccount.XS_BA_STATUS_FAILED ) ) {
        // Bank Account add failed, look at messages for reasons why
        System.out.println( o_ba_sally.getMessages() );
    } else if( o_ba_sally.isStatus( BankAccount.XS_BA_STATUS_ACTIVE ) ) {
        // Bank Account added Successfully, record the token in your system so you can use it later
        s_sally_token = o_ba_sally.getToken();
    }
 
 
    //Add vault record for Merchant B user who will be paid out later once the merchant settles
    BankAccount o_ba_merchant_b = new BankAccount();
    o_ba_merchant_b.setName("Merchant B");
    o_ba_merchant_b.setAccountNumber("999999999");
    o_ba_merchant_b.setRoutingNumber("011001962");
    o_ba_merchant_b.setAlias("Merchant B's BA Checking Account");
    o_ba_merchant_b.setType(BankAccount.XS_BA_TYPE_CHECKING);
 
    o_ba_merchant_b = o_client.addBankAccount( o_ba_merchant_b );
    if( o_ba_merchant_b.isStatus(BankAccount.XS_BA_STATUS_FAILED ) ) {
        // Bank Account add failed, look at messages for reasons why
        System.out.println( o_ba_merchant_b.getMessages() );
    } else if( o_ba_merchant_b.isStatus( BankAccount.XS_BA_STATUS_ACTIVE ) ) {
        // Bank Account added Successfully, record the token in your system so you can use it later
        s_merchant_b_token = o_ba_merchant_b.getToken();
    }
 
 
    // Bob is going to run a $100 transaction which then later will be split up between the merchant, Sally, and Merchant B
    BankCardTransaction o_bct = new BankCardTransaction();
    o_bct.setType(BankCardTransaction.XS_BCT_TYPE_SALE);
    o_bct.setAmount(100);
    o_bct.setCardName("Sample Bank Card Transaction");
    o_bct.setCardNumber("4111111111111111");
    o_bct.setCardExpirationMonth("10");
    o_bct.setCardExpirationYear("2021");
 
 
    o_bct = o_client.processBankCardTransaction( o_bct );
 
    if (o_bct.isStatus(BankCardTransaction.XS_BCT_STATUS_FAILED)) {
        // Transaction failed, look at messages for reasons why
        System.out.println( "failed:  " + o_bct.getMessages() );
    } else if( o_bct.isStatus( BankCardTransaction.XS_BCT_STATUS_DECLINED ) ) {
        // Transaction declined, look at response code and response message
        System.out.println(o_bct.getResponseCode());
        System.out.println( o_bct.getResponseMessage());
    } else if( o_bct.isStatus( BankCardTransaction.XS_BCT_STATUS_CAPTURED ) ) {
        // Transaction successful, record the transaction ID for your own reference
        n_bobs_transaction_id = o_bct.getTransactionId();
    }
 
 
    //NOTE
    //After the merchant settles and the money is moved to the merchants settlement account money can then be moved out.
    //This would need to be talked with your account manager depending on merchant batching and file cutoffs of when the money will 
    //be available to be moved from the merchant settlement account to the other accounts. This part of the code should NOT be run right after
    //the card payment is made otherwise this could lead to accounts being overdrawn.
 
 
   //For this scenario, Sally will be getting 20% and Merchant B will be getting 30% which leaves Merchant A to keep 50% of the initial $100
    BankAccountTransaction o_bat_sally = new BankAccountTransaction();
    //set the token on the BankAccountTransaction so that this money is going to go into Sallys account
    //If Sally did not have a vault record already, the routing and account number could be set instead on this BankAccountTransaction
    o_bat_sally.setToken( s_sally_token );
    //set the transaction type to CREDIT, so that the money will come from Merchant A (since we are using Merchant A's SDK credentials
    //and it will send the money to Sallys account
    o_bat_sally.setType(BankAccountTransaction.XS_BAT_TYPE_CREDIT );
    //The SEC method would be determined on who is getting the money, make sure to talk to your account manager/RM to make sure you
    //are using the right SEC methods for the right scenarios
    o_bat_sally.setMethod(BankAccountTransaction.XS_BAT_METHOD_PPD );
    //Just for tracking purposes the original transaction ID can be set as a custom field on the split funding ACH transaction
    //as a note though the custom fields are not searchable and are only used to pass data along that we keep stored.
    o_bat_sally.setCustomField1( String.valueOf( n_bobs_transaction_id ) );
    //The one merchant settable searchable field is the merchant transaction ID which can also be used here
    o_bat_sally.setMerchantTransactionID( String.valueOf( n_bobs_transaction_id ) );
 
    //based on whatever math and logic your software uses to calculate how much this person should be paid out, set that amount on the transaction
    //in our scenario we are doing 20% which is $20.
    o_bat_sally.setAmount( 20 );
 
    o_bat_sally = o_client.processBankAccountTransaction( o_bat_sally );
 
    if( o_bat_sally.isStatus( BankAccountTransaction.XS_BAT_STATUS_FAILED ) ) {
        //failed validation, look at error messages as to why
        System.out.println( o_bat_sally.getMessages() );
    } else if( o_bat_sally.isStatus( BankAccountTransaction.XS_BAT_STATUS_CREATED ) ) {
        //transaction was successful so update your system accordingly
        System.out.println("Sally's $20 Transaction ID :" + o_bat_sally.getBankAccountTransactionId() );
    }
 
 
    //Transaction for Merchant B's payout, based on whatever math and logic your software uses to calculate how much this person should be paid out
	//set that amount on the transaction in our scenario we are doing 30% which is $30.
    BankAccountTransaction o_bat_merchant_b = new BankAccountTransaction();
    o_bat_merchant_b.setToken( s_merchant_b_token );
    o_bat_merchant_b.setType(BankAccountTransaction.XS_BAT_TYPE_CREDIT );
    o_bat_merchant_b.setMethod(BankAccountTransaction.XS_BAT_METHOD_CCD );
    o_bat_merchant_b.setCustomField1( String.valueOf( n_bobs_transaction_id ) );
    o_bat_merchant_b.setMerchantTransactionID( String.valueOf( n_bobs_transaction_id ) );
 
    o_bat_merchant_b.setAmount( 30 );
 
    o_bat_merchant_b = o_client.processBankAccountTransaction( o_bat_merchant_b );
 
    if( o_bat_merchant_b.isStatus( BankAccountTransaction.XS_BAT_STATUS_FAILED ) ) {
        //failed validation, look at error messages as to why
        System.out.println( o_bat_merchant_b.getMessages() );
    } else if( o_bat_merchant_b.isStatus( BankAccountTransaction.XS_BAT_STATUS_CREATED ) ) {
        //transaction was successful so update your system accordingly
        System.out.println("Merchant B's $30 Transaction ID :" + o_bat_merchant_b.getBankAccountTransactionId() );
    } 
}