Slim-Integrated Host Transactions

Integrated host transactions allow a client of the sdk to handle the communication between the card reader and the host which approves the transaction.

You are required to implement the Payment Sdk apis for initialization, performing a sale and handling the required CommerceListenerAdapter events.

Payment Sdk initialization for Slim-Integrated

To use this feature you need to set DEVICE_HOST_AUTHENTICATION_KEY to DEVICE_HOST_AUTHENTICATION_ENABLED when initializing the SDK. Please see initialize-payment-sdk for a complete description of the initialization process.

1
2
3
4
HashMap<String, String> paramMap = new HashMap<>();
paramMap.put(TransactionManager.DEVICE_HOST_AUTHENTICATION_KEY,
    TransactionManager.DEVICE_HOST_AUTHENTICATION_ENABLED);
mPaymentSdk.initializeFromValues(mInitStatusListener, paramMap);
1
2
3
val paramMap = HashMap()
paramMap.put(TransactionManager.DEVICE_HOST_AUTHENTICATION_KEY, TransactionManager.DEVICE_HOST_AUTHENTICATION_ENABLED)
mPaymentSdk.initializeFromValues(mInitStatusListener, paramMap)
1
2
3
4
let paramMap = [
    VFITransactionManagerDEVICEHOSTAUTHENTICATIONKEY:
    VFITransactionManagerDEVICEHOSTAUTHENTICATIONENABLED]
sdk.initialize(fromValues: self, config: paramMap)
1
2
3
4
5
6
var param_map = new Windows.Foundation.Collections.StringMap
{
    {TransactionManager.DEVICE_HOST_AUTHENTICATION_KEY,
    TransactionManager::DEVICE_HOST_AUTHENTICATION_ENABLED}
};
payment_sdk_.InitializeFromValues(param_map);
1
2
3
4
5
std::unordered_map<std::string, std::string> param_map;
// Add other required parameters:
param_map.insert({verifone_sdk::TransactionManager::DEVICE_HOST_AUTHENTICATION_KEY,
    verifone_sdk::TransactionManager::DEVICE_HOST_AUTHENTICATION_ENABLED});
payment_sdk_->initializeFromValues(listener, param_map);
1
2
3
4
5
6
var param_map = new Dictionary<string, string>
{
    {TransactionManager.DEVICE_HOST_AUTHENTICATION_KEY,
    TransactionManager::DEVICE_HOST_AUTHENTICATION_ENABLED}
};
payment_sdk_.InitializeFromValues(param_map);

See also

Host Authorization Event

During a transaction in which the payment application requires host authorization, the payment application sends a HostAuthorizationEvent to the CommerceListenerAdapter which was previously created.

When you receive the HostAuthorizationEvent it will contain information about the payment that you as the client will be required to send to your host for authorization. Once you have a response from your host you must then forward the details back to the PSDK using the TransactionManager.respondToHostAuthorization(...). The response must contain the auth code, host decision, and any EMV data supplied by your host response.

If you receive a HostAuthorizationEvent then you must provide a response through TransactionManager.respondToHostAuthorization(...).

This event has apis for getting the HostPaymentContext, HostPaymentData, HostTransaction, and HostSalesData.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override // Overridden from the CommerceListenerAdapter
public void handleHostAuthorizationEvent(HostAuthorizationEvent event) {
   if (event.getStatus() == StatusCode.SUCCESS) {
        // use event data to communicate with the host
        HostTransaction hostTransaction = event.getHostTransaction();
        BigDecimal authAmount = ConversionUtility.parseAmount(0.00);
        if (hostTransaction != null && hostTransaction.getTotalAmount() != null) {
            authAmount = ConversionUtility.parseAmount(hostTransaction.getTotalAmount());
        }
        HashMap<String, String> emvData = new HashMap<>();
        emvData.put("8a", "abc123");
        emvData.put("91", "cba312");
        emvData.put("92", "bac213");
        transactionManager.respondToHostAuthorization(
            "123456",
            HostDecisionType.HOST_AUTHORIZED,
            emvData,
            Decimal.valueOf(authAmount);
    } else {
        // Handle failure by examining the status code and message.
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Overridden from the CommerceListenerAdapter
@Override fun handleHostAuthorizationEvent(event: HostAuthorizationEvent) {
   if (event.getStatus() == StatusCode.SUCCESS) {
        // use event data to communicate with the host
        val hostTransaction = event.getHostTransaction()
        var authAmount = ConversionUtility.parseAmount(0.00)
        if (hostTransaction != null && hostTransaction.getTotalAmount() != null) {
            authAmount = ConversionUtility.parseAmount(hostTransaction.getTotalAmount())
        }
        val emvData = mutableMapOf("8a" to "abc123",
            "91" to "cba312",
            "92" to "bac213")
        transactionManager.respondToHostAuthorization(
            "123456",
            HostDecisionType.HOST_AUTHORIZED,
            emvData,
            Decimal.valueOf(authAmount))
    } else {
        // Handle failure by examining the status code and message.
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Overridden from the VFICommerceListenerAdapter
override func handle(_ event: VFIHostAuthorizationEvent?) {
    if (event?.getStatus() == VFIStatusCodeSuccess) {
        // use event data to communicate with the host
        let emvData = ["8a": "abc123", "91": "cba312", "92": "bac213"]
        var amount = VFIDecimal.init(valueDecimal: Decimal.init(0.00))
        if let total = event?.getHostTransaction()?.totalAmount {
            amount = VFIDecimal.init(valueDecimal: Decimal.init(string: total) ?? 0.0)
        }
        sdk?.getTransactionManager()?.respond(
            toHostAuthorization: "123456",
            hostDecision: VFIHostDecisionTypeHOSTAUTHORIZED,
            emvTags: emvData,
            authAmount: amount)
    } else {
        // Handle failure by examining the status code and message.
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private readonly EventHandler<HostAuthorizationEvent> host_authorization_event_handler;

private void HandleEvent(HostAuthorizationEvent event)
{
    if (event.Status == StatusCode.SUCCESS)
    {
        // use event data to communicate with the host
        var emv_data = new Windows.Foundation.Collections.StringMap
        {
            { "8a", "abc123" },
            { "91", "cba312" },
            { "92", "bac213" },
        };
        var host_transaction = event.GetHostTransaction();
        var auth_amount = new Decimal(0);
        if (host_transaction)
        {
            if (host_transaction.TotalAmount() != null)
            {
                auth_amount = Decimal.FromDouble(Double.Parse(host_transaction.TotalAmount());
            }
        }
        payment_sdk_.TransactionManager.RespondToHostAuthorization(
            "123456", // authorization code
            PaymentSDK.HostDecisionType.HOST_AUTHORIZED,  // host decision
            emv_data,  // emv tags
            auth_amount); //authorization amount
    }
    else
    {
        // Handle failure by examining the status code and message.
    }
}

// ...
// Link event handler after initialization is complete
host_authorization_event_handler = async (sender, args) =>
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () => HandleEvent(args));

    payment_sdk_.TransactionManager.HandleHostAuthorizationEvent +=
        host_authorization_event_handler;
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
void handleHostAuthorizationEvent(
    const std::shared_ptr<verifone_sdk::HostAuthorizationEvent>& event) override {
  if (event->getStatus() == verifone_sdk::StatusCode::SUCCESS) {
    // use event data to communicate with the host
    std::unordered_map<std::string, std::string> emv_data;
    auto host_transaction = event->getHostTransaction();
    std::optional<verifone_sdk::Decimal> auth_amount;
    if (host_transaction) {
      auth_amount = verifone_sdk::Decimal::Parse(host_transaction->totalAmount.value_or(""));
    }
    emv_data["8a"] = "abc123";
    emv_data["91"] = "cba312";
    emv_data["92"] = "bac213";
    transaction_manager_->respondToHostAuthorization(
        "123456", // authorization code
        verifone_sdk::HostDecisionType::HOST_AUTHORIZED, // host decision
        emv_data, // emv tags
        auth_amount); // authorized amount
  } else {
    // Handle failure by examining the status code and message.
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public void HandleHostAuthorizationEvent(HostAuthorizationEvent sdk_event)
{
    if (sdk_event.Status == 0)
    {
        // use event data to communicate with the host
        var emv_data = new Dictionary<string, string>
        {
            { "8a", "abc123" },
            { "91", "cba312" },
            { "92", "bac213" },
        };
        var host_transaction = sdk_event.HostTransaction;
        var auth_amount = new VerifoneSdk.Decimal(0);
        if (host_transaction != null)
        {
            if (host_transaction.Value.TotalAmount != null)
            {
                auth_amount = Decimal.FromDouble(Double.Parse(host_transaction.Value.TotalAmount);
            }
        }
        mw.Dispatcher.Invoke(() => { mw.payment_sdk_.TransactionManager.RespondToFinalizeTransaction(
            "123456", // authorization code
            VerifoneSdk.HostDecisionType.HOST_AUTHORIZED,  // host decision
            emv_data,  // emv tags
            auth_amount);}); //authorization amount

    }
    else
    {
        // Handle failure by examining the status code and message.
    }
}

Finalizing a Host Transaction

During a transaction when the payment application requires the host to finalize the transaction it sends the HostFinalizeTransactionEvent to the CommerceListenerAdapter which was previously created.

When you receive the HostFinalizeTransactionEvent it will contain information about the payment that you as the client will be required to send to your host for finalizing the transaction. Once you have a response from your host you must then forward the details back to the PSDK using the TransactionManager.respondToHostFinalizeTransaction(...). The response must contain the auth code, host decision, and any EMV data supplied by your host response.

If you receive a HostFinalizeTransactionEvent then you must provide a response through TransactionManager.respondToHostFinalizeTransaction(...).

This event has apis for getting the HostPaymentContext, HostPaymentData, HostTransaction, and HostSalesData.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override // Overridden from the CommerceListenerAdapter
public void handleHostFinalizeTransactionEvent(HostFinalizeTransactionEvent event) {
   if (event.getStatus() == StatusCode.SUCCESS) {
        // use event data to communicate with the host
        HostTransaction hostTransaction = event.getHostTransaction();
        BigDecimal authAmount = ConversionUtility.parseAmount(0.00);
        if (hostTransaction != null && hostTransaction.getTotalAmount() != null) {
            authAmount = ConversionUtility.parseAmount(hostTransaction.getTotalAmount());
        }
        HashMap<String, String> emvData = new HashMap<>();
        emvData.put("8a", "abc123");
        emvData.put("91", "cba312");
        emvData.put("92", "bac213");
        transactionManager.respondToHostFinalizeTransaction(
            "123456",
            HostDecisionType.HOST_AUTHORIZED,
            emvData,
            Decimal.valueOf(authAmount));
    } else {
        // Handle failure by examining the status code and message.
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// Overridden from the CommerceListenerAdapter
@Override fun handleHostFinalizeTransactionEvent(event: HostFinalizeTransactionEvent) {
    if (event.getStatus() == StatusCode.SUCCESS) {
        // use event data to communicate with the host
        val hostTransaction = event.getHostTransaction()
        var authAmount = ConversionUtility.parseAmount(0.00)
        if (hostTransaction != null && hostTransaction.getTotalAmount() != null) {
            authAmount = ConversionUtility.parseAmount(hostTransaction.getTotalAmount())
        }
        val emvData = mutableMapOf("8a" to "abc123",
            "91" to "cba312",
            "92" to "bac213")
        transactionManager.respondToHostFinalizeTransaction(
            "123456",
            HostDecisionType.HOST_AUTHORIZED,
            emvData,
            Decimal.valueOf(authAmount))
    } else {
        // Handle failure by examining the status code and message.
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// Overridden from the VFICommerceListenerAdapter
override func handle(_ event: VFIHostFinalizeTransactionEvent?) {
    if (event?.getStatus() == VFIStatusCodeSuccess) {
        // use event data to communicate with the host
        let emvData = ["8a": "abc123", "91": "cba312", "92": "bac213"]
        var amount = VFIDecimal.init(valueDecimal: Decimal.init(0.00))
        if let total = event?.getHostTransaction()?.totalAmount {
            amount = VFIDecimal.init(valueDecimal: Decimal.init(string: total) ?? 0.0)
        }
        sdk?.getTransactionManager()?.respond(
            toHostFinalizeTransaction: "123456",
            hostDecision: VFIHostDecisionTypeHOSTAUTHORIZED,
            emvTags: emvData,
            authAmount: amount)
    } else {
        // Handle failure by examining the status code and message.
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private readonly EventHandler<HostFinalizeTransactionEvent> host_finalize_transaction_event_handler;

private void HandleEvent(HostFinalizeTransactionEvent event)
{
    if (event.Status == StatusCode.SUCCESS)
    {
        // use event data to communicate with the host
        var emv_data = new Windows.Foundation.Collections.StringMap
        {
            { "8a", "abc123" },
            { "91", "cba312" },
            { "92", "bac213" },
        };
        var host_transaction = event.GetHostTransaction();
        var auth_amount = new Decimal(0);
        if (host_transaction)
        {
            if (host_transaction.TotalAmount() != null)
            {
                auth_amount = Decimal.FromDouble(Double.Parse(host_transaction.TotalAmount());
            }
        }
        payment_sdk_.TransactionManager.RespondToFinalizeTransaction(
            "123456", // authorization code
            PaymentSDK.HostDecisionType.HOST_AUTHORIZED,  // host decision
            emv_data,  // emv tags
            auth_amount); //authorization amount
    }
    else
    {
        // Handle failure by examining the status code and message.
    }
}

// ...
// Link event handler after initialization is complete
host_finalize_transaction_event_handler = async (sender, args) =>
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () => HandleEvent(args));

    payment_sdk_.TransactionManager.HostFinalizeTransactionEvent +=
        host_finalize_transaction_event_handler;
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
void handleHostFinalizeTransactionEvent(
    const std::shared_ptr<verifone_sdk::HostFinalizeTransactionEvent>& event) override {
  if (event->getStatus() == verifone_sdk::StatusCode::SUCCESS) {
    // use event data to communicate with the host
    std::unordered_map<std::string, std::string> emv_data;
    auto host_transaction = event->getHostTransaction();
    std::optional<verifone_sdk::Decimal> auth_amount;
    if (host_transaction) {
      auth_amount = verifone_sdk::Decimal::Parse(host_transaction->totalAmount.value_or(""));
    }
    emv_data["8a"] = "abc123";
    emv_data["91"] = "cba312";
    emv_data["92"] = "bac213";
    transaction_manager_->respondToHostFinalizeTransaction(
        "123456", // authorization code
        verifone_sdk::HostDecisionType::HOST_AUTHORIZED, // host decision
        emv_data, // emv tags
        auth_amount); // authorized amount
  } else {
    // Handle failure by examining the status code and message.
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
private readonly EventHandler<HostFinalizeTransactionEvent> host_finalize_transaction_event_handler;

private void HandleEvent(HostFinalizeTransactionEvent event)
{
    if (event.Status == StatusCode.SUCCESS)
    {
        // use event data to communicate with the host
        var emv_data = new Windows.Foundation.Collections.StringMap
        {
            { "8a", "abc123" },
            { "91", "cba312" },
            { "92", "bac213" },
        };
        var host_transaction = event.GetHostTransaction();
        var auth_amount = new Decimal(0);
        if (host_transaction)
        {
            if (host_transaction.TotalAmount() != null)
            {
                auth_amount = Decimal.FromDouble(Double.Parse(host_transaction.TotalAmount());
            }
        }
        payment_sdk_.TransactionManager.RespondToFinalizeTransaction(
            "123456", // authorization code
            PaymentSDK.HostDecisionType.HOST_AUTHORIZED,  // host decision
            emv_data,  // emv tags
            auth_amount); //authorization amount
    }
    else
    {
        // Handle failure by examining the status code and message.
    }
}

// ...
// Link event handler after initialization is complete
host_finalize_transaction_event_handler = async (sender, args) =>
{
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
        () => HandleEvent(args));

    payment_sdk_.TransactionManager.HostFinalizeTransactionEvent +=
        host_finalize_transaction_event_handler;
};