Changelog

Payment API

Payment API provides all the functionality required to manage 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 beneficiaries - Retrieve beneficiaries from the bank account.
  • [Not required when using Autoflow] Create Beneficiary - Create a beneficiary into the bank account.
  • [Not required when using Autoflow] Create Transfer - Initiate a transfer to an existing beneficiary only.

Dapi AutoFlow Transfer [Recommended]

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

Using Dapi AutoFlow you can easily create a 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
accountDAPIBankAccount?
OPTIONAL
Sender account where the amount must be transferred from.
If you don't provide it, AutoFlow will display bank account selection screen for your user to pick the account.
beneficiaryDAPIBeneficiary?
OPTIONAL
Beneficiary that will receive the amount.
If in your use case the beneficiary is a constant, you can set the beneficiary on the Dapi Dashboard. It will be automatically used during a transfer by Dapi system.
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.
remarkString?
OPTIONAL
Unique ID generated by your application. Can be used to track the transfer during settlement.

NB! No special characters allowed

❗️

How to set beneficiary details?

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


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

  • Option 2: Set the beneficiary as the DAPIBeneficiary object in the SDK function call
    • ✅ Works for both dynamic and static beneficiaries.
    • ⚠️ You should be double-checking the 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 beneficiary details only in the SDK Backend Server (in principle the same as Option 2)
    • ✅ Works for both dynamic and static beneficiaries.
    • ✅ You never have to expose the beneficiary details to the front-end layer.
    • ✅ You want your backend to be in full control of the beneficiary details.
    • ⚠️ Don't recommend for static beneficiary use cases, since it would be unnecessary additional development work on the Backend Server Side.


AutoFlow Examples for Different Use Cases

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

//#1
// autoFlowVC will start with the Account selection screen then enter the amount 
// will use the beneficiary that set from the dashboard
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection)

//#2
// autoFlowVC will start with the account selection screen and then enter the amount 
// will use the beneficiary that set from the dashboard and the provided remark
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                remark: "Transfer remark")

//#3
// autoFlowVC will start with entering the amount screen since you already pass the account
// will use the beneficiary that set from the dashboard and the provided remark
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                        account: #account#,
                                        remark: "Transfer remark")


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


//#5 
// autoFlowVC will start with the account selection screen, and enter amount screen will not be shown, since you already pass the amount.
// will use the beneficiary that is set in the #beneficiary object
//[REOMMENDATION] If you use this approach, make sure to double-check the integrity of beneficiary details in the SDK Backend Server
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection,
                                amount: 2.0,
                                beneficiary: #beneficiary,
                                remark: "Transfer remark")

// After you choose the way you want to initialize autoFlowVC, present 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:nil
                                                              beneficiary:beneficiary
                                                             transferType:DAPITransferTypeNormal
                                                                   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 connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection)

//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:nil
                                                              beneficiary:beneficiary
                                                             transferType:DAPITransferTypeNormal
                                                                   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 autoFlowDelegate

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
let autoFlowVC = DAPIAutoFlowVC(bankConnection: connection)
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 beneficiary: DAPIBeneficiary?,
                  with error: Error) {
        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:nil
                                                              beneficiary:beneficiary
                                                             transferType:DAPITransferTypeNormal
                                                                   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
              to:(DAPIBeneficiary *)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.
receiverBeneficiaryDAPIBeneficiary?
OPTIONAL
Beneficiary that will receive the amount.
Beneficiary that will receive the amount.
If in your use case the beneficiary is a constant, you can set the beneficiary on the Dapi Dashboard. It will be automatically used during a transfer by Dapi system.
amountFloat
REQUIRED
Amount to be transferred.
remarkString?
OPTIONAL
Unique ID generated by your application. Can be used to track the transfer during settlement.

NB! No special characters allowed

Response
Check Create Transfer Response

Example

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
Dapi.shared.createTransfer(bankConnection: connection,
                           senderBankAccount: #sender_account#,
                           receiverBeneficiary: #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 createTransferWithBankConnection:connection
                          senderBankAccountID:accountID
                          receiverBeneficiary:beneficiary
                                       amount:100
                                       remark:@"remark"
                                   completion:^(DAPITransferResult * _Nullable transferData, NSError * _Nullable error) {
    NSLog(@"[DAPI] Success: %@",transferData);
    NSLog(@"[DAPI] Error: %@", error.dapiErrorMessage);
    
}];

No AutoFlow approach

❗️

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

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

Get Beneficiaries

Retrieve all the 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 Beneficiaries Response

Example

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
Dapi.shared.bankBeneficiaries(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 bankBeneficiariesWithBankConnection:[self selectedConnection]
                                      completion:^(DAPIBankBeneficiariesResponse * _Nullable response, NSError * _Nullable error) {
    NSLog(@"[DAPI] Success: %@",response);
    NSLog(@"[DAPI] Error: %@", error.dapiErrorMessage);
}];

Create A Transfer To Existing Beneficiary

Initiate a transfer to an already existing 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
Beneficiary ID that will receive the amount. Obtained from calling the Get Beneficiaries function.
senderBankAccountIDString
REQUIRED
Account ID where the amount must be transferred from. Obtained from calling the Accounts information
amountFloat?
REQUIRED
Amount to be transferred.
remarkString?
OPTIONAL
Unique ID generated by your application. Can be used to track the transfer during settlement.

NB! No special characters allowed

Response
Check Create Transfer To Exist Beneficiary Response

Example

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
Dapi.shared.createTransferToExistBeneficiary(bankConnection: connection,
                                             senderBankAccountID:#senderBankAccountID#,
                                             receiverBeneficiaryID: #receiverBeneficiaryID#,
                                             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 createTransferToExistBeneficiaryWithBankConnection:connection
                                            senderBankAccountID:accountID
 																						receiverBeneficiaryID:beneficiaryID
                                            amount:100
                                            remark:@"remark"
                                            completion:^(DAPITransferResult * _Nullable response, NSError * _Nullable error) {
                                           
    NSLog(@"[DAPI] Success: %@",response);
    NSLog(@"[DAPI] Error: %@", error.dapiErrorMessage);

}];

Create Beneficiary

Create a 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
beneficiaryDAPIBeneficiary
REQUIRED
Beneficiary to be created.

Response
Check Create Beneficiary Response

Example

var beneficiary: DAPIBeneficiary {
    var lineAddress = DAPILineAddress()
    lineAddress.line1 = "Reem Island" 
    lineAddress.line2 = "Abu Dhabi"
    lineAddress.line3 = "UAE"
    var beneficiary =  DAPIBeneficiary()
    beneficiary.linesAddress =  lineAddress
    beneficiary.accountNumber = "1647518280840289401662" //no special characters
    beneficiary.bankName = "STANDARD CHARTERED BANK" //no special characters
    beneficiary.swiftCode = "SCBLAEAD" //no special characters
    beneficiary.iban = "DAPIBANKAEHSBC1647518280840289401662" //no special characters
    beneficiary.country = "AE" //Alpha-2 country code
    beneficiary.branchAddress = "Dubai Mall" //no special characters
    beneficiary.branchName = "Dubai Mall"//no special characters
    beneficiary.phoneNumber = "0585859206" //no special characters
    beneficiary.name = "Magdy Saad Zamel" //no special characters
    return beneficiary
}

let connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
Dapi.shared.createBeneficiary(bankConnection: connection,
                              beneficiaryDetails: dapiBeneficiary) { results in
    switch results {
    case .success(let response):
        print(response)
    case .failure(let error):
        print(error.dapiErrorMessage)
        print(error.dapiMetaData)

      
    }
}
DAPIBeneficiary *beneficiary = [[DAPIBeneficiary alloc] init];
DAPILineAddress *lineAddress = [[DAPILineAddress alloc] init];
lineAddress.line1 = @"baniyas road";
lineAddress.line2 = @"dubai";
lineAddress.line3 = @"united arab emirates";
beneficiary.linesAddress =  lineAddress;
beneficiary.accountNumber = @"1656643155846781425823";
beneficiary.bankName = @"STANDARD CHARTERED BANK";
beneficiary.swiftCode = @"SCBLAEAD";
beneficiary.iban = @"DAPIBANKAEADIB1656643155846781425823";
beneficiary.country = @"AE";
beneficiary.branchAddress = @"Dubai Mall";
beneficiary.branchName = @"Dubai Mall";
beneficiary.phoneNumber = @"432789122";
beneficiary.name = @"Test";

DAPIBankConnection *connection = ... // selectedConnection or use Dapi.shared.connections to get cashed accounts
[Dapi.shared createBeneficiaryWithBankConnection:connection
                              beneficiaryDetails:beneficiary
                                      completion:^(DAPIResponseResult * _Nullable result, NSError * _Nullable error) {
    NSLog(@"[DAPI] Success: %@",result);
    NSLog(@"[DAPI] Error: %@", error.dapiErrorMessage);
}];