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
Description | Type | Description |
---|---|---|
bankConnection | DAPIBankConnection 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 |
account | DAPIBankAccount? 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. |
beneficiary | DAPIBeneficiary? 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. |
amount | Float? 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. |
remark | String? 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
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
Description | Type | Description |
---|---|---|
bankConnection | DAPIBankConnection 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 |
senderBankAccount | DAPIBankAccount REQUIRED | Account where the amount must be transferred from. |
receiverBeneficiary | DAPIBeneficiary? 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. |
amount | Float REQUIRED | Amount to be transferred. |
remark | String? 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.
Parameter | Type | Description |
---|---|---|
bankConnection | DAPIBankConnection 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 |
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
Description | Type | Description |
---|---|---|
bankConnection | DAPIBankConnection 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 |
receiverBeneficiaryID | String REQUIRED | Beneficiary ID that will receive the amount. Obtained from calling the Get Beneficiaries function. |
senderBankAccountID | String REQUIRED | Account ID where the amount must be transferred from. Obtained from calling the Accounts information |
amount | Float? REQUIRED | Amount to be transferred. |
remark | String? 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
Parameter | Type | Description |
---|---|---|
bankConnection | DAPIBankConnection 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 |
beneficiary | DAPIBeneficiary 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);
}];
Updated about 1 year ago