Автоматический вариант работы с программой Спасибо
В статье описан процесс настройки системы для автоматического начисления и списания балов Спасибо при оплате заказа на кассовой станции.
Настройки в системе
В группу Анализ чека (системы лояльности) добавьте скрипт:


procedureReceiptXMLAnalysis1001330(AXMLReceiptParameters: TXMLReceiptParameters);varp:integer;xml, PaymentTag, ExtInfo, CardInfo:string;beginxml := AXMLReceiptParameters.ReceiptXML;whilexml <>''dobeginp := pos('<PAYMENT ', xml);ifp =0thenexit;xml := copy(xml, p, length(xml));p := pos('/>', xml);PaymentTag := copy(xml,1, p +1);xml := copy(xml, p +2, length(xml));p := pos('exttransactioninfo="BANK:SBRF', PaymentTag);ifp >0thenbeginExtInfo := copy(PaymentTag, p + length('exttransactioninfo="'),length(PaymentTag));p := pos('"', ExtInfo);ExtInfo := copy(ExtInfo,1, p -1);p := pos('/PdsCard=', ExtInfo);ifp =0thenbeginp := pos('PdsCard=', ExtInfo);ifp =1thenCardInfo := copy(ExtInfo,1+ length('PdsCard='), length(ExtInfo))elseCardInfo :='';endelseCardInfo := copy(ExtInfo, p + length('/PdsCard='), length(ExtInfo));ifCardInfo <>''thenbeginp := pos(CardInfo,'/');ifp >0thenCardInfo := copy(CardInfo,1, p -1);AXMLReceiptParameters.CardCode := CardInfo;AXMLReceiptParameters.DoTransfer :=true;AXMLReceiptParameters.SilentMode :=true;end;end;end;end;- Назначьте скрипт интерфейсу SBRF_Spasibo созданному ранее

Автоматическое списание Спасибо
- В настройках созданного ранее MCR-алгоритма проверьте активность типа устройства Скрипты.
- В свойствах драйвера измените значение параметра RemindLoyalty на WithPayPass

- В настройках параметров самого терминала TlvEdit.exe измените значение параметра Возвращать промежуточный код ответа (DF7D) на По картам Сбербанка:

- В форме где будет использоваться функционал — здесь выбрана Редактирование заказа (быстрый чек) создайте копию предустановленного экземпляра формы, переименуйте ее и сохраните изменения

Откройте редактор формы, выделите компонент CheckView в строке OnOrderVerify добавьте скрипт:
ifAVerifyType = vtAfterPaythenCheckLoyaltyOnAuthorization;
В самом начале обработчика событий и форм вставьте скрипт
constminordersum =250;constSpasiboCurrencyCode =126;functionExtractPartFromExtTransactionInfo(ExtTransactionInfo:String;PartName:String):String;vari:Integer;s:string;begini:=pos(PartName,ExtTransactionInfo);ifi>1thenbegini:=pos('/'+PartName,ExtTransactionInfo);ifi>0theni:=i+1;end;ifi=0thens:=''elsebegins:=copy(ExtTransactionInfo,i+length(PartName),65535);i:=pos('/',s);ifi>0thenSetLength(s,i-1);end;Result:=s;end;procedurePerformLoyalyMCR(PayLine: TPayLine);vari:integer;CardCode:string;FirstNumbers:String;LastNumbers:String;BankName:String;beginCardCode := ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'PdsCard=');i:=pos(';',CardCode);ifi >0thenbeginLastNumbers:=copy(CardCode,i+1,255);SetLength(CardCode, i-1);endelseLastNumbers:='';FirstNumbers:=PayLine.CardNum;i:=pos('*',PayLine.CardNum);ifi>0thenSetLength(FirstNumbers, i-1);BankName:=ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'BANK:');// Slide a spasibo card//RK7.PerformMcrAlgorithSilent('BANK:'+BankName+';'+FirstNumbers+';'+LastNumbers+';'+CardCode, 1);RK7.PerformMcrAlgorithSilent(BankName+':'+CardCode+';'+LastNumbers,1);end;functionSpasiboOnAuthorize(PayLine: TPayLine):Boolean;vari, k:integer;CardCode:string;it: TCheckItem;McrPay: TMcrPay;a:double;Editor: TNumEditor;SpasiboExists:boolean;BankName:String;begin//Exit; //Uncomment me to disable auto write-off SB SPASIBO// Looking for payment in tsAuthoring stateResult:=False;a :=0;SpasiboExists :=False;fori :=0toRKCheck.CurrentOrder.Sessions.LinesCount -1dobeginit := RKCheck.CurrentOrder.Sessions.Lines[i];ifSYS.ObjectInheritsFrom(TObject(it),'TPayLine')thenbeginifit.Code = trunc(SpasiboCurrencyCode)thenSpasiboExists :=True;if(it<>PayLine)and(it.State <> disClosed)and(it.State <> disDeleted)thena := a + TPayLine(it).BasicSum;end;end;ifPayLine =NilthenExit;BankName:=ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'BANK:');if(PayLine.OriginalSum <= minordersum)orSpasiboExistsor(BankName<>'SBRF')thenExit;// Spasibo card code: between "PdsCard=" and "/"CardCode := ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'PdsCard=');ifcopy(CardCode,1,1)='H'thenCardCode := Copy(CardCode,2,255);// Slide a spasibo cardPerformLoyalyMCR(PayLine);Editor := TNumEditor(GUI.FindComponentByName('Editor'));fori :=0toRKCheck.CurrentOrder.Sessions.McrPays.Count -1dobeginMcrPay := TMcrPay(RKCheck.CurrentOrder.Sessions.McrPays.Items[i]);// Checking mcr-payment for spasibo cardif(McrPay.CardNum = CardCode)and(McrPay.Amount >= minordersum -1)thenbegink := GUI.MessageDlgEx('Предложите гостю оплатить заказ бонусами "Спасибо". '+'К оплате бонусов: '+ FloatToStr(McrPay.Amount), mtInformation,mbYes + mbNo + mbCancel,'Полностью;Частично;Не списывать');ifk = ID_YESthenbegin// MaximumRKCheck.DeleteCheckItem(PayLine);ifa =0thena := RKCheck.CurrentOrder.ToPaySumelsea := RKCheck.CurrentOrder.ToPaySum - a;ifa > McrPay.Amountthena := McrPay.Amountelsea := a -1;Editor.Text := FloatToStr(a);RKCheck.CreateCheckItem(rkrefCurrencies, IntToStr(McrPay.Code), McrPay.CardNum);Result:=True;endelseifk = ID_NOthenbegin// PartiallyRKCheck.DeleteCheckItem(PayLine);Result:=True;end;Exit;end;end;// Mcr-pay not found, Result=Falseend;procedureCheckLoyaltyOnAuthorization;vari:integer;it: TCheckItem;PayLine: TPayLine;beginPayLine :=Nil;fori :=0toRKCheck.CurrentOrder.Sessions.LinesCount -1dobeginit := RKCheck.CurrentOrder.Sessions.Lines[i];ifSYS.ObjectInheritsFrom(TObject(it),'TPayLine')thenbeginifTPayLine(it).TransactionStatus = tsAuthorizingthenPayLine := TPayLine(it)end;end;ifPayLine =NilthenExit;ifSpasiboOnAuthorize(PayLine)thenexit;RK7.PerformOperation(rkoReAuhorizePay,0);end;minordersum = 250 — минимальная сумма заказа при которой можно использовать оплату баллами "Спасибо", где:
SpasiboCurrencyCode =126 — это код валюты, у которой в качестве интерфейса выбран интерфейс Спасибо. В данном случае, при настройке Extspasibo.ini выбрана валюта с кодом 12
Начиная с версии 7.07.00.277 поддержан режим, когда зарезервированная сумма (рубль) оплачивается обязательно картой и без второго прикладывания карты. В этом случае скрипты такие:constminordersum =2;constSpasiboCurrencyCode =97;constRESERVE_VALUE =1.0;
functionExtractPartFromExtTransactionInfo(ExtTransactionInfo:String;PartName:String):String;vari:Integer;s:string;begini:=pos(PartName,ExtTransactionInfo);ifi>1thenbegini:=pos('/'+PartName,ExtTransactionInfo);ifi>0theni:=i+1;end;ifi=0thens:=''elsebegins:=copy(ExtTransactionInfo,i+length(PartName),65535);i:=pos('/',s);ifi>0thenSetLength(s,i-1);end;Result:=s;end;
procedurePerformLoyalyMCR(PayLine: TPayLine);vari:integer;CardCode:string;FirstNumbers:String;LastNumbers:String;BankName:String;beginCardCode := ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'PdsCard=');i:=pos(';',CardCode);ifi >0thenbeginLastNumbers:=copy(CardCode,i+1,255);SetLength(CardCode, i-1);endelseLastNumbers:='';FirstNumbers:=PayLine.CardNum;i:=pos('*',PayLine.CardNum);ifi>0thenSetLength(FirstNumbers, i-1);BankName:=ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'BANK:');// Slide a spasibo card//RK7.PerformMcrAlgorithSilent('BANK:'+BankName+';'+FirstNumbers+';'+LastNumbers+';'+CardCode, 1);RK7.PerformMcrAlgorithSilent(BankName+':'+CardCode+';'+LastNumbers,1);end;
functionPartialSpasiboPay(PayLine: TPayLine; MCRPay: TMCRPay; prepaid:double; toPay:double):boolean;varsourceValue, a:double;peio: TPayExtraInfoObj;Editor: TNumEditor;CurrCode:integer;beginEditor := TNumEditor(GUI.FindComponentByName('Editor'));peio := payLine.GetExtraInfoObj();sourceValue := payLine.BasicSum;CurrCode := PayLine.RefItem.Code;RKCheck.DeleteCheckItem(PayLine);Editor.Text := FloatToStr(toPay);RKCheck.CreateCheckItem(rkrefCurrencies, IntToStr(McrPay.Code), McrPay.CardNum);a := RKCheck.CurrentOrder.ToPaySum - prepaid - toPay;ifa > sourceValuethena := sourceValue;Editor.Text :='';RKCheck.CreatePayLine(CurrCode, a, peio);Result :=True;end;
functionSpasiboOnAuthorize(PayLine: TPayLine):Boolean;vari, k:integer;CardCode:string;it: TCheckItem;McrPay: TMcrPay;prepaid:double;SpasiboExists:boolean;BankName:String;toPay:double;newValStr:string;a:double;begin//Exit; //Uncomment me to disable auto write-off SB SPASIBOResult:=False;prepaid :=0;SpasiboExists :=False;fori :=0toRKCheck.CurrentOrder.Sessions.LinesCount -1dobeginit := RKCheck.CurrentOrder.Sessions.Lines[i];ifSYS.ObjectInheritsFrom(TObject(it),'TPayLine')thenbeginifit.Code = trunc(SpasiboCurrencyCode)thenSpasiboExists :=True;if(it<>PayLine)and(it.State <> disClosed)and(it.State <> disDeleted)thenprepaid := prepaid + TPayLine(it).BasicSum;end;end;ifPayLine =NilthenExit;BankName:=ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'BANK:');//gui.showmessage('BankName: '+BankName+' paid='+floattostr(prepaid));if(PayLine.OriginalSum <= minordersum)orSpasiboExistsor(BankName<>'SBRF')thenExit;// Spasibo card code: between "PdsCard=" and "/"CardCode := ExtractPartFromExtTransactionInfo(PayLine.ExtTransactionInfo,'PdsCard=');ifcopy(CardCode,1,1)='H'thenCardCode := Copy(CardCode,2,255);// Slide a spasibo cardPerformLoyalyMCR(PayLine);//gui.showmessage('McrPays.Count= '+inttostr(RKCheck.CurrentOrder.Sessions.McrPays.Count));fori :=0toRKCheck.CurrentOrder.Sessions.McrPays.Count -1dobeginMcrPay := TMcrPay(RKCheck.CurrentOrder.Sessions.McrPays.Items[i]);// Checking mcr-payment for spasibo cardif(McrPay.CardNum = CardCode)and(McrPay.Amount >= minordersum - RESERVE_VALUE)thenbegina := prepaid;ifa < RESERVE_VALUEthena := RESERVE_VALUE;toPay := RKCheck.CurrentOrder.ToPaySum - a;iftoPay > McrPay.AmountthentoPay := McrPay.Amount;repeatk := GUI.MessageDlgEx('Предложите гостю оплатить заказ бонусами "Спасибо". '+'Можно потратить бонусов: '+ FloatToStr(toPay), mtInformation,mbYes + mbNo + mbCancel,'Полностью;Частично;Не списывать');ifk = ID_YESthenResult := PartialSpasiboPay(PayLine, McrPay, prepaid, toPay)elseifk = ID_NOthenbegin// PartiallynewValStr := gui.InputBox('','Введите сумму баллов "Спасибо", которую надо потратить, не менее '+FloatToStr(minordersum - RESERVE_VALUE), floattostr(toPay),true);a := StrToFloat(newValStr);ifa < minordersum -1thenbegingui.showMessage('Слишком маленькая сумма, нельзя тратить менее '+FloatToStr(minordersum - RESERVE_VALUE));endelsebeginifa > toPaythena := toPay;Result := PartialSpasiboPay(PayLine, McrPay, prepaid, a);Exit;end;end;untilk <> ID_NO;Exit;end;end;// Mcr-pay not found, Result=Falseend;
procedureCheckLoyaltyOnAuthorization;vari:integer;it: TCheckItem;PayLine: TPayLine;beginPayLine :=Nil;// Looking for payment in tsAuthoring statefori :=0toRKCheck.CurrentOrder.Sessions.LinesCount -1dobeginit := RKCheck.CurrentOrder.Sessions.Lines[i];ifSYS.ObjectInheritsFrom(TObject(it),'TPayLine')thenbeginifTPayLine(it).TransactionStatus = tsAuthorizingthenPayLine := TPayLine(it)end;end;ifPayLine =NilthenExit;ifSpasiboOnAuthorize(PayLine)thenexit;RK7.PerformOperation(rkoReAuhorizePay,0);end;
- Сохраните изменения
Модифицированную форму назначьте для схемы форм, которая будет применяться на станции
Настроенную схему форм добавьте в использование.
Пользовательский сценарий работы на кассовой станции
В данном примере использован сценарий работы в быстром чеке.
- Наполните заказ позициями меню
Если стоимость заказа меньше указанного в скрипте значение const minordersum = 250 — процесс расчета аналогичен классической оплате по банковской карте, при выборе формы чека с настроенной информацией о статусах в системе "Спасибо" можно наблюдать количество начисленных балов - Нажмите кнопку Оплатить Рубли > Кредитные карты > Валюта VISA

- Будет получено сообщение о подтверждении операции

Подтверждение можно исключить, если назначить валюте Автозаполнение в значение Вся сумма. - Согласитесь с подтверждением, далее произойдет оплата:


- После настроек печати чека вы увидите начисление баллов Спасибо, при печати

- Сумма заказа превышает порог, назначенный переменной minordersum, в нашем случае это 250 рублей.
После прохождения Оплатить Рубли > Кредитные карты > Валюта VISA будет получено сообщение, формируемое в скрипте:
- От выбора кнопки зависит дальнейший расчет:
- Полностью — бонусами оплачивается вся сумма минус 1 рубль, его оплачиваем наличными или банковской картой


- Частично — укажите сумму частичной оплаты балами и выберите валюту, указанную при настройке Extspasibo.ini для оплаты балами Спасибо. В данном случае выбрана валюта с кодом 126

Остаток доплатите рублями

- Не списывать — простая оплата картой, с начислением баллов по программе "Спасибо"


- Полностью — бонусами оплачивается вся сумма минус 1 рубль, его оплачиваем наличными или банковской картой