/// <summary> /// /// </summary> /// <param name="request"></param> public override Issue SendPaymentRequest(PaymentRequest request) { byte[] bytes = PrepareMessage(request); // Step 1 Terminal.Connect(); Terminal.Write(ENQ); if (Terminal.ReadOne() != ACK) { Terminal.Disconnect(); return(Issue.Failure("Terminal did not respond ACK after login")); } Terminal.Write(bytes); if (Terminal.ReadOne() != ACK) { Terminal.Disconnect(); return(Issue.Failure("Terminal did not respond ACK after payment request")); } Terminal.Write(EOT); // Step 2 if (!Terminal.WaitData(WAITING_TIME)) { Terminal.Disconnect(); return(Issue.Failure("Terminal response was empty")); } if (Terminal.ReadOne() != ENQ) { Terminal.Disconnect(); return(Issue.Failure("Terminal did not respond ENQ after payment waiting")); } Terminal.Write(ACK); Terminal.WaitData(WAITING_TIME); bytes = Terminal.ReadAll(); Terminal.Write(ACK); Terminal.Disconnect(); PaymentResponse response = null; try { response = PrepareResponse(bytes); } catch (Exception e) { return(Issue.Failure(e.Message)); } if (response.Status == ConcertProtocol.STATUS_SUCCESS) { return(Issue.Success("Payment success", response)); } else { return(Issue.Failure("Payment failure", response)); } }
/// <summary> /// /// </summary> /// /// Structure d'une réponse E /// /// xx : N° Caisse : Identifiant de la caisse /// x : STATUT : Etat de la transaction /// = 0 → si transaction acceptée /// = 7 → si transaction non aboutie /// xxxxxxxx : MONTANT : Montant exprimé dans la plus petite unité de fractionnement /// complété à gauche par des zéros. Indiquer un montant positif. /// x : MODE : Mode de règlement, /// = 1 → traitement carte uniquement, /// = C → traitement chèque (si pas d'appli chèque, message "FONCTIONNON IMPLEMENTEE ") /// = autre → choix "CARTE CHEQUE" /// xx...55..xx : REP : si l’application, ayant traitée le débit, a renseigné le champ REP, celui-ci est remonté. /// xxx : DEVISE : Code numérique de la devise /// (pour info: 250 pour FRF, 978 pour EUR) /// = code numérique connu → traitement du débit dans la devise spécifiée /// = code numérique inconnu → affichage "FONCTION IMPOSSIBLE" /// = autre → choix "CARTE CHEQUE" /// xxxxxxxxxx : PRIVE : Données privées remontées par l’application. /// par défaut = 10 caractères (à blanc lorsqu’elle ne véhicule rien /// /// <param name="message"></param> /// <returns></returns> public PaymentResponse PrepareResponse(byte[] bytes) { ByteStream stream = new ByteStream(bytes); if (!stream.Available()) { throw new ProtocolException("Terminal response is empty"); } // at least STX ETX LRC if (!stream.Available(3)) { throw new ProtocolException("Laformed terminal response : " + BitConverter.ToString(bytes)); } // Must start with STX if (stream.ReadFirstByte() != STX) { throw new ProtocolException("Response does not start with ETX : " + BitConverter.ToString(bytes)); } // Read payload and compute LRC List <byte> payload = new List <byte>(); stream.ReadBytesUntil(ETX, true, payload); int lrc = stream.ReadLastByte(); int lrcExpected = LRC(payload.ToArray()); if (lrcExpected != lrc) { throw new ProtocolException(String.Format("Wrong LRC for {0} Expected {1}, Given {2} ", BitConverter.ToString(payload.ToArray()), lrcExpected, lrc)); } // now parse payload, reset the stream first with payload stream.Close(); stream.Dispose(); payload.RemoveAt(payload.Count - 1); // Delete ETX stream = new ByteStream(payload.ToArray()); PaymentResponse response = new PaymentResponse(); response.Pos = stream.ReadStringToShort(2); response.Status = stream.ReadChar(); response.Amount = (float)stream.ReadStringToInt(8) / 100; response.Mode = stream.ReadChar(); // If content is available if (stream.BytesToRead() > 13) { response.Content = stream.ReadString(55); } response.Currency = stream.ReadStringToShort(3); response.Data = stream.ReadString(10); stream.Close(); stream.Dispose(); return(response); }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="response"></param> /// <returns></returns> public static Issue Success(string message, PaymentResponse response) { return(new Issue(SUCCESS, message, response)); }
/// <summary> /// /// </summary> /// <param name="message"></param> /// <param name="response"></param> /// <returns></returns> public static Issue Failure(string message, PaymentResponse response) { return(new Issue(FAILURE, message, response)); }
/// <summary> /// /// </summary> protected Issue(string type, string message, PaymentResponse response) { Type = type; Message = message; Response = response; }