Skip to content

Commit e51d392

Browse files
author
Thomas Danzl
committed
#10 added docs about how payment vendor side tip is handled + extend HOWTO_01 and HOWTO_08 to log the tip information nicely on the console
1 parent d55c7bd commit e51d392

6 files changed

Lines changed: 52 additions & 17 deletions

File tree

HOWTO_01_Payment_csharp/Program.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,12 @@ static async Task Main(string[] args)
6363
// - the terminal ID is not defined here (null) so the request will be processed by all available terminals for the cashbox
6464
// IMPORTANT: In a real setup you might want to define a specific terminal ID here to target a specific payment terminal device; especially when multiple payment terminals are registered for the same cashbox!
6565
// - we provide the operation ID to be able to retry in case of failure
66-
ExecutedResult<PayResponse> payResult = await ftPosAPI.Pay.PaymentAsync(new PayItemRequest
66+
var payItemRequest = new PayItemRequest
6767
{
6868
Description = "Card",
6969
Amount = amount,
70-
}, fiskaltrust.Payment.DTO.PaymentProtocol.use_auto, null, operationId);
70+
};
71+
ExecutedResult<PayResponse> payResult = await ftPosAPI.Pay.PaymentAsync(payItemRequest, fiskaltrust.Payment.DTO.PaymentProtocol.use_auto, null, operationId);
7172

7273
/////////////////////////////////////////////////////////////////////////////////////////////////
7374
// Check Result
@@ -80,7 +81,7 @@ static async Task Main(string[] args)
8081
{
8182
// YES --> SUCCESS: Payment was successful
8283
PayResponse payResp = await payResult.Operation.GetResponseAsAsync();
83-
Utils.DumpToLogger(payResp);
84+
Utils.DumpToLogger(payResp, payItemRequest);
8485
break;
8586
}
8687
else

HOWTO_01_Payment_csharp/README.MD

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,22 @@ Several critical error scenarios must be managed carefully to prevent double pay
2525
- The response is not received within the expected time frame (HTTP timeout), which can be simulated by a device losing internet connectivity during payment execution.
2626

2727
In all of these cases, the solution is to resend the original request using the identical operation ID and request body. The backend will then return the final result of the operation.
28+
29+
## Special case - payment vendor added TIP
30+
31+
In many payment vendor apps it is possible to add a tip to the payment amount.
32+
Flow example in a restaruant:
33+
- Guest asks for the bill
34+
- Waiter triggers to create the bill at the POS (e.g. mobile device)
35+
- The POS on the mobile device pushes the amount (for example 10€) to be paid to the configured payment app (via POS System API and the fiskaltrust InStore App)
36+
- The payment app opens and the waiter hands the mobile device over to the guest
37+
- The guest sees a TIP entry screen and adds a tip of 2€
38+
- The guests now pays the full sum of 12€
39+
- The payment app reports a paid amount of 12€ (including 2€ of tip)
40+
- The fiskaltrust InStore App / POS System API does report back the following in the payment response (see also example in the POS System API docs):
41+
- 2 pay items
42+
- Pay item 1: The fully paid amount with the receipt -> 12€
43+
- Pay item 2: The tip with negative amount -> -2€
44+
- sum of the 2 pay items is the orginal requested amount of 10€
45+
46+
NOTE: The tip can be calculated by simply substracting the requested amount from the paid amount (12-10 = 2€ tip) or alternatively from the 2nd pay item (-2 * -1 = 2€ tip).

HOWTO_08_pay_sign_issue_csharp/Program.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ static async Task Main(string[] args)
5454
decimal totalAmount = chargeItems.Sum(ci => ci.Amount);
5555
Logger.LogInfo($"Total amount to pay: {totalAmount} EUR");
5656

57+
PayItemRequest payRequest = new()
58+
{
59+
Amount = totalAmount,
60+
Description = "Card"
61+
};
5762
var payRunner = new ftPosAPIOperationRunner();
5863
(PayResponse? pResp, string errorMsg) = await payRunner.Execute<PayResponse>(async () =>
5964
{
60-
PayItemRequest payRequest = new()
61-
{
62-
Amount = totalAmount,
63-
Description = "Card"
64-
};
65+
6566
return await ftPosAPI.Pay.PaymentAsync(payRequest, PaymentProtocol.use_auto, null, payRunner.OperationID);
6667
});
6768

@@ -72,7 +73,7 @@ static async Task Main(string[] args)
7273
else
7374
{
7475
Logger.LogInfo("Payment succeeded.");
75-
Utils.DumpToLogger(pResp);
76+
Utils.DumpToLogger(pResp, payRequest);
7677

7778
///////////////////////////////////////////////////////////////////////////////////////////////////////
7879
///

README.MD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Any payment amount will return a SUCCESS response, except for the following defi
8080
| 30000,10 | DECLINED |
8181
| 30000,20 | TIMEOUT (returned as an error message as no other option is available yet) |
8282
| 30000,40 | CANCELLED BY USER |
83-
| 30000,50 | SUCCESS with added guest tip |
83+
| 30000,50 | SUCCESS with added guest tip (see [HOWTO_01_Payment](HOWTO_01_Payment_csharp/README.MD) on how to handle such a tip) |
8484
| 30000,60 | SUCCESS after 1-minute delay |
8585
| 30000,70 | SUCCESS after 3-minute delay |
8686
| 30000,80 | SUCCESS after 6-minute delay |

libPosSystemAPI.Test/IntegrationTestsPayment.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public async Task TestPayment()
3939
Assert.NotNull(payResponse);
4040
Assert.True(payResponse.Protocol == Payment.DTO.PaymentProtocol.use_auto);
4141
Assert.NotNull(payResponse.ftPayItems);
42-
// dummy payment provider should return exactly one pay item (as we did not execute a 30000,50 which would result in multiple pay items as there would be a tip)
42+
// dummy payment provider should return exactly one pay item
4343
Assert.Single(payResponse.ftPayItems);
4444

4545
PayItem pi = payResponse!.ftPayItems![0];

libPosSystemAPI/PosAPIUtils/Utils.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ public static (Guid ftCashboxID, string ftCashboxAccessToken)? GetCashboxCredent
182182
return (ftCashboxID, ftCashboxAccessToken);
183183
}
184184

185-
public static void DumpToLogger(PayResponse payResp)
185+
public static void DumpToLogger(PayResponse payResp, PayItemRequest? payItemRequest = null)
186186
{
187187
Logger.LogInfo("Payment successful! Queue ID: " + payResp.ftQueueID);
188188
if (payResp.ftPayItems == null || payResp.ftPayItems.Length == 0)
@@ -193,9 +193,15 @@ public static void DumpToLogger(PayResponse payResp)
193193

194194
// pretty log the response (JSON)
195195
Logger.LogDebug("PayResponse: " + JsonSerializer.Serialize(payResp, new JsonSerializerOptions { WriteIndented = true }));
196-
197-
foreach (PayItem ftPayItem in payResp.ftPayItems)
196+
if (payItemRequest != null)
197+
{
198+
Logger.LogInfo("Requested Payment:");
199+
Logger.LogInfo($"- Amount: {payItemRequest.Amount}");
200+
}
201+
Logger.LogInfo("Received Pay Response:");
202+
for (int i = 0; i < payResp.ftPayItems.Length; i++)
198203
{
204+
PayItem ftPayItem = payResp.ftPayItems[i];
199205
var payItemCaseData = ftPayItem.GetPayItemCaseData();
200206

201207
Dictionary<string, JsonElement>? providerInfo = payItemCaseData?.Provider;
@@ -204,10 +210,18 @@ public static void DumpToLogger(PayResponse payResp)
204210
{
205211
protocol = protocolValue.GetString() ?? "ERROR: invalid type";
206212
}
207-
Logger.LogInfo($"- {protocol}:");
213+
Logger.LogInfo($"- PayItem {i+1}");
214+
if (protocol != "unknown") Logger.LogInfo($"\t\tprotocol: {protocol}");
215+
Logger.LogInfo($"\t\tAmount: {ftPayItem.Amount}");
216+
if (payItemRequest != null)
217+
{
218+
decimal tipAmount = ftPayItem.Amount - payItemRequest.Amount;
219+
Logger.LogInfo($"\t\t\tIncluded Tip Amount: {tipAmount}");
220+
}
221+
Logger.LogInfo("\t\tReceipt:");
208222
if (payItemCaseData?.Receipt == null)
209223
{
210-
Logger.LogInfo("\t WARNING: No receipt info received!");
224+
Logger.LogInfo("\t\t\t WARNING: No receipt info received!");
211225
}
212226
else
213227
{
@@ -216,7 +230,7 @@ public static void DumpToLogger(PayResponse payResp)
216230
{
217231
foreach (string line in payReceipt)
218232
{
219-
Logger.LogInfo($"\t{line}");
233+
Logger.LogInfo($"\t\t\t{line}");
220234
}
221235
}
222236
}

0 commit comments

Comments
 (0)