In this topic:


Before you get started, make sure to install the following:

Proxy Configuration

In order to process transactions, Commerce SDK needs to be able to make outbound internet calls to the Converge payment gateway. If the Windows workstations running Commerce SDK are required to send internet traffic through a network proxy, you have a couple of options. You can either bypass the proxy or configure Commerce SDK proxy support.

Proxy Bypass

This will enable the workstations to access Converge directly without going through the proxy. Request your network administrator to add the following Converge addresses/IPs to a proxy bypass whitelist:

  • api.convergepay.com
  • api.demo.convergepay.com

No further Commerce SDK configuration is required.

Commerce SDK Proxy Configuration

To configure the proxy for Commerce SDK, pass the proxy information and use validateAccount to test if Commerce SDK can communicate with Converge.

Proxy Address
Proxy Port Number
Proxy User
The username for proxy authentication (where applicable).
Proxy Password
The password for proxy authentication (where applicable).


Commerce SDK returns errors in the validateAccount callback and the Commerce Web Services may provide more information.

If you cannot configure the proxy environment, you must use the proxy bypass method.


OpenPaymentArgs obea = new OpenPaymentArgs();           


ProxyInfo proxyInfo = null;
String proxyAddress = null;
String proxyPort = null;
String proxyUser = null;
String proxyPassword = null;

if (!(null == (temp = pf.get("proxyAddress"))))
    proxyAddress = temp;
if (!(null == (temp = pf.get("proxyPort"))))
    proxyPort = temp;
if (!(null == (temp = pf.get("proxyUser"))))
    proxyUser = temp;
if (!(null == (temp = pf.get("proxyPassword"))))
    proxyPassword = temp;

// address and port are required attributes
// user and password should only be populated if the proxy server requires them
if (proxyAddress != null && proxyPort != null)
    proxyInfo = new ProxyInfo(proxyAddress, proxyPort, proxyUser, proxyPassword);

obea.proxyInfo = proxyInfo;

OpenPaymentGatewayResults tr = m_CWS.OpenPaymentGateway(obea, null);


Build the Sample Application

  1. Copy and extract the CSharpSrc.zip file.

    There are two sample apps to choose from:

    • SalesApp is a simple app that focuses on basic functionality
    • TransApp explores all the available features in CSDK
  2. In Visual Studio, go to File/Open/Project/Solution and choose SalesApp.sln or TransApp.sln.

  3. You are set to start building and debugging the sample application.


    You may need to remove and re-add the CWSWrapper DLL files in your project’s References section.

Converge Credentials

  1. Open the CWSTransApp.properties file in the CWSApp\CWSTransApp directory.

  2. Uncomment these lines and add your information.

    # serverType=DEMO
    # pin=demo_pin
    # user=demo_userId
    # merchant=demo_merchantId
    # vendorId=your_vendorId
    # vendorAppName=your_vendorAppName
    # vendorAppVersion=your_vendorAppVersion

Set Up Your Application

  1. Add the CWS Wrapper library to your application.

    • Add a reference to CWSWrapper.dll in the Solution Explorer.
    • Add a using CWSWrapper; statement to any files that use that DLL.
  2. Create and initialize an instance of CWS.

    private string m_PaymentGatewayId;
    private CWS m_CWS;
    m_CWS = new CWS();
    m_CWS.Start("path to log file.txt", 4);
  3. Open the payment gateway.


    Once you establish a link, you’ll use use the paymentGatewayIn in any future calls to the gateway.

    OpenPaymentArgs obea = new OpenPaymentArgs();
    obea.merchantId = MY_MERCHANT;
    obea.userId = MY_USER;
    obea.pin = MY_PIN;
    obea.app = MY_APP;
    obea.vendorId = MY_VENDOR_ID;
    obea.vendorAppName = MY_VENDOR_APP_NAME;
    obea.vendorAppVersion = MY_VENDOR_APP_VERSION;
    obea.partnerAppId = MY_PARTNER_APP_ID; // optional Converge partner app id
    obea.email = IGNORE_ME; // Ignore this parameter; we're removing it in a future release.
    obea.paymentGatewayEnvironment = MY_SERVERTYPE;
    obea.handleDigitalSignature = false;

    For RBA & UPP PIN pads only, you have the option to override the default language for Canadian transactions. If you do not specify a language, the transaction defaults to the server setting. Commerce SDK supports English and French in Canada.

    obea.overrideDefaultTerminalLanguage = new OverrideDefaultTerminalLanguage();
    obea.overrideDefaultTerminalLanguage.languageInformation = new LanguageInformation();
    obea.overrideDefaultTerminalLanguage.languageInformation.languageCode = ...;
    obea.overrideDefaultTerminalLanguage.languageInformation.countryCode = ...;

    For US RBA & UPP PIN pads only, you have the option to override the Commerce SDK the US debit network preference. If you do not specify a preference, Commerce SDK uses the server-supplied value. Valid Values: global debit network, us common debit network and no preference. No preference prompts the user to make the selection on PIN pad. Contactless transactions: PIN pad does not ask user for a selection. The PIN pad selects the AID with the highest priority remaining after applying setting filters. For example, if the setting is the global debit network and there are two global AIDs on the card, the PIN pad selects the AID with the highest priority.

    obea.overrideDebitNetworkPreferences = new OverrideDebitNetworkPreferences();
    obea.overrideDebitNetworkPreferences.visa = ...;
    obea.overrideDebitNetworkPreferences.mastercard = ...;
    obea.overrideDebitNetworkPreferences.discover = ...;
    OpenPaymentGatewayResults results = m_CWS.OpenPaymentGateway(obea, null);
    if (null != results.OpenPaymentData)
    // Save the paymentGatewayId for future use
    m_PaymentGatewayId = results.OpenPaymentData.paymentGatewayId;
  4. Run a credit card Sale transaction.

    PaymentArgs pa = new PaymentArgs();
    pa.paymentGatewayId = m_PaymentGatewayId;
    Money m = new Money(Money.CurrencyCodefromString("USD"), myAmount);
    pa.baseTransactionAmount = m;
    pa.tenderType = TenderType.CARD;
    pa.transactionType = TransactionType.SALE;
    m_CWS.StartPaymentTransaction(pa, MyNotifyCWSEvent, MyPaymentComplete);
  5. Handle event notifications.

    public void MyNotifyCWSEvent(CWSEvent cwsevent)
        /* cwsevent.statusDetails will contain simple messages like
  6. Receive transaction results.

    public void MyPaymentComplete(PaymentTransactionResults ptr)
        m_ChanId = ptr.getChanId();
        PaymentTransactionData ptdata = ptr.PaymentTransactionData;
        if (null != ptdata)
        // PaymentTransactionData contatins all the details of the transaction

C# Interface to the CWS REST API

The C# interface handles the REST API details to simplify what you interact with at the end of the transaction. Commerce SDK summarizes the results for each transaction in a Results object.

Getting Started

  1. Create an instance of CWS.

    CWS m_CWS = new CWS();
  2. Call its Start method.

    m_CWS.Start(“c:\\somedir\\mylog.log”, 4);
  3. Pass the filename for logging debug information and a level 1 (least) to 4 (most).

  4. Call the Stop method before exiting your application.

    Now you’re ready to call any method.


All CWS functions are defined in the CWSWrapper namespace. You can either precede all CWS references with CWSWrapper or add a "using CWSWrapper;" at the beginning of each of module.

Returned Results Objects

All results objects normally contain one or more objects that contain properties of interest.

For example, the card read function returns the cardholder’s first and last names. CardReadResults stores these data in a CardData object.

Assuming crr is a CardReadResults object, you can obtain the values:

CardData cd = crr.CardData;
String lastname = cd.lastName;
String firstname = cd.firstName;

Properties of CWS

URLString defaults to https://localhost:9790/rest/command.


If the URL changes, you need to set this property.

DelayMillisInteger for the number of milliseconds to wait between REST API calls to check on status.
Default value: 250 (1/4 second).
MaxWaitMillisInteger for the maximum number of miilliseconds the interface will spend sending REST API status calls.
Default value: 60,000 (60 seconds).


-1 means no time limit.


This layer may produce informational messages you find useful.

Use Case

The card reader usually faces the customer and the cashier cannot see what the reader display reads. Suppose a terminal prompt confuses the customer; if the cashier knew where the customer was in the transaction process, the cashier could quickly help navigate the prompt without the customer even having to ask.

You can pass a delegate listener to all functions to receive these notifications. Pass a delegate listener as a CWSEvent.

public class CWSEvent
    public String timeStamp { get; set; }
    public String statusDetails { get; set; }

The delegate looks like:

public void MyNotifyCWSEvent(CWSEvent cwsevent)
// Do something with the event


You must call this delegate on a separate thread.

Synchronous or Asynchronous

All functions can run synchronously or asynchronously.

To run functions asynchronously, pass a Start method and a delegate to handle the completion.

Now you can call any method.

A word about naming

Let’s take an example method,  Foo.

The name of the synchronous version is  Foo and the asynchronous version is  StartFoo.

The results are  FooResults and the delegate signature is  FooComplete(FooResults).


You want to perform a sale transaction. This returns a BackEndResults object.

Calling Synchronously
PaymentTransactionResults ptr = m_CWS.PaymentTransaction(bea, MyNotifyCWSEvent);
Calling Asynchronously
public void MyPaymentComplete(PaymentTransactionResults ber)
// Do something with the results


// Returns right away; MyBackEndComplete called later
m_CWS.StartPaymentTransaction(bea, MyNotifyCWSEvent, MyPaymentComplete);
More Information Required

Commerce SDK uses callbacks to obtain additional information during a transaction.

Normally, your call to BackEnd does not return until finished with the transaction results available. However, if the SDK needs information, it returns before completion with a request for additional information.

You must check if BackEndResults.getRequiredInformation is null (BackEndResults.BackEndTransactionData will be null). These strings will tell you what information to supply.

Likewise, if you use StartBackEnd, requiredInformation calls your BackEndComplete method.

This is a BackEndComplete example:

public void MyPaymentComplete(PaymentTransactionResults ber)
    String chanId = ber.getChanId();
    PaymentTransactionData betd = ber.PaymentTransactionData;
    if (null != betd) // Results available?
        m_TransData = betd;
        if ((null != betd.approved) && (betd.approved.Equals("yes"))   
        // Transaction approved?
    else if (null = ber.getRequiredInformation())
        // Determine what additional information is necessary

You continue the transaction once you obtain the additional required information. For example, if VoiceReferral is required, you could continue the transaction like this:

Dictionary<string, string> info = new Dictionary<string, string>();
info["VoiceReferral"] = theVoiceReferral;
m_CWS.StartContinuePaymentTransaction(m_PaymentGatewayId, chanId, info, MyNotifyCWSEvent, MyPaymentComplete);