public static ServioCardInfo ReadCardNumber(string pin) { ServioCardInfo res = new ServioCardInfo { ErrorCore = -1, CardNumber = "", IssuerID = -1 }; try { _pin = pin; IntPtr obj = new IntPtr(); if ((res.ErrorCore = InitInternal(_config, ref obj)) != 0) { throw new CardShellException("Error Init No" + res, res.ErrorCore); } SetCallback(obj, Marshal.GetFunctionPointerForDelegate(Callback), IntPtr.Zero); SerialnumberT serialNumber = new SerialnumberT(); IntPtr serialNumberPtr = Marshal.AllocHGlobal(sizeof(SerialnumberT)); IntPtr cardImagePtr = Marshal.AllocHGlobal(sizeof(Mf1S70T)); IntPtr operationPtr = CardOperation_Create(); var operation = (CardOperation)Marshal.PtrToStructure(operationPtr, typeof(CardOperation)); if ((res.ErrorCore = ReadCard(obj, serialNumberPtr, cardImagePtr, true)) != 0) { throw new CardShellException("Error ReadCard No" + res, res.ErrorCore); } operation.PosName = "TestTestTest"; operation.Size = sizeof(CardOperation); operation.POS = 1; operation.OpTime = DateTime.Now.ToOADate(); operation.IsPostpay = 0; operation.CardType = (int)CardType.CtIdentifierAuthorization; operation.SerialNumber = serialNumber; operation.CardNumber = null; operation.IssuerID = -1; operation.AddPrefixZeros = 0; operation.WoCard = 0; operation.PINChecked = (byte)(pin == "" ? 1 : 0); operation.ItemCount = 0; Marshal.StructureToPtr(operation, operationPtr, true); //Operation = (TCardOperation)Marshal.PtrToStructure(_Operation, typeof(TCardOperation)); if ((res.ErrorCore = Auth(obj, serialNumberPtr, cardImagePtr, operationPtr)) != 0) { throw new CardShellException("Error Auth No" + res, res.ErrorCore); } operation = (CardOperation)Marshal.PtrToStructure(operationPtr, typeof(CardOperation)); res.IssuerID = operation.IssuerID; res.CardNumber = operation.CardNumber.PadLeft(20, '0'); } finally { _pin = ""; } return(res); }
// ОПЕРАЦИЯ ПО КАРТЕ /// <summary> /// ОПЕРАЦИЯ ПО КАРТЕ /// </summary> /// <param name="type">тип операции</param> /// <param name="terminal">терминал (азс)</param> /// <param name="transact">номер транзакции</param> /// <param name="opItem">параметры операции</param> /// <returns></returns> public static ServioCardInfo CardOperationExecute(CardOperationType type, int terminal, long transact, CardOperationItem opItem) { ServioCardInfo res = new ServioCardInfo { ErrorCore = -1, CardNumber = "", IssuerID = -1 }; IntPtr obj = new IntPtr(); IntPtr serialNumberPtr = Marshal.AllocHGlobal(sizeof(SerialnumberT)); IntPtr cardImagePtr = Marshal.AllocHGlobal(sizeof(Mf1S70T)); IntPtr operationPtr = CardOperation_Create(); try { if ((res.ErrorCore = InitInternal(_config, ref obj)) != (int)ErrorCodes.ESuccess) { if (res.ErrorCore == (int)ErrorCodes.ECancel) { return(res); } throw new CardShellException("Error Init No" + res, res.ErrorCore); } UnMemory <byte> .SaveInMemArr(new byte[Mf1S70T.Size], ref cardImagePtr); if ((res.ErrorCore = ReadCard(obj, serialNumberPtr, cardImagePtr, false)) != (int)ErrorCodes.ESuccess) { if (res.ErrorCore == (int)ErrorCodes.ECancel) { return(res); } throw new CardShellException("Error ReadCard No" + res, res.ErrorCore); } var operation = UnMemory <CardOperation> .ReadInMem(operationPtr); SerialnumberT serialNumber = UnMemory <SerialnumberT> .ReadInMem(serialNumberPtr); operation.Size = sizeof(CardOperation); operation.OpCode = (byte)OperationSelector(type); operation.POS = terminal; // Номер АЗС или терминала operation.OpTime = DateTime.Now.ToOADate(); // Реальное время с вашего терминала operation.TransactID = transact; // Тут желательно ваш код код транзакции указать operation.CardType = (int)CardType.CtPayment; // Предположим что тип карты неизвестен operation.SerialNumber = serialNumber; // Указать серийный номер, считанный с метки operation.IssuerID = -1; // Указать -1, программа сама переопределит. Если указать другой код - программа будет использовать его operation.CardNumber = ""; // Не указывать !!! operation.AddPrefixZeros = 0; // Нужна доп. настройка. Аналогичная нашей опции в обработчиках operation.ItemCount = 1; // При аутентификации позиции не заполнять. IntPtr pItem1 = Marshal.AllocHGlobal(sizeof(CardOperationItem)); UnMemory <CardOperationItem> .SaveInMem(opItem, ref pItem1); IntPtr ppItem1 = Marshal.AllocHGlobal(sizeof(IntPtr)); UnMemory <IntPtr> .SaveInMem(pItem1, ref ppItem1); operation.Items = ppItem1; UnMemory <CardOperation> .SaveInMem(operation, ref operationPtr); if ((res.ErrorCore = OperationSelector(type, obj, serialNumberPtr, cardImagePtr, operationPtr)) != (int)ErrorCodes.ESuccess) { throw new CardShellException("Error Operation No" + res, res.ErrorCore); } // флаг указывает на то что образ карты был изменен в процессе операции // и нужно записать его обратно. // Нужно для пополнения карты при просмотре информации operation = UnMemory <CardOperation> .ReadInMem(operationPtr); if (operation.CardImageChanged != 0) { // при ошибке можно попробовать повторить операцию несколько раз 3-10... // если не проходит то это патовая ситуация и для её дальнейшего // разрешения нужно сохранить SerialNumber, CardImage и CardInfo // В теории, сохранённый SerialNumber и CardImage можно попробовать // записать обратно даже при перезапуске ПО, но до следующего // обслуживания по карте. Чтобы решить ситуацию можно сохранить CardInfo // чтобы в офисе уменьшили или увеличили баланс карты на соотв. значение. if ((res.ErrorCore = WriteCard(obj, serialNumberPtr, cardImagePtr)) != (int)ErrorCodes.ESuccess) { throw new CardShellException("Error WriteCard No" + res, res.ErrorCore); } } operation = (CardOperation)Marshal.PtrToStructure(operationPtr, typeof(CardOperation)); res.CardInfo = operation.CheckImage; return(res); } finally { //CardOperation_Free(operationPtr); UnMemory.FreeIntPtr(serialNumberPtr); UnMemory.FreeIntPtr(cardImagePtr); //MarshalHelper.UnMemory.FreeIntPtr(operationPtr); } }
// АВТОРИЗАЦИЯ public static ServioCardInfo Authorize() { ServioCardInfo res = new ServioCardInfo { ErrorCore = -1, CardNumber = "", IssuerID = -1 }; IntPtr obj = new IntPtr(); IntPtr serialNumberPtr = Marshal.AllocHGlobal(sizeof(SerialnumberT)); IntPtr cardImagePtr = Marshal.AllocHGlobal(sizeof(Mf1S70T)); IntPtr operationPtr = CardOperation_Create(); try { if ((res.ErrorCore = InitInternal(_config, ref obj)) != (int)ErrorCodes.ESuccess) { if (res.ErrorCore == (int)ErrorCodes.ECancel) { return(res); } throw new CardShellException("Error Init No" + res, res.ErrorCore); } if ((res.ErrorCore = ReadCard(obj, serialNumberPtr, cardImagePtr, true)) != (int)ErrorCodes.ESuccess) { if (res.ErrorCore == (int)ErrorCodes.ECancel) { return(res); } throw new CardShellException("Error ReadCard No" + res, res.ErrorCore); } var operation = UnMemory <CardOperation> .ReadInMem(operationPtr); SerialnumberT serialNumber = UnMemory <SerialnumberT> .ReadInMem(serialNumberPtr); operation.Size = sizeof(CardOperation); operation.POS = 1; // Номер АЗС или терминала operation.OpTime = DateTime.Now.ToOADate(); // Реальное время с вашего терминала operation.TransactID = 0; // Тут желательно ваш код код транзакции указать operation.OpCode = (byte)OpCode.OpAuthorization; operation.IsPostpay = 0; // как есть - если постоплата - указать true operation.CardType = (int)CardType.Unknown; // Предположим что тип карты неизвестен operation.SerialNumber = serialNumber; // Указать серийный номер, считанный с метки operation.IssuerID = -1; // Указать -1, программа сама переопределит. Если указать другой код - программа будет использовать его operation.CardNumber = ""; // Не указывать !!! operation.AddPrefixZeros = 0; // Нужна доп. настройка. Аналогичная нашей опции в обработчиках operation.WoCard = 0; // operation.PINChecked = 0; // Если указать false то драйвер запросит форму ввода пароля через callback в случае, если на карту поставили PIN-код operation.ItemCount = 0; // Позиции не нужны UnMemory <CardOperation> .SaveInMem(operation, ref operationPtr); if ((res.ErrorCore = Auth(obj, serialNumberPtr, cardImagePtr, operationPtr)) != (int)ErrorCodes.ESuccess) { if (res.ErrorCore == (int)ErrorCodes.ECancel) { return(res); } throw new CardShellException("Error Auth No" + res, res.ErrorCore); } operation = UnMemory <CardOperation> .ReadInMem(operationPtr); res.IssuerID = operation.IssuerID; res.CardNumber = operation.CardNumber.PadLeft(20, '0'); return(res); } catch (CardShellException ex) { return(new ServioCardInfo { ErrorCore = ex.ErrorCode }); } catch { return(new ServioCardInfo { ErrorCore = (int)ErrorCodes.EGeneric, }); } finally { UnMemory.FreeIntPtr(serialNumberPtr); UnMemory.FreeIntPtr(cardImagePtr); //MarshalHelper.UnMemory.FreeIntPtr(operationPtr); CardOperation_Free(operationPtr); } }