Search

Page tree
Skip to end of metadata
Go to start of metadata

This article describes the steps needed to implement a Payment Gateway plugin for SDK v2.0 that is using a redirection flow.

At the time of writing this document the SDK is migrating from v1.0 to v2.0. This means that some implementation is still needed using the v1.0 SDK. More specific you need to create a project that is used by the BSS's Setup in order for the user to configure the gateway (written using SDK v1.0) and a project to be used to process any transactions with the gateway, commonly known as the Processor (written using SDK v2.0).


Creating the Processor project (SDK v2.0)

  1. Create a new C# Class Library Project (.NET Framework). Use the naming convention for the namespace and project name "Iwcp.PaymentGateways.<Gateway Name>".

  2. Create a new folder in vs solution to add the following DLLs. These libraries should be provided by interworks.cloud. (on-premises installations collect DLLs from bin folder of BSS)
    1. Iwcp.SDK.PaymentGateways.dll (SDK v2.0 for creating the processor)
    2. Interworks.SDK.PaymentGateways.dll (SDK v1.0 for supporting the setup of payment gateway on BSS)
  3. Create the Processor class that will be used by the SDK to complete transactions with the gateway. We recommend using a naming convention "<Gateway Name>Processor.cs".
  4. Add reference Iwcp.SDK.PaymentGateways in the processor project. In our example we have copied the libraries to a folder with libs' name.
  5. Enable the gateway for the SDK to discover it. You need to decide a display name and a gateway type for your gateway.  The display name should be meaningful and reflect the commercial name of the gateway ie. My Foo Gateway. The gateway type should be all lower-case and hyphen separated ie. "my-foo-gateway".
    1. On-premises installations. Run the following query in your working DB 

      INSERT INTO tblPaymentGateway ([Name], [Type], [IsSupported], [PCICompliant])
      VALUES ('My Foo Gateway', 'my-foo-gateway',1, NULL);
    2. Otherwise, contact interworks.cloud to enable the plug-in
  6. Extend your class from Iwcp.SDK.PaymentGateways.DefaultProcessor. This will give your Processor some basic functionality such as logging support via Trace. Decorate the class using a PaymentGateway attribute so that the Processor will be discovered by the SDK.  The name used in the attribute must match the gateway type used in the previous steps.

    	[PaymentGateway("my-foo-gateway")]
    	public class FooProcessor : DefaultProcessor, IRedirection
     	{
            public FooProcessor()
            {
    
            }
    	}
    
  7. Implement the interface Iwcp.SDK.PaymentGateways.Interfaces.IRedirection. This is the interface used by the Redirection flow. The interface serves the "on-session" transactions. The "on-session transaction" is a transaction with a user present, usually during a basket checkout procedure. Also the "on-session" transaction may or may not produce a token for future re-curring charges. A redirection flow always has two phases. The "before" (PrepareTransaction) and "after" (VerifyTransaction) redirection.
    1. PrepareTransaction - The first phase is the communication with the gateway, like a "hand-shake", which is established right before the user's agent is redirected to the gateway's website. At this point the two parties exchange some inrfomation about the imminent transaction such as the amount, currency, buyer details etc. After a successful PrepareTransaction the user will be redirected to the designated URL by the TransactionRedirectResponse. He will confirm his Credit Card details and commit the transaction. At this point the gateway's website will redirect the user back at the designated URL by the Processor by the TransactionRedirectResponse or in some cases directly configured on the gateway's portal, passing a transaction token and/or the transaction result in the query params. 

      		public TransactionRedirectResponse PrepareTransaction(TransactionRedirectRequest request)
              {
                  // Try to log before and after a request
                  Trace("Foo::PrepareTransaction - Request", request);
      
                  // Communicate with gateway...
                  // Retrieve some "Transaction ID" and the redirect-away URL from the gateway's API...
                  // Return the URL in order for the SDK to redirect the user to it
      
                  var fooResponse = invokeFooGateway(...);
      			
      			// Remove the decimal from the number...
      			decimal amount = request.Amount * request.Currency.MinorUnits;
      
                  Trace("Foo::PrepareTransaction - Response", fooResponse);
      
                  return new TransactionRedirectResponse
                  {
      				// RedirectionUrl is provided by payment gateway.
                      RedirectionUrl = fooResponse.RedirectionUrl,
                      TransactionId = fooResponse.TransactionId
                  };
              }
    2. VerifyTransaction - When redirected-back the VerifyTransaction will be invoked by the SDK passing the query params in the TransactionStatusRequest. Use the query params to communicate with the gateways, determine the result of the transaction and return a TransactionStatusResponse. At this point if a token was generated for re-curring charges return it so it can be persisted for future use. If not return null in the PaymentProfile.

      		public TransactionStatusResponse<CreditCard> VerifyTransaction(TransactionStatusRequest request)
              {
                  // Try to log before and after a request
                  Trace("Foo::VerifyTransaction - Request", request);
      
                  // Communicate with gateway using any data from request.ExtraData
                  // Retrieve information about the transaction's result
      
                  var fooResponse = invokeFooGateway(...);
      
                  Trace("Foo::VerifyTransaction - Response", fooResponse);
      
                  return new TransactionStatusResponse<CreditCard>
                  {
                      IsPaid = fooResponse.Charged,
                      PaymentProfile = new CreditCard                         // If the gateway has tokenized the credit card return a PaymentProfile, otherwise return null
                      {
                          ExpirationMonth = fooResponse.ExpMonth,             //  You can leave it empty, if not provided by your gateway
                          ExpirationYear = fooResponse.ExpYear,               //  You can leave it empty, if not provided by your gateway
                          MaskedNumber = fooResponse.MaskedCreditCardNumber,  //  You can leave it empty, if not provided by your gateway
                          Token = fooResponse.CreditCardToken                 //  Must always be provided, if you provide a PaymentProfile
                      }
                  };
              }
  8. ExecuteTransaction - If your gateway tokenizes Credit Cards for re-curring charges you need to implement the ExecuteTransaction method. This method is part of the "off-session" transaction interface. An "off-session transaction" is considered a transaction that takes place without a user present, usually used for recurring charges from our Billing engine. When this method is invoked you will have access to the previously generated and persisted token so you can use it to complete the transaction. If your gateway doesn't tokenize credit cards you can leave the method body empty, it will not be invoked by the SDK.

    		public TransactionResponse ExecuteTransaction(PaymentRequest request)
            {
                // Try to log before and after a request
                Trace("Foo::ExecuteTransaction - Request", request);
    
                // Communicate with gateway using the request.Token
                // Retrieve information about the transaction's result
                // Return whether the credit card got charged
    
                var fooResponse = invokeFooGateway(request.Token, ...);
    
                Trace("Foo::ExecuteTransaction - Response", fooResponse);
    
                return new TransactionResponse
                { 
                    IsPaid = fooResponse.Charged,
                    TransactionId = fooResponse.GatewayTranscationId,   // Some identifier for the transcation generated by the gateway, if provided, otherwise leave empty string
                    Amount = (decimal)fooResponse.AmountCharge          // The amount that was charged, if provided, otherwise leave null
                };
            }
  9. ValidateSettings - For convience the SDK will call this method right before invoking any of the aforementioned methods. You can write here any validation logic and throw exceptions if your criteria are not met.

    		public override void ValidateSettings(Dictionary<string, object> settings)
            {
                if (!settings.ContainsKey("fooUsername") && string.IsNullOrEmpty(settings["fooUsername"].ToString()))
                    throw new ArgumentException("Incorrect payment gateway fooUsername");
    
                if (!settings.ContainsKey("fooPassword") && string.IsNullOrEmpty(settings["fooPassword"].ToString()))
                    throw new ArgumentException("Incorrect payment gateway fooPassword");            
            }
  10. Copy the generated DLL(in our example is Iwcp.PaymentGateways.FooGateway.dll) to bin folder in the Marketpalce V4.0.

If the payment gateway returns some error, you can throw a PaymentGatewayException so that the error to be logged and displayed on the UI.


Re-capping:

  • Create the gateway's "Processor" project
  • Update the DB with the gateway's name and type
  • Implement the appropriate interfaces of the Processor
  • Copy the generated DLL to bin folder in the Marketpalce V4.0 and installation folder of billing service for on-premises installations or contact interworks.cloud.

Creating the BSS Setup project

  1. Create a new C# Class Library Project (.NET Framework). Use the naming convention for the namespace and project name "Iwcp.PaymentGateways.SetupOptions.<Gateway Name>".
  2. Add Interworks.SDK.PaymentGateways as a reference.
  3. Create a new class that will be used by the BSS for setting payment gateway. We recommend using a naming convention "PaymentGatewaySetupOptions<GatewayName>".
  4. Implement the interface ISetupOptionsUI from Interworks.SDK.PaymentGateways
  5. Implement OnInit method.

    [PaymentGateway("my-foo-gateway")]
    public class PaymentGatewaySetupOptionsFoo : ISetupOptionsUI
    {
        public void OnInit(SetupOptionsBuilder builder)
        {
            builder
                .AddInputText("foo-option-1", "Foo 1")
                .AddInputText("foo-option-2", "Foo 2")
                .AddInputText("foo-option-3", "Foo 3")
                .SetInstructions("<div style=\"padding:5px\">\r\n" +
                        "<b>Setup Instructions</b><br/>\r\n" +
                        "<br/>\r\n" +
                        "Lorem ipsum...\r\n" +
                        "</div>");
    
     
    
        }
    }
  6. Copy the generated DLL(in our example is Iwcp.PaymentGateways.SetupOptions.FooGateway.dll) to bin folder in the BSS for on-premises installations or contact interworks.cloud.

The source code of example is attached to the following file.

My Foo Gateway.rar


Enable the logger on payment gateways, adding a new rule on NLog.config file of application. The new rule is  <logger name="Iwcp.SDK.PaymentGateways*" writeTo="DB" minLevel="Trace"/>.