Open Hardware Station sample from Retail SDK. Path of Retail SDK will be something like below:
C:\RetailSDK\Code\SampleExtensions\HardwareStation\SampleHardwareStation.sln
C:\RetailSDK\Code\SampleExtensions\HardwareStation\SampleHardwareStation.sln
Create new project in this solution "MyNewMSRExtension".
Right click on "SampleHardwareStation" Solution and select "Class Library (Portable)":
Now select following targets and click OK:
- .NET Framework 4.5
- Windows 8
- ASP.NET Core 1.0
- Windows Phone 8.1
Now you can see your new project in this solution:
Now add new class "OposMagneticSwipeReader".
Add below references in your newly created project:
Now add below code in your class:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Interop.OposMSR;
using Microsoft.Dynamics.Commerce.HardwareStation;
using Microsoft.Dynamics.Commerce.HardwareStation.CardPayment;
using Microsoft.Dynamics.Commerce.HardwareStation.Peripherals;
using Microsoft.Dynamics.Commerce.HardwareStation.Peripherals.Entities;
using Microsoft.Dynamics.Commerce.Runtime.Handlers;
using Microsoft.Dynamics.Commerce.Runtime.Messages;
using Microsoft.Dynamics.Retail.Diagnostics;
namespace MyNewMSRExtension
{
public sealed class OposMagneticSwipeReader : INamedRequestHandler
{
private const string MsrInstanceNameTemplate = "OposMsr_{0}";
private OPOSMSR oposMsr;
private string msrInstanceName;
/// <summary>
/// Occurs when card is swiped.
/// </summary>
private event EventHandler<MagneticCardSwipeInfo> MsrSwipeEvent;
/// <summary>
/// Gets the unique name for this request handler.
/// </summary>
public string HandlerName
{
get { return PeripheralType.Opos; }
}
/// <summary>
/// Gets the collection of supported request types by this handler.
/// </summary>
public IEnumerable<Type> SupportedRequestTypes
{
get
{
return new[]
{
typeof(OpenMagneticSwipeReaderDeviceRequest),
typeof(SwipeMagneticSwipeReaderDeviceRequest),
typeof(CloseMagneticSwipeReaderDeviceRequest)
};
}
}
/// <summary>
/// Represents the entry point for the magnetic swipe reader device request handler.
/// </summary>
/// <param name="request">The incoming request message.</param>
/// <returns>The outgoing response message.</returns>
public Response Execute(Request request)
{
ThrowIf.Null(request, "request");
Type requestType = request.GetType();
if (requestType == typeof(OpenMagneticSwipeReaderDeviceRequest))
{
var openRequest = (OpenMagneticSwipeReaderDeviceRequest)request;
this.Open(openRequest.DeviceName);
}
else if (requestType == typeof(SwipeMagneticSwipeReaderDeviceRequest))
{
var swipeRequest = (SwipeMagneticSwipeReaderDeviceRequest)request;
MagneticCardSwipeInfo swipeInfo = this.WaitForSwipe(swipeRequest.TimeoutInSeconds);
return new SwipeMagneticSwipeReaderDeviceResponse(swipeInfo);
}
else if (requestType == typeof(CloseMagneticSwipeReaderDeviceRequest))
{
this.Close();
}
else
{
throw new NotSupportedException(string.Format("Request '{0}' is not supported.", requestType));
}
return new NullResponse();
}
/// <summary>
/// Opens a peripheral.
/// </summary>
/// <param name="peripheralName">Name of the peripheral.</param>
private void Open(string peripheralName)
{
this.msrInstanceName = string.Format(MsrInstanceNameTemplate, peripheralName);
this.oposMsr = OPOSDeviceManager<OPOSMSR>.Instance.AcquireDeviceHandle<OPOSMSRClass>();
if (!this.oposMsr.DeviceEnabled)
{
// Open the device only if the device is not claimed.
if (!this.oposMsr.Claimed)
{
// Open
RetailLogger.Log.HardwareStationOposMethodCall(this.msrInstanceName, "Open");
this.oposMsr.Open(peripheralName);
OposHelper.CheckResultCode(this, this.oposMsr.ResultCode);
// Claim
RetailLogger.Log.HardwareStationOposMethodCall(this.msrInstanceName, "Claimed");
this.oposMsr.ClaimDevice(OposHelper.ClaimTimeOut);
OposHelper.CheckResultCode(this, this.oposMsr.ResultCode);
// Enable/Configure
this.oposMsr.DeviceEnabled = true;
// Set the decode data - so that the device decodes the scanned data
this.oposMsr.DecodeData = true;
// Note: there are two properties that look similar
// ParseDecodedData and ParseDecodeData
// Both do the same as per the OPOS spec.
// Setting this property makes the device return data
// in individual fields.
this.oposMsr.ParseDecodedData = true;
// Set Transmit Sentinels to true
// so that when the data is sent, we can get the sentinels
// and can parse the data of the tracks.
this.oposMsr.TransmitSentinels = true;
// Plug in handlers for data events
this.oposMsr.DataEvent += this.OnMsrDataEvent;
this.oposMsr.ErrorEvent += this.OnMsrErrorEvent;
// Set autodisable to false
this.oposMsr.AutoDisable = false;
// Enable data events
this.oposMsr.DataEventEnabled = true;
}
else
{
RetailLogger.Log.HardwareStationPeripheralInteraction(this.msrInstanceName, "Prevent MSR device open call, as device is already claimed.");
}
}
}
/// <summary>
/// Waits for a swipe during the specified <paramref name="timeoutInSeconds"/>.
/// </summary>
/// <param name="timeoutInSeconds">The timeout in seconds to wait for a swipe to occur.</param>
/// <returns>Swipe info.</returns>
private MagneticCardSwipeInfo WaitForSwipe(int timeoutInSeconds)
{
var eventCompletionSource = new TaskCompletionSource<MagneticCardSwipeInfo>();
EventHandler<MagneticCardSwipeInfo> handler = null;
handler = (sender, args) =>
{
eventCompletionSource.SetResult(args);
this.MsrSwipeEvent -= handler;
};
this.MsrSwipeEvent += handler;
var timeout = TimeSpan.FromSeconds(timeoutInSeconds);
var completeTaskIndex = Task.WaitAny(new[] { (Task)eventCompletionSource.Task }, timeout);
var isSwipeOccurred = completeTaskIndex == 0;
return isSwipeOccurred
? eventCompletionSource.Task.Result
: null;
}
/// <summary>
/// Closes a connection with MSR.
/// </summary>
private void Close()
{
try
{
this.oposMsr = OPOSDeviceManager<OPOSMSR>.Instance.AcquireDeviceHandle<OPOSMSRClass>();
if (this.MsrSwipeEvent != null)
{
this.MsrSwipeEvent(this, null);
}
if (this.oposMsr != null)
{
this.oposMsr.DataEvent -= this.OnMsrDataEvent;
this.oposMsr.ErrorEvent -= this.OnMsrErrorEvent;
this.oposMsr.DeviceEnabled = false;
RetailLogger.Log.HardwareStationOposMethodCall(this.msrInstanceName, "Released");
this.oposMsr.ReleaseDevice();
RetailLogger.Log.HardwareStationOposMethodCall(this.msrInstanceName, "Closed");
this.oposMsr.Close();
}
}
finally
{
if (this.oposMsr != null)
{
OPOSDeviceManager<OPOSMSR>.Instance.ReleaseDeviceHandle(this.oposMsr);
}
}
}
private void OnMsrErrorEvent(int resultCode, int resultCodeExtended, int errorLocus, ref int errorResponse)
{
var ex = new PeripheralException(PeripheralException.PeripheralEventError, "Error Event from Peripheral with error code {0}", resultCode);
RetailLogger.Log.HardwareStationPerpheralError("Magnetic Swipe Reader (MSR)", resultCode, resultCodeExtended, ex);
throw ex;
}
private void OnMsrDataEvent(int status)
{
if (this.MsrSwipeEvent != null)
{
var swipeInfo = new MagneticCardSwipeInfo();
//Do your work here. Here you can find MSR scanned data
// Store the account number in the temporary storage and mask the accout number only if it's the payment card.
if (swipeInfo.IsPaymentCard)
{
// Store the swipe info into the temporary memory storage.
var temporaryMemoryManager = new TemporaryMemoryManager<string, string>();
temporaryMemoryManager.AddCardInfoToMemory(MagneticCardSwipeInfo.MsrCardKey, swipeInfo.AccountNumber, DateTime.UtcNow, swipeInfo.AccountNumber);
// Mask the account number using mask chars.
string maskedAccountNumber = Utilities.GetMaskedCardNumber(swipeInfo.AccountNumber);
swipeInfo.AccountNumber = maskedAccountNumber;
}
this.MsrSwipeEvent(this, swipeInfo);
}
// This should not be required since the auto disable is set to false
// but apparently some Msrs require this explictly enabled
// every time.
this.oposMsr.DataEventEnabled = true;
}
}
}
You can also write your custom logic in above code after comments "Do your work here. Here you can find MSR scanned data".
No comments:
Post a Comment