Changelog

Wire API (US only)

Payment API provides all the functionality required to manage wire beneficiaries and initiate payments on your user's behalf.

The Payment APIs are:

  • Dapi AutoFlow - The easiest and most efficient way to facilitate payments.
  • [Not required when using Autoflow] Get Wire Beneficiaries - Retrieve wire beneficiaries from the bank account.
  • [Not required when using Autoflow] Create Wire Beneficiary - Create a wire beneficiary into the bank account.
  • [Not required when using Autoflow] Create Wire Transfer - Initiate a wire transfer to an existing wire beneficiary only.

Dapi AutoFlow Wire Transfer [Recommended]

Wire Transfer Auto Flow automatically takes care of all requirements for adding a wire beneficiary as well as initiating a transfer. We recommend using Wire Transfer Auto Flow to initiate a payment.

Using Dapi AutoFlow you can easily create a wire transfer and listen on the success or failure results

Initializer Parameters

DescriptionTypeDescription
bankConnectionDAPIBankConnection REQUIRED A connection to the bank that will be used to call APIs upon. The connection will include details about the bank. Check How To Create Bank Connection
transferTypeDAPITransferType
OPTIONAL
by default it's a normal, but if you use us APIs you have to set it with Wire value
accountDAPIBankAccount?
OPTIONAL
Account where the amount must be transferred from.
If you don't provide it, AutoFlow will start display bank accounts screen for your user to pick the account from it.
wireBeneficiaryDAPIWireBeneficiary?
OPTIONAL
WireBeneficiary that will receive the money.
If you are accepting a transfer into your own company's account, you don't need to set the parameter. You can simply add one in your dashboard under your app. The wireBeneficiary will automatically be set to that account from there.
amountFloat?
OPTIONAL
Amount to be transferred.
If you don't set an amount SDK will display a screen with a numpad screen for your user to enter the amount in.
remarkString?
OPTIONAL
This is the id you can use to track the transaction.

❗️

How to set wire beneficiary details?

There are multiple ways to communicate the wire beneficiary details to Dapi. Please follow the best approach based on your exact use case and security requirements


  • Option 1: Set the wire beneficiary on the Dapi Dashboard.
    • ⚠️ Works only for static wire beneficiaries. (All of the transfers will be sent to wire beneficiaries that you know ahead of time.)
    • ✅ No configuration required on the SDK nor on the SDK Backend Server side.

  • Option 2: Set the wire beneficiary as the DAPIWireBeneficiary object in the SDK function call
    • ✅ Works for both dynamic and static wire beneficiaries.
    • ⚠️ You should be double-checking the wire beneficiary details integrity in the SDK Backend Server that you set up. This is to ensure no tampering with the data on the front-end layer.

  • Option 3: Set the wire beneficiary details only in the SDK Backend Server (in principle the same as Option 2)
    • ✅ Works for both dynamic and static wire beneficiaries.
    • ✅ You never have to expose the wire beneficiary details to the front-end layer.
    • ✅ You want your backend to be in full control of the wire beneficiary details.
    • ⚠️ Don't recommend for static wire beneficiary use cases, since it would be unnecessary additional development work on the Backend Server Side.


AutoFlow Examples for Different Use Cases

Note: No need to pass nil to any OPTIONAL parameter, just don't include it in its Initializer parameter.

//#1
// autoFlowVC will start with Account selection screen then enter amount 
// will use wireBeneficiary that set from dashboard
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                transferType: .wire)

//#2
// autoFlowVC will start with account selection screen then enter amount 
// will use wireBeneficiary that set from dashboard and provide remark
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                transferType: .wire,
                                remark: "Transfer remark")

//#3
// autoFlowVC will start with enter amount screen, since you already pass the account.
// will use wireBeneficiary that set from dashboard and provide remark
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                account: #account#,
                                transferType: .wire,
                                remark: "Transfer remark")


//#4
// autoFlowVC will start with account selection screen, and enter amount screen will not be shown, since you already pass the amount.
// will use wireBeneficiary that set from dashboard and provide remark
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                transferType: .wire,
                                amount: 2.0 ,
                                remark: "Transfer remark")


//#5 [NOT RECOMMENDED] to pass wireBeneficiary object, but you can do it if your bussiness need it 
// autoFlowVC will start with account selection screen, and enter amount screen will not be shown, since you already pass the amount.
// will use wireBeneficiary that set from dashboard and provide remark
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                amount: 2.0,
                                wireBeneficiary: #wire_beneficiary,
                                remark: "Transfer remark")



// After choose the way you want to initialize autoFlowVC, presnet it.
self.present(autoFlowVC, animated: true)
DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
DAPIAutoFlowVC *autoflow = [[DAPIAutoFlowVC alloc] initWithBankConnection:connection
                                                                  account:account
                                                          wireBeneficiary:wireBeneficiary
                                                              beneficiary:nil
                                                             transferType:DAPITransferTypeWire
                                                                   amount:100
                                                                   remark:@"remark"];
[self presentViewController:autoflow animated:YES completion:nil];

AutoFlow Result Handling

You can handle transfer results using delegate autoFlowDelegate or closures transferDidFail and transferDidSucceed

let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                transferType: .wire)

//closures fired when transfer failed 
autoFlowVC.transferDidFail = { error in 
    print(error.dapiMetaData)
    print(error.dapiErrorMessage)
}

//closures fired when transfer succeeded
autoFlowVC.transferDidSucceed = { transfer in 
    print(transfer.operationID)
    print(transfer.referenceNumber)
    print(transfer.remark)
}

self.present(autoFlowVC, animated: true)
DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
DAPIAutoFlowVC *autoflow = [[DAPIAutoFlowVC alloc] initWithBankConnection:connection
                                                                  account:account
                                                          wireBeneficiary:wireBeneficiary
                                                              beneficiary:nil
                                                             transferType:DAPITransferTypeWire
                                                                   amount:100
                                                                   remark:@"remark"];
[autoflow setTransferDidSucceed:^(DAPITransferResult * _Nonnull data) {
    NSLog(@"[DAPI] Success: data %@", data.dictionaryRepresentation);
    
}];
[autoflow setTransferDidFail:^(NSError  * _Nonnull error ) {
    NSLog(@"[DAPI] error: data %@",error.dapiOperationID);
    NSLog(@"[DAPI] type: data %@",error.dapiErrorType);
    NSLog(@"[DAPI] code: data %@",error.dapiStatusCode);
    NSLog(@"[DAPI] code: data %@",error.dictionaryRepresentation);
    NSDictionary *coolDownPeriod = [error.dictionaryRepresentation objectForKey:@"coolDownPeriod"];
    NSNumber *value = [coolDownPeriod objectForKey:@"value"];
    NSString *unit = [coolDownPeriod objectForKey:@"unit"];
    
}];
[self presentViewController:autoflow animated:YES completion:nil];

Complete Example using autoFlowDelegate

let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                transferType: .wire)

autoFlowVC.autoFlowDelegate = self
self.present(autoFlowVC, animated: true)
--------------------------------------------------------------------------------------

extension ViewController: DAPIAutoFlowDelegate {

    func autoFlow(_ autoFlow: DAPIAutoFlowVC,
                  willTransferAmount amount: Float,
                  fromAccount senderAccount: DAPIBankAccount) {
        print(#function)

    }

    func autoFlow(_ autoFlow: DAPIAutoFlowVC,
                  transferDidFailFrom senderAccount: DAPIBankAccount?,
                  to wireBeneficiary: DAPIWireBeneficiary?,
                  with error: Error) {
        print(error.dapiErrorMessage)
        print(error.dapiErrorMessage)


    }

    func autoFlow(_ autoFlow: DAPIAutoFlowVC,
                  transferDidSuccessFrom senderAccount: DAPIBankAccount,
                  transferResult: DAPITransferResult) {
        print(transferResult.referenceNumber)
        print(transferResult.remark)
        print(transferResult.operationID)
    }

    func autoFlowUserDidCanceled(_ autoFlow: DAPIAutoFlowVC) {
        print(#function)

    }
}
DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
DAPIAutoFlowVC *autoflow = [[DAPIAutoFlowVC alloc] initWithBankConnection:connection
                                                                  account:account
                                                          wireBeneficiary:wireBeneficiary
                                                              beneficiary:nil
                                                             transferType:DAPITransferTypeWire
                                                                   amount:100
                                                                   remark:@"remark"];

[autoflow setAutoFlowDelegate:self];
[self presentViewController:autoflow animated:YES completion:nil];
-------------------------------------------------------------------------------------

- (void)autoFlow:(DAPIAutoFlowVC * _Nonnull)autoFlow
willTransferAmount:(float)amount
     fromAccount:(DAPIBankAccount * _Nonnull)senderAccount {
    NSLog(@"willTransferAmount: amount %f", amount);
    NSLog(@"willTransferAmount senderAccount %@", senderAccount);
}

- (void)autoFlow:(DAPIAutoFlowVC * _Nonnull)autoFlow
transferDidSuccessFrom:(DAPIBankAccount * _Nonnull)senderAccount
  transferResult:(DAPITransferResult * _Nonnull)transferResult {
    NSLog(@"transferDidSuccessFrom: amount error %@", transferResult);
    NSLog(@"transferDidSuccessFrom senderAccount %@", senderAccount);
    
}

- (void)autoFlow:(DAPIAutoFlowVC *)autoFlow
transferDidFailFrom:(DAPIBankAccount *)senderAccount
toWireBeneficiary:(DAPIWireBeneficiary *)beneficiary
            with:(NSError *)error {
    NSLog(@"transferDidFail Error: %@", error.dapiErrorMessage);
    NSLog(@"transferDidFailFrom Account: %@", senderAccount);
    NSLog(@"transferDidFailto beneficiary: %@", beneficiary);
}

- (void)autoFlowUserDidCanceled:(DAPIAutoFlowVC * _Nonnull)autoFlow {
    NSLog(@"autoFlowUserDidCanceled");
}

Complete Visual Example

AutoFlow Transfer Without UI

Use this approach only if you don't want to use any pre-built UI elements from the SDK.

Parameters

DescriptionTypeDescription
bankConnectionDAPIBankConnection REQUIRED A connection to the bank that will be used to call APIs upon. The connection will include details about the bank. Check How To Create Bank Connection
senderBankAccountDAPIBankAccount
REQUIRED
Account where the amount must be transferred from.
receiverBeneficiaryDAPIWireBeneficiary?
OPTIONAL
WireBeneficiary that will receive the money.
If you are accepting a transfer into your own company's account, you don't need to set the parameter. You can simply add one in your dashboard under your app. The beneficiary will automatically be set to that account from there .
amountFloat
REQUIRED
Amount to be transferred.
remarkString?
OPTIONAL
This is the id you can use to track the transaction.

Response
Check Create Wire Transfer Response

Example

Dapi.shared.createWireTransfer(bankConnection: connection,
                               senderBankAccount: #sender_account#,
                               receiverBeneficiary: #wire_receiver_beneficiary#,
                               amount: 12.0,
                               remark: "Test") { results in
    switch results {
    case .success(let response):
      print(response)
    case .failure(let error):
      print(error.dapiErrorMessage)
      print(error.dapiErrorMessage)
    }
}
DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts

[Dapi.shared createWireTransferWithBankConnection:connection
                              senderBankAccountID:accountID
                              receiverBeneficiary:wireBeneficiary
                                           amount:100
                                           remark:@"remark"
                                       completion:^(DAPITransferResult * _Nullable transferData, NSError * _Nullable error) {
}];

No AutoFlow approach

❗️

If you do not use AutoFlow you will be responsible for:

  • ⚠️ Handling wire beneficiary addition based on each bank's requirements
  • ⚠️ Handling wire beneficiary existence checks
  • ⚠️ Setting up a way to call the Accounts API to obtain the sender account information

Read more about the full flow that needs to be implemented here

Get Wire Beneficiaries

Retrieve all the wire beneficiaries from the bank account.

ParameterTypeDescription
bankConnectionDAPIBankConnection REQUIREDA connection to the bank that will be used to call APIs upon. The connection will include details about the bank. Check How To Create Bank Connection

Response
Check Get Wire Beneficiaries Response

Example

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts

Dapi.shared.bankWireBeneficiaries(bankConnection: connection) { results in
    switch results {
    case .success(let response):
      print(response)
    case .failure(let error):
      print(error.dapiErrorMessage)
    }
}
DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
[Dapi.shared bankWireBeneficiariesWithBankConnection:connection
                                          completion:^(DAPIBankWireBeneficiariesResponse * _Nullable data, NSError * _Nullable error) {
}];

Create A WireTransfer To Existing Beneficiary

Initiate a wire transfer to an already existing wire beneficiary in the bank account.

Parameters

DescriptionTypeDescription
bankConnectionDAPIBankConnection REQUIRED A connection to the bank that will be used to call APIs upon. The connection will include details about the bank. Check How To Create Bank Connection
receiverBeneficiaryIDString
REQUIRED
Account ID where the amount must be transferred from.
senderBankAccountIDString
REQUIRED
Wire Beneficiary ID that will receive the money
amountFloat?
REQUIRED
Amount to be transferred.
remarkString?
OPTIONAL
This is the id you can use to track the transaction.

Response
Check Create Wire Transfer To Exist Wire Beneficiary Response

Example

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts

Dapi.shared.createWireTransferToExistBeneficiary(bankConnection: connection,
                                                 senderBankAccountID:#senderBankAccountID#,
                                                 receiverBeneficiaryID: #receiverWireBeneficiaryID#,
                                                 amount: 12.0,
                                                 remark: "Test") { results in
    switch results {
    case .success(let response):
        print(response)
    case .failure(let error):
      print(error.dapiErrorMessage)
      print(error.dapiErrorMessage)
    }
}
DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
[Dapi.shared createWireTransferToExistBeneficiaryWithBankConnection:connection
                                                senderBankAccountID:accountID
                                              receiverBeneficiaryID:beneficiaryID
                                                             amount:100
                                                             remark:@"remark"
                                                         completion:^(DAPITransferResult * _Nullable transferData, NSError * _Nullable error) {
}];

Create Wire Beneficiary

Create a wire beneficiary

ParameterTypeDescription
bankConnectionDAPIBankConnection REQUIREDA connection to the bank that will be used to call APIs upon. The connection will include details about the bank. Check How To Create Bank Connection
beneficiaryDetailsDAPIWireBeneficiary
REQUIRED
Wire Beneficiary to be created.

Response
Check Create Wire Beneficiary Response

Example

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
var dapiWireBeneficiary: DAPIWireBeneficiary {
    var lineAddress = DAPILineAddress()
    lineAddress.line1 = "2400 bruce street UCA stadium 
    lineAddress.line2 = ""
    lineAddress.line3 = ""
    var beneficiary =  DAPIWireBeneficiary()
    beneficiary.linesAddress =  lineAddress
    beneficiary.accountNumber = "1234567654321" //no special characters
    beneficiary.name = "TestAccount"//no special characters
    beneficiary.country = "US"//no special characters
    beneficiary.receiverType = "retail"//no special characters
    beneficiary.routingNumber = "953349354"//no special characters
    beneficiary.nickname = "JohnDoe"//no special characters
    beneficiary.receiverAccountType = "checking"//no special characters
    beneficiary.firstName = "John"//no special characters
    beneficiary.lastName = "Doe"//no special characters
    beneficiary.zipCode = "72305"//no special characters
    beneficiary.state = "Arkansas"//no special characters
    beneficiary.city = "Conway" //no special characters
    return beneficiary
}

Dapi.shared.createWireBeneficiary(bankConnection: connection,
                                  beneficiaryDetails: dapiWireBeneficiary) { results in
    switch results {
    case .success(let response):
        print(response)
    case .failure(let error):
        print(error.dapiErrorMessage)
        print(error.dapiMetaData)

      
    }
}
DAPIWireBeneficiary *beneficiary = [[DAPIWireBeneficiary alloc] init];
DAPILineAddress *lineAddress = [[DAPILineAddress alloc] init];
lineAddress.line1 = @"baniyas road";
lineAddress.line2 = @"dubai";
lineAddress.line3 = @"united arab emirates";
beneficiary.linesAddress =  lineAddress;
beneficiary.accountNumber = @"1647262785195476117137";
beneficiary.name = @"TestAccount";
beneficiary.country = @"US";
beneficiary.receiverType = @"retail";
beneficiary.routingNumber = @"953349354";
beneficiary.nickname = @"JohnDoe";
beneficiary.receiverAccountType = @"checking";
beneficiary.firstName = @"John";
beneficiary.lastName = @"Doe";
beneficiary.zipCode = @"72305";
beneficiary.state = @"Arkansas";
beneficiary.city = @"Conway";

DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
[Dapi.shared createWireBeneficiaryWithBankConnection:connection
                                  beneficiaryDetails:beneficiary
                                          completion:^(DAPIResponseResult * _Nullable data, NSError * _Nullable error) {
}];