iOS Deep Linking Integration
Prerequisites
Before you get started with your implementation, read the integration overview to learn about integration and required configuration.
You are onboarded to our sandbox enviroment as a merchant and has a valid TPN.
Setup Testing Environment
- Install Xcode (opens in a new tab)
Before setting up the testing device
-
Use a separate device for testing.
-
Only use the credentials given to you throughout the testing process.
To get sandbox credentials, contact support@dejavoosystems.com
-
Avoid changing the account during testing.
-
Don't change the device's date and time.
-
These rules apply only to the testing environment, not production.
Watch this video for a visual walkthrough of the steps
To Develop iOS Application, Create a new iOS project or use the existing project and configure the below app setup.
Initially, we will use the new TPN. You must accept the Apple Tap-on-Phone Terms and Conditions before proceeding with the Tap-on-Pay transaction.
Supported Device's & version's
- OS Version Above 16.9
- Tap to Pay on iPhone requires iPhone Xs or later.
Configure the URL Scheme
Keys demo-AppLink
and iPosgo-AppLink
are case sensitive.
- Demo App Setup
- iPosGo! Setup
- Configure the SDK
Install the Applications
To install Demo App and iPosGo!! Application via link. I’ll create a diawi Link for testing purposes using this url to obtain the UDID for your device. I can now share the source file of the Demo application so that you can see how it is implemented.
https://get.udid.io/ (opens in a new tab)
TPN Register
TPN register is used to download the parameters to configure the merchant configuration data from the backend application portal.
Watch this video for a visual walkthrough of the steps.
Input Request Parameters:
Field | Type | Description | Example |
---|---|---|---|
tpn * | string | It’s a Unique 12-digit code. This value is unique for each merchant. | 123456789012 |
applicationType | string | The application type is used to identify the application | "IPosGo!" |
- To access the SDK Reader wrapper class, import DeepLinking, and initiate an instance of the class as follows:
import DeepLinking
- Create a variable to access the methods
var deepLinkVariable = Wrapper()
- Access
makeARequestBasedOnTPN()
ondeepLinkVariable
deepLinkVariable.makeARequestBasedOnTPN(tpnNo: tpn, delegate: self)
- Below snippet helps to make a connection between the iPosGo! and Demo App.
func didReceiveResponse(sucess success: URL?) {
if UIApplication.shared.canOpenURL(success!) {
UIApplication.shared.open(success!, options: [:]) { result in
print(result)
}
}
else {
print("App Not Installed in the Device!")
}
}
Perform Transactions
This api is used to Demo application to perform the transaction. It supports SALE, REFUND, VOID, PRE-AUTH & TICKET transaction types.
Watch this video for a visual walkthrough of the steps.
1. SALE, REFUND, PREAUTH
Input Request Parameters:
Field | Type | Description | Example |
---|---|---|---|
type * | string | Transaction type [SALE, REFUND, PREAUTH] | sale |
amount * | string | Transaction Amount | 10.00 |
- Access
makeARequestBasedOnTransactionTypes()
ondeepLinkVariable
deepLinkVariable.makeARequestBasedOnTransactionTypes(type: Type, Amount: Amount, delegate: self)
- Below snippet helps to make a
sale
transaction.
func didReceiveResponse(success: URL?) {
if UIApplication.shared.canOpenURL(success!) {
UIApplication.shared.open(success!, options: [:]) { result in
print(result)
}
}
else {
txtResponse.text = ""
showAlert(alertMessage: "App Not Installed in the Device!")
}
}
2. VOID, TICKET
Input Request Parameters:
Field | Type | Description | Example |
---|---|---|---|
type * | string | Transaction type [VOID, TICKET] | ticket |
rrn * | string | Its Unique identifier to track the transaction from TXN response | 1234567890 |
- Access
makeARequestBasedOnTransactionTypes()
ondeepLinkVariable
deepLinkVariable.makeARequestBasedOnTransactionTypes(type: Type, Amount: rrn, delegate: self)
- Below snippet helps to make a
void
transaction.
func didReceiveResponse(success: URL?) {
if UIApplication.shared.canOpenURL(success!) {
UIApplication.shared.open(success!, options: [:]) { result in
print(result)
}
}
else {
txtResponse.text = ""
showAlert(alertMessage: "App Not Installed in the Device!")
}
}
3. BATCH
InputRequest Parameters:
Field | Type | Description | Example |
---|---|---|---|
type * | string | Transaction type [BATCH/ SETTLEMENTS] | batch |
amount | string | Transaction Amount | "" |
- Access
makeARequestBasedOnTransactionTypes()
ondeepLinkVariable
deepLinkVariable.makeARequestBasedOnTransactionTypes(type: Type, Amount :"", delegate: self)
- Below snippet helps to make a
batch
settlement.
func didReceiveResponse(success: URL?) {
if UIApplication.shared.canOpenURL(success!) {
UIApplication.shared.open(success!, options: [:]) { result in
print(result)
}
}
else {
txtResponse.text = ""
showAlert(alertMessage: "App Not Installed in the Device!")
}
}
Transaction Response
iPosGo! Call back the result in Demo like this. You can fetch the details.
{
{
[
"Card": { AID = A000000025010801; Label = AMEX; MaskedPan = 3767522012; },
"BaseAmt": ["Amt": "100", "Label": "Amount"],
"TxDetail": {DateNTime = 20240515191215; Tpn = 544424127175; TraceNo = 1; },
"BaseFee": ["Amt": "5", "Label": "BaseFee"],
"Tax2": ["Amt": "21", "Label": "Tax2"],
"surveyAns": "1", "Currency": "840",
"Tip": ["Amt": "20", "Label": "Tip"],
"Tax1": ["Amt": "11", "Label": "Tax1"],
"Response": {
AppCode = AXS802;
BatchNo = 63;
CardType = CREDIT;
DTxId = 03430717348412717520240515191215;
HTxId = 000000321000803;
InvoiceNo = 5;
RespCode = 00;
RespMsg = "APPROVAL AXS802 ";
Rrn = 413613500098;
TxRefNo = 034307173484;
}
]
"Date" : "03.09.2023"
}
}
Payment Session Errors
enum PaymentSessionError: String {
case notAllowed = "Account not allowed."
case backgroundRequestNotAllowed = "Background request not allowed."
case unsupported = "Unsupported hardware or a problem with the device"
case osVersionNotSupported = "Please update your app to the latest iOS version."
case modelNotSupported = "Current device doesn't support NFC."
case networkError = "Please check your network settings and try again."
case networkAuthenticationError = "An authentication error occurred during the server connection."
case serviceConnectionError = "Internal service is unavailable."
case notReady = "Please try the session again to resolve the issue."
case emptyReaderToken = "The token is empty, making it invalid."
case prepareExpired = "Please reinitiate the session to try again"
case tokenExpired = "Token Expired."
case readerMemoryFull = "The card reader is busy."
case accountNotLinked = "Accept the Terms and Conditions using a valid Apple ID."
case accountAlreadyLinked = "Terms and Conditions have already been accepted."
case accountLinkingFailed = "The system couldn't link or relink the merchant using the provided Apple ID."
case accountLinkingRequiresiCloudSignIn = "Please accept the Terms and Conditions on your device while signed into iCloud"
case accountLinkingCancelled = "The linking or relinking operation has been canceled."
case merchantBlocked = "The merchant is blocked"
case invalidMerchant = "The merchant is invalid or unknown"
case somethingWentWrong = ""
}
Card Reader Session Errors
enum CardReaderSessionError: String {
case cardReadFailed = "The reader was unable to read a card"
case invalidAmount = "Amount must be positive and contain less than 10 digits."
case invalidCurrencyCode = "Currency code in the request must follow the ISO 4217 standard."
case nfcDisabled = "The user needs to enable their NFC"
case noReaderSession = "No reader session is available or the session isn't ready."
case passcodeDisabled = "Passcode disabled. Please set a security passcode on your device."
case paymentCardDeclined = "The payment card declined the transaction."
case paymentReadFailed = "An internal failure prevented the read operation."
case pinCancelled = "The current PIN capture was canceled, thereby canceling any ongoing read operation."
case pinNotAllowed = "The time window for capturing a PIN after a card read has expired."
case pinEntryFailed = "An error occurred when capturing the PIN."
case pinEntryTimeout = "The ongoing PIN capture was not completed within the given time."
case pinTokenInvalid = "An error that indicates an invalid PIN token."
case readFromBackgroundError = "Read operations aren't allowed when an app is running in the background."
case readNotAllowed = "This error usually occurs when there's an entitlement issue."
case readNotAllowedDuringCall = "Read operations aren't allowed during a phone call."
case readerServiceConnectionError = "The session wasn't able to connect the system UI or other services"
case readerServiceError = "Reader service internal state issue occurred."
case readerSessionAuthenticationError = "An authentication error occurred while refreshing reader session"
case readerSessionBusy = "The reader is busy with another session."
case readerSessionExpired = "The reader session expired and couldn't refresh due to other state changes."
case readerSessionNetworkError = "Network error occurred that prevented a reader session refresh."
case readerTokenExpired = "The configuration token for the reader session expired."
case vasReadFail = "Error occurred when reading a loyalty pass."
case invalidReaderToken = "Invalid reader token"
case prepareFailed = "Prepare session failed"
}
Custom error messages
enum CustomErrorMessage: String {
case entitlementIssue = "Please check the tap on phone entitlement configuration."
case environmentIssue = "The token key environment is not acceptable."
case deviceSupportTapOnPay = "Device Supports Tap to Pay"
case deviceUnSupportTapOnPay = "Your current device does not support NFC."
case readerSessionCleanUp = "Reader session cleaned up"
}
Transaction Response Details:
Field | Type | Description | Example |
---|---|---|---|
Rrn * | string | It’s a Unique code. Just to tracks the TXN status | 123456789012 |
DTxId * | string | It’s a Unique code.Its TXN hash key | 39676826774069372420240510183738 |
Label * | string | Its Card type | VISA, AMEX |
MaskedPan * | string | Last few digit of card number | 3767522012 |
DateNTime * | string | TXN date and time | 20240515191215 |
Tpn * | string | Device unique Identifier | 544424127175 |
TraceNo * | string | Its unique code to track the TXN | 1 |
CardType * | string | Card type of the TXN | CREDIT / DEBIT |
HTxId * | string | It’s a Unique code. Just to tracks the TXN’s | 000000321000803 |
TxRefNo * | string | It’s a Unique code. Just to tracks the TXN’s | 034307173484 |
DateNTime * | string | It’s specify the date and time on TXN’s | 20240515191215 |
AppCode * | string | It’s a unique code | AXS802 |
RespCode * | string | It’s a unique code to represent a success data | 00 |
RespMsg * | string | It’s a response message for success | APPROVAL AXS802 |
BatchNo * | string | 63 | |
InvoiceNo * | string | 5 | |
AID * | string | A000000025010801 | |
Amt | string | It’s a base amount | 5.00 |
Label | string | Amount | |
Tax2 Amt | string | It’s an amount of State Tax | 21 |
Tax2 Label | string | Tax2 | |
Tax1 Amt | string | It’s an amount of Local Tax | 11 |
Tax1 Label | string | Tax1 | |
Tip Amt | string | It’s an amount of given by the Tip | 20 |
Tip Label | string | Tip | |
Fee Amt | string | It’s an amount of given by the mentioned Fee | 9 |
Fee Label | string | Custom Fee | |
surveyAns | string | 1 | |
Currency | string | It’s a currency code | 840 |
Video For Reference
iPOSgo! Deep Linking Demo Video.
support
Email us directly at devsupport@denovosystem.com with any questions or suggestions.
FAQ
- What is a TPN?
A Terminal Profile Number (TPN) is a special code given to a payment terminal or POS device. It helps payment solution providers recognize and set up the terminal’s specific features and abilities.
- Which iPhones and operating systems are compatible for Tap to Pay on iPhone?
Tap to Pay on iPhone requires iPhone XS or later, and the latest version of iOS. Update to the latest iOS here: https://support.apple.com/en-ca/HT204204 (opens in a new tab)
- How do I know if the customer’s payment card is contactless?
The front or back of contactless cards have an EMV® Contactless Indicator.
- Does Tap to Pay on iPhone work on an iPad?
Tap to Pay on iPhone is only available on an iPhone.
- What if a customer does not have a contactless card?
In cases where the customer does not have a contactless card during the transaction, the merchant has the option to present a QR code and request the customer scan it using their smartphone and manually enter their card details.
- What best practices can help prevent "invalid reader token" error?
A: If the JWT token has expired, it throws an error. In case TPN accepts the terms and conditions on another device, this occurs.
- In development mode on the UAT version, what type of Apple account should I be logged into on my testing device?
A: Using a UAT version, you can use a Sandbox Account on your testing device to proceed.
- Why does the app crash when importing our SDK?
A: As mentioned in our integration documentation, after dragging and dropping our SDK into your project, you must enable the "Embed & Sign" in Xcode’s general settings.
- How can they resolve the integrity error that appears when trying to install the app?
A: As mentioned in our integration documentation, you can provide UDIDs for testing the devices to resolve this issue.
- How do I start the Integration Process ?
A: Please should go through our integration documentation and contact your Dejavoo representative to guide you throughout the process.