Skip to content

    SDK overview

    Get started

    This integration leverages the OAuth 2.0 protocol to enable secure and seamless authentication between two applications. OAuth 2.0 is an industry-standard authorization framework designed for secure delegated access to resources.

    The SDK iOS leverage on Cloud-Authentication which needs web portal set up, check the following section: https://developer.nexigroup.com/softposmobilepos/en-EU/docs/web-portal-configuration/

    SDK IOS PROCESS IMAGE

    Below is the flow diagram that explains in detail the interaction of the SDK to be integrated into the merchant app and how the Enrollment flow is handled for backend authentication

    sdkiosdiagram v4

    Project set up

    The project involves the use of two different types of libraries:

    Downloadable via CocoaPods/JFrog Artifactory:

    • App2AppSDK
    • SoftPOS

    Downloadable via SPM (Swift Package Manager):

    • Alamofire
    • SwiftyJSON
    • SwiftyBeaver
    • Swift-JWT

    Library Retrieval and Installation Phase

    CocoaPods/JFrog Artifactory

    Before downloading the libraries, you must obtain credentials to access the repository at [https://artifactory.nexicloud.it/ui/login/]

    Ask to supporto.development@nexigroup.com to receive credentials

    You will then need to install the cocoapods-art plugin, which allows you to integrate JFrog Artifactory as a dependency manager.

    Open the terminal and enter the following command:

    code

    gem install cocoapods-art

    STEP 1

    Select Artifacts and the libs-nexi-pos-a2a-ios-release

    jfrog1

    STEP 2

    Select the SET ME UP option

    jfrog2

    STEP 3

    Insert the log in password

    jfrog3

    STEP 4

    At this point, by scrolling down in the panel, the authentication credentials to be entered in the .netrc file on your computer are displayed:

    machine artifactory.nexicloud.it

    login mario.rossi

    password PWDAPWDPWDPWDPWDPWD

    The command to be executed in the terminal to add the repository to the computer’s CocoaPods configuration is:

    code

    *pod repo-art add libs-nexi-pos-a2a-ios-release "https://artifactory.nexicloud.it/artifactory/api/pods/libs-nexi-pos-a2a-ios-release"*

    JFROG4

    STEP 5

    Then, access the main directory of your computer from the terminal. Type the command ls -las and check for the presence of the .netrc file. If the file is not present, it needs to be created and then opened. For example, from the terminal, you can use the following command:

    code

    *nano ~/.zshrc*

    JFROG5

    STEP 6

    Copy the credentials previously retrieved from the JFrog portal into the file. Save and exit the editor (CTRL + X, then press Y when prompted to save).

    JFROG6

    code

    pod repo-art add libs-nexi-pos-a2a-ios-release "https://artifactory.nexicloud.it/artifactory/api/pods/libs-nexi-pos-a2a-ios-release"

    The repository will be added and made available as a source from which to download the required libraries. In the following pages, the procedure for installing the SDK libraries in an Xcode project will be explained. This will be done using the pod install command, which will retrieve the SDK libraries from the previously added repository.

    Prerequisites and Project set up

    • A paid Apple Developer Account
    • An Apple Sandbox Account

    setup

    **Tap to pay Capability Enablement

    Follow the instructions provided later in this document.

    Once the iPhone setup is completed, the developer can proceed with the development phase.

    T2P

    Set the Minimum Deployment Target to iOS 16.4.

    Immagine2

    Add the following packages to the project:

    github.com/Alamofire/Alamofire.git

    github.com/SwiftyJSON/SwiftyJSON

    github.com/SwiftyBeaver/SwiftyBeaver.git

    github.com/Kitura/Swift-JWT

    Note: Do NOT integrate AlamofireDynamic when prompted by Xcode.

    1. In Xcode, go to File → Add Package Dependencies, then insert the GitHub URLs above to download the libraries.
    2. The developer has to hadd the github url to download libreries in the finder bar
    3. Once completed, all libraries will be correctly added to the project

    Immagine3

    Immagine4

    When the developer adds Alamofire, must not add AlamoFireDynamic (set “Add to Target” on None)

    Immagine5

    Libraries have been added to the project

    Immagine6

    Now, install the SDK using CocoaPods.

    Open Finder, navigate to your project folder, and open Terminal there.

    Immagine7

    Immagine8

    Type the following command:

    code

    pod init

    Immagine9

    The Podfile will be created.

    Open the Podfile and paste the following content (make sure to insert the correct target name, as specified in your Xcode project, e.g. sdk-ios-swiftui01):

    code

    source 'https://github.com/CocoaPods/Specs.git
    '
    
    platform :ios, '16.4'
    
    plugin 'cocoapods-art', :sources => [
    'libs-nexi-pos-a2a-ios-release'
    ]
    
    def shared_pods
    
    pod 'App2AppSDK', '1.0.2'
    pod 'Softpos', '1.0.71'
    
    end
    
    target 'sdk-ios-swiftui01' do
    use_frameworks!
    
    shared_pods
    end
    
    post_install do |installer|
    installer.pods_project.targets.each do |target|
    if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
    target.build_configurations.each do |config|
    config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
    config.build_settings["IPHONEOS_DEPLOYMENT_TARGET"] = "16.4"
    end
    end
    end
    end

    Then type:

    code

    pod install

    Once the installation completes successfully, the Pods are integrated into your project.

    Immagine10

    Immagine11

    During the first build, you might encounter the following error.

    To fix it, open Build Settings and set: User Script Sandboxing = NO

    Immagine12

    To fix it, open Build Settings and set: User Script Sandboxing = NO

    Immagine13

    Once your app appears on the Apple Developer portal, go to the App ID configuration section and enable the Tap to Pay capability.

    Immagine14

    If the provisioning support is set only to Development, the generated Distribution Provisioning Profile will not include Tap to Pay capability. You must request Apple to extend Tap to Pay functionality to the Distribution mode.

    Immagine15

    Immagine16

    Provisioning profile creation

    Immagine17

    Select iOS App Development

    Immagine18

    Select the App ID to be associated with the provisioning profile.

    Verify the Provisioning Support.

    If it is set to Development only, the distribution provisioning profile will not include the Tap to Pay entitlement.

    Request from Apple an extension of the Tap to Pay capability to the Distribution mode.

    Immagine19

    Select Certificates

    Immagine20

    Select Devices

    Immagine21

    Save

    Immagine22

    Provisioning Profile Created

    Immagine23

    Create a Distribution provisioning profile, and select App Store Connect as the distribution option.

    Immagine1x

    Select the certificate, then proceed by following the same steps described for the Development provisioning profile.

    Immagine2x

    If the Tap to Pay capability is not available, submit a request to Apple using the following form:

    https://developer.apple.com/contact/request/tap-to-pay-on-iphone/

    Technical specification

    Introduction

    The technical interaction between App2App SDK and Merchant App involves the exchange of data through defined operations. In this context:

    ● Incoming data, refers to data that App2App SDK receives from Merchant App during various operations.

    ● Outgoing data, represents the data that App2App SDK sends back to Merchant App as a result of the operations

    The scope of the interaction between the app (merchant application) and the App2App SDK is primarily related to facilitating secure and seamless payment transactions.

    Prerequisites

    First, to test the App2App SDK features (payments/refunds, etc.), you need to log in to your iPhone with an Apple Sandbox ID created for Apple Tap to Pay and use provisioning profiles with Apple Tap to Pay as an enabled feature (the Apple Sandbox ID is not used in production, only in pre-production).

    If all these requirements are not met, some exceptions that are difficult to read will be displayed when building/running the app. You then have to add the entitlements file with this key-value to the Xcode project: com.apple.developer.proximity-reader.payment.acceptance

    To integrate App2App SDK, the following requirements must be met:

    ● iOS Version: The SDK supports a minimum deployment target of iOS 16.4. Using the SDK on earlier versions is not supported.

    ● Swift Integration Only: At this time, integration is only supported in Swift-based projects. Direct usage from Objective-C is not supported.

    Please ensure your project meets these prerequisites before proceeding with the integration. This SDK can be used both UIKit and SwiftUI projects. For using App2AppSDK in your project, you have to integrate some dependency libs required from main dependency lib that is Softpos.

    These libs are:

    1. Alamofire
    2. SwiftyJSON
    3. SwiftyBeaver
    4. SwiftJWT You have to integrate them like swift packages using SPM.

    These are the url to use for adding them:

    github.com/Alamofire/Alamofire.git github.com/SwiftyJSON/SwiftyJSON github.com/SwiftyBeaver/SwiftyBeaver.git github.com/Kitura/Swift-JWT

    Operational flow

    To perform any operation, the app is required to instance the App2AppManager class, needed to send developer data and then, setup the connection to Nexi POS app.

    Init

    public init(
        appData: AppData,
        delegate: App2AppManagerSoftPosEventsDelegate,
        onGetRequestUri: @escaping (String) async throws -> String

    The App2AppManager class is responsible for setting up and handling the interaction with the App2App SDK. Hence, an instance of this class is needed before starting any operation. The class requires the following parameters:

    appData, data representing the app created by developer on web portal.

    AppData contains:

    o appId, the id of the app.

    o redirectUri, the URI chosen during app creation

    o merchantUsername, the merchant username with which any operation will be run

    o merchantId, the merchant id corresponding to the account assigned on the portal

    o domain, desired service domain among INTEGRATION, STAGING, PRODUCTION

    delegate is a protocol created to handle the various events triggered by the App2App SDK following operations such as initialization, payment, refund, receipt retrieval, and transaction list retrieval. The methods defined within it must therefore be implemented in order to handle the received data. It can be updated after the creation of the App2AppManager instance.

    onGetRequestUri (deviceId), used to verify whether the current device can be enrolled during the enrollment phase.

    Here an example of how to implement onGetRequestUri:

    OnGetRequestUri

    func onGetRequestUri(_ deviceId: String) -> String {
        var requestUri = ""
        let semaphore = DispatchSemaphore(value: 0)

    SDK APIs

    The caller app can run the following operations:

    ● Payment, using the pay method.

    ● Refund a transaction, using the refund method.

    ● Recover payment receipt, using the getPayReceipt method

    ● Recover refund receipt, using the getRefundReceipt method

    ● Recover the transaction list, using the getListTransactions method

    ● Logout MPOS account, using the logout method

    When calling any of them, the SDK will check if the device is enrolled, which implies a group of security checks have been executed on the device. The enrollment involves SDK internal calls, requesting the merchant application to provide the requestUri parameter. By passing the onGetRequestUri callback, the merchant app can prepare a specific flow to use the device id and produce the requestUri. The latter must be passed to the SDK, using the onSuccess callback, to allow the SDK to perform the enrollment.

    SDK outcome and App outcome All methods will return an outcome via operationListener, which is not the real outcome of the operation (payment, refund, payment receipt, refund receipt, transaction list, logout), but the outcome of the SDK task. In case of failure, for example, the listener will tell why the SDK operation has failed. In case of success, instead, the SDK will notify about having completed its task.

    Happy flow:

    1. App calls pay method
    2. OperationListener notifies a success (could be used for tracking or logging events)
    3. Once the payment has been completed, the result is returned via the associated operation delegate. The SDK then intercepts the event and invokes the app2AppManagerSoftPosEventsOnDidPaymentSuccess method.

    Unhappy flow:

    1. App calls pay method
    2. OperationListener notifies a failure, which can be used to show an error Outcome and threads The operationListener returns the result on a background thread, so any logic within the success or failure callbacks must be thread-safe. In particular, any UI-related operations must be executed on the main thread. To do this, the app must wrap the relevant code inside a DispatchQueue.main.async block. Failing to do so may result in unexpected behavior or runtime exceptions.Any violation of background thread rules will result into an exception.

    Enrollment

    During payment or any App2App operation, the enrollment could be requested. In case of need, the onGetRequestUri callback will be called from the SDK and the application should gather necessary params to send a network request and get a request URI from our side.

    Delegate

    The methods provided by the protocol and implemented by the delegate return information at the end of the triggered operations. During the initialization phase, the app2AppManagerSoftPosEventsOnReaderInitProgress method can be used to monitor the current initialization progress percentage.

    Name parameter : Progress

    Description: Represents the current initialization progress percentage

    Type: Int

    Mandatory: yes

    Delegate

    func app2AppManagerSoftPosEventsOnReaderInitProgress( _ progress: Int){}

    Payment The payment can be run by calling the pay method;the pay method takes an instance of PaymentData as an argument and an operationListener, which will propagate the operation outcome to the caller application. In OnSuccess callback, the exception field will contain a null value. In OnFailure callback, the exception will be filled with an A2AException instance. In case of NetworkException, the HTTP error code and reason will be sent through errorCode and errorMessage fields. For any other error, the errorMessage field will be filled with a specific error message.

    Payment

    @objc public func pay(
        paymentData: PaymentData,
        operationListener: OperationListener
    ) {}

    Payment Data

    The PaymentData is a class used for holding information related to a payment. PaymentData class properties are detailed below:

    ParameterDescriptionTypeMandatory
    ImportValueRepresents the amount of the payment in centsIntyes
    CurrencyRepresents the currency of the payment (It can be “euro” or “huf”).CurrencyEnumyes
    tagsRepresents the additional tags.[String: String]no

    Additional tags

    The payment flow can also be used to add up to five additional tags at the time of payment, if needed. An additional tag is a key-value string pair that provides supplementary information related to the transaction request.

    Delegate Payment

    The methods provided by the protocol and implemented by the delegate return information at the end of the triggered operations. At the end of the payment process, in case of success, the result can be intercepted through the app2AppManagerSoftPosEventsOnDidPaymentSuccess method. This method receives an input parameter of type App2AppSoftposTransactionResult, which contains the details of the completed transaction.

    Delegate Pyament

    func app2AppManagerSoftPosEventsOnDidPaymentSuccess(
        _ result: App2AppSoftposTransactionResult
    ) {}
    ParameterDescriptionTypeMandatory
    refusalcodeRepresents the transaction status (ex. `00` means success transaction;Stringyes
    customMessageRepresents the transaction data, in particular the KEY_TRX_IMPORT_VALUE represent the transaction amount and the KEY_TRX_CURRENCY_CODE represent the currency code[ String : String ]yes
    transactionIdRepresents the transaction id generated by NexiStringyes

    Refund

    The reversal can be run by calling the reversal method. The refund method takes an instance of RefundData as an argument and an operationListener, which will propagate the operation outcome to the caller application.

    Refund

    @objc public func refund(
        refundData: RefundData,
        operationListener: OperationListener
    ) {}

    Refund data

    The RefundData is a class used for holding information related to a refund operation. RefundData class properties are detailed below:

    ParameterDescriptionTypeMandatory
    transactionIdRepresents the ID of the transaction to be refunded.Stringyes
    importValueRepresents the amount of the reversal in centsIntyes
    currencyRepresents the currency of the payment (It can be “euro” or “huf”).CurrencyEnumyes

    Refund Delegate

    The methods provided by the protocol and implemented by the delegate return information at the end of the triggered operations. At the end of the refund process, in case of success, the result can be intercepted through the app2AppManagerSoftPosEventsOnDidRefundSuccess method. This method receives an input parameter of type App2AppSoftposTransactionResult, which contains the details of the completed transaction.

    Refund Delegate

    func app2AppManagerSoftPosEventsOnDidRefundSuccess(
        _ result: App2AppSoftposTransactionResult
    ) {}
    ParameterDescriptionTypeMandatory
    refusalCodeRepresents the transaction status (ex. `00` means success transaction;String yes
    customMessageRepresents the transaction data, in particular the KEY_TRX_IMPORT_VALUE represent the transaction amount and the KEY_TRX_CURRENCY_CODE represent the currency code[String : String]yes
    transactionIdRepresents the transaction idString yes

    Receipt

    The receipt can be generated for both payment and refund transactions. The receipt methods takes an instance of ReceiptData as an argument and an operationListener, which will propagate the operation outcome to the caller application.

    Receipt

    @objc public func getPayReceipt(
        receiptData: ReceiptData,
        operationListener: OperationListener
    ) {}

    ReceiptData

    The ReceiptData is a class used for holding information related to a receipt. ReceiptData class properties are detailed below:

    ParameterDescriptionTypeMandatory
    transactionIdRepresents the transaction ID associated to the receipt.StringYes
    isTransactionSuccessRepresents the status of the transaction.BoolYes

    Receipt Delegate

    The methods provided by the protocol and implemented by the delegate return information at the end of the triggered operations. At the end of the receipt retrieval process, in case of success, the result can be intercepted through the app2AppManagerSoftPosEventsOnDidPaymentGetReceiptSuccess method for the payment and with app2AppManagerSoftPosEventsOnDidRefundGetReceiptSuccess method for the refund. This method receives an input parameter of type App2AppSoftPosReceipt, which contains the details of the retrieved receipt.

    Receipt Delegate

    func app2AppManagerSoftPosEventsOnDidPaymentGetReceiptSuccess(
        _ receipt: App2AppSoftPosReceipt
    ) {}

    Download App2AppSoftPosReceipt_Parameters.xlsx

    GetTransactionList

    The get transaction list action can be run by calling the getListTransaction method. The getListTransaction method retrieves up to the last 100 transactions, starting from today and moving backward chronologically. The getLastTransaction method takes an instance of operationListener, which will propagate the operation outcome to the caller application.

    GetTransactionList

    @objc public func getListTransactions(
        operationListener: OperationListener
    ) {}

    GetTransactionList Delegate

    The methods provided by the protocol and implemented by the delegate return information at the end of the triggered operations. At the end of the transaction list retrieval process, in case of success, the result can be intercepted through the app2AppManagerSoftPosEventsOnDidGetListTransactions method. This method receives an input parameter of type [App2AppSoftposTransaction], which contains the list of transactions.

    GetTransactionList Delegate

    override func app2AppManagerSoftPosEventsOnDidGetListTransactions(
        _ list: [App2AppSoftposTransaction]
    ) {}

    Download SDK_SoftposTransaction_Parameters.xlsx

    Was this helpful?

    What was your feeling about it?