· 6 years ago · Aug 06, 2019, 05:14 PM
1#include <stdio.h>
2
3#include "hw.h"
4#include "SDK/PaymentController.h"
5
6#define DEBUG_ENABLED 1
7#define AUTH 1
8#define GET_READER_INFO 0
9#define TEST_LINKED_CARD 0
10#define TEST_CARD_PAYMENT 1
11#define TEST_SCHEDULE 0
12#define TEST_REVERSE 0
13#define TEST_PURCHASES 0
14#define TEST_PRODUCT 0
15#define TEST_TAGS 0
16#define TEST_TRANSACTION 0
17#define TEST_FISCALIZE 0
18#define TEST_PREPARE 0
19#define TEST_REVERSE_LAST_TRANSACTION 0
20
21#define EMAIL ""
22#define SECRET_KEY ""
23#define AMOUNT 1.0
24#define AMOUNT_REVERSE 0.0
25#define TRANSACTION_ID "2f809619-d26f-48f2-a523-8a5044224400"
26#define RECEIPT_EMAIL "test@mail.de"
27#define RECEIPT_PHONE "+73211232312"
28#define ACQUIRER_CODE NULL //"ACQ_CODE"
29#define PRODUCT_FIELD_TEST_DATA "field data"
30
31// member variables
32const char *mTransactionId = NULL;
33
34void startTransactionAction(const char *transactionId)
35{
36 mTransactionId = transactionId;
37 fprintf(stderr, "TransactionID:%s\n", transactionId);
38}
39
40void addProductData(Ibox_PaymentContext *paymentContext, Ibox_Result_Authentication *authResult)
41{
42 if (paymentContext)
43 {
44 if (authResult && authResult->productsCount)
45 {
46 Ibox_Product *product = NULL;
47 for (int i = 0; i < authResult->productsCount; i++)
48 {
49 Ibox_Product *localProduct = authResult->products[i];
50 if (!localProduct->preparable)
51 {
52 product = localProduct;
53 break;
54 }
55 }
56
57 if (product && product->fieldsCount)
58 {
59 int productDataCount = 0;
60 Ibox_ProductField **buffer = calloc(product->fieldsCount, sizeof(Ibox_ProductField *));
61
62 for (int i = 0; i < product->fieldsCount; i++)
63 {
64 Ibox_ProductField *field = product->fields[i];
65 if (field->state == Ibox_ProductField_State_ENABLED && field->type == Ibox_ProductField_Type_TEXT)
66 {
67 if (field->defaultValue )
68 field->value = field->defaultValue;
69 else
70 field->value = PRODUCT_FIELD_TEST_DATA;
71
72 memcpy(buffer + productDataCount, &field, sizeof(Ibox_ProductField *));
73 productDataCount++;
74 }
75 }
76
77 if (productDataCount)
78 {
79 Ibox_ProductField **productData = calloc(productDataCount, sizeof(Ibox_ProductField *));
80 for (int i = 0; i < productDataCount; i++)
81 {
82 Ibox_ProductField *field = buffer[i];
83 memcpy(productData + i, &field, sizeof(Ibox_ProductField *));
84 }
85
86 paymentContext->product = product;
87 paymentContext->productData = productData;
88 paymentContext->productDataCount = productDataCount;
89 }
90
91 free(buffer);
92 }
93 }
94 else
95 {
96 Ibox_Product *product = calloc(1, sizeof(Ibox_Product));
97 product->title = "Тестовый продукт 1";
98 product->code = "PRODUCT_TEST";
99
100 Ibox_ProductField *field1 = calloc(1, sizeof(Ibox_ProductField));
101 field1->title = "Поле один";
102 field1->code = "FIELD_1";
103 field1->value = "Тестовое значение";
104
105 Ibox_ProductField *field2 = calloc(1, sizeof(Ibox_ProductField));
106 field2->title = "Поле два";
107 field2->code = "FIELD_2";
108 field2->value = "Тестовое значение";
109
110 int productDataCount = 2;
111 Ibox_ProductField **productData = calloc(productDataCount, sizeof(Ibox_ProductField *));
112 memcpy(productData, &field1, sizeof(Ibox_ProductField *));
113 memcpy(productData + 1, &field2, sizeof(Ibox_ProductField *));
114
115 paymentContext->product = product;
116 paymentContext->productData = productData;
117 paymentContext->productDataCount = productDataCount;
118 }
119 }
120}
121
122void addPurchases(Ibox_PaymentContext *paymentContext, Ibox_ReverseContext *reverseContext)
123{
124 if (paymentContext || reverseContext)
125 {
126 /*
127 Ibox_Purchase *purchase1 = calloc(1, sizeof(Ibox_Purchase));
128
129 Ibox_Tag *tag1 = calloc(1, sizeof(Ibox_Tag));
130 tag1->code = "1030";
131 tag1->value = "Позиция 1";
132
133 Ibox_Tag *tag2 = calloc(1, sizeof(Ibox_Tag));
134 tag2->code = "1079";
135 tag2->value = "120.0";
136
137 Ibox_Tag *tag3 = calloc(1, sizeof(Ibox_Tag));
138 tag3->code = "1023";
139 tag3->value = "2";
140
141 Ibox_Tag *tag4 = calloc(1, sizeof(Ibox_Tag));
142 tag4->code = "1199";
143 tag4->value = "2";
144
145 int tagsCount = 4;
146 Ibox_Tag **tags = calloc(tagsCount, sizeof(Ibox_Tag *));
147 memcpy(tags, &tag1, sizeof(Ibox_Tag *));
148 memcpy(tags + 1, &tag2, sizeof(Ibox_Tag *));
149 memcpy(tags + 2, &tag3, sizeof(Ibox_Tag *));
150 memcpy(tags + 3, &tag4, sizeof(Ibox_Tag *));
151
152 purchase1->tagsCount = tagsCount;
153 purchase1->tags = tags;
154
155 Ibox_Purchase *purchase2 = calloc(1, sizeof(Ibox_Purchase));
156 purchase2->title = "Позиция 2";
157 purchase2->price = 100.0;
158 purchase2->quantity = 1.2;
159 int taxesCount = 1;
160 char **taxes = calloc(taxesCount, sizeof(char *));
161 char *tax = "VAT1800";
162 memcpy(taxes, &tax, sizeof(char *));
163 purchase2->taxesCount = taxesCount;
164 purchase2->taxes = taxes;
165
166 int purchasesCount = 2;
167 Ibox_Purchase **purchases = calloc(purchasesCount, sizeof(Ibox_Purchase *));
168 memcpy(purchases, &purchase1, sizeof(Ibox_Purchase *));
169 memcpy(purchases + 1, &purchase2, sizeof(Ibox_Purchase *));
170
171 if (paymentContext)
172 {
173 paymentContext->purchasesCount = purchasesCount;
174 paymentContext->purchases = purchases;
175 }
176 else if (reverseContext)
177 {
178 reverseContext->purchasesCount = purchasesCount;
179 reverseContext->purchases = purchases;
180 }
181 */
182
183 //amount = 380
184 const char *purchasesJson = "{\"Purchases\": [{\"1030\": \"Позиция 1\", \"1079\": 120, \"1023\": 2, \"1199\": 2}, {\"Title\": \"Позиция 2\", \"Price\": 100, \"Quantity\": 1.4, \"TaxCode\": [\"VAT1800\"]}]}";
185 //amount = 190
186 //const char *purchasesJson = "{\"Purchases\": [{\"1030\": \"Позиция 1\", \"1079\": 120, \"1023\": 1, \"1199\": 2}, {\"Title\": \"Позиция 2\", \"Price\": 100, \"Quantity\": 0.7, \"TaxCode\": [\"VAT1800\"]}]}";
187 if (paymentContext)
188 paymentContext->purchasesJson = purchasesJson;
189 else if (reverseContext)
190 reverseContext->purchasesJson = purchasesJson;
191 }
192}
193
194void addTags(Ibox_PaymentContext *paymentContext, Ibox_ReverseContext *reverseContext)
195{
196 if (paymentContext || reverseContext)
197 {
198 /*
199 Ibox_Tag *tag1 = calloc(1, sizeof(Ibox_Tag));
200 tag1->code = "1005";
201 tag1->value = "Тcет666";
202
203
204 Ibox_Tag *tag2 = calloc(1, sizeof(Ibox_Tag));
205 tag2->code = "1008";
206 tag2->value = "email@test.moc";
207
208 int tagsCount = 2;
209 Ibox_Tag **tags = calloc(tagsCount, sizeof(Ibox_Tag *));
210 memcpy(tags, &tag1, sizeof(Ibox_Tag *));
211 memcpy(tags + 1, &tag2, sizeof(Ibox_Tag *));
212
213 if (paymentContext)
214 {
215 paymentContext->tagsCount = tagsCount;
216 paymentContext->tags = tags;
217 }
218 else if (reverseContext)
219 {
220 reverseContext->tagsCount = tagsCount;
221 reverseContext->tags = tags;
222 }
223 */
224
225 const char *tagsJson = "{\"1005\": \"тсет джсон\", \"1008\": \"emailJS@test.moc\"}";
226 if (paymentContext)
227 paymentContext->tagsJson = tagsJson;
228 else if (reverseContext)
229 reverseContext->tagsJson = tagsJson;
230 }
231}
232
233int main(void)
234{
235 Ibox_Result_Authentication *authResult = NULL;
236 Ibox_PaymentController_SetSendWebRequestAction(&sendWebRequest);
237 Ibox_PaymentController_SetSendReaderRequestAction(&sendReaderRequest);
238 Ibox_PaymentController_SetStartTransactionAction(&startTransactionAction);
239 Ibox_PaymentController_SetCredentials(EMAIL, SECRET_KEY);
240 Ibox_PaymentController_SetDebugEnabled(DEBUG_ENABLED);
241 Ibox_PaymentController_ReaderSoundEnabled(1);
242
243 mTransactionId = NULL;
244
245 fprintf(stderr, "Version:%s\n", Ibox_PaymentController_Version());
246
247 if (GET_READER_INFO)
248 {
249 fprintf(stderr, "Getting reader info.\n");
250
251 Ibox_Result_ReaderId *readerIdResult = Ibox_PaymentController_ReaderId();
252 if (!readerIdResult->errorCode)
253 {
254 fprintf(stderr, "ReaderId:%s\n", readerIdResult->id);
255 }
256 else
257 {
258 fprintf(stderr, "Reader id error.\n");
259 }
260 free(readerIdResult);
261
262 Ibox_Result_ReaderInfo *readerInfoResult = Ibox_PaymentController_ReaderInfo();
263 if (!readerInfoResult->errorCode)
264 {
265 fprintf(stderr, "BootloaderVersion:%s\n", readerInfoResult->bootloaderVersion);
266 fprintf(stderr, "FirmwareVersion:%s\n", readerInfoResult->firmwareVersion);
267 fprintf(stderr, "HardwareVersion:%s\n", readerInfoResult->hardwareVersion);
268 }
269 else
270 {
271 fprintf(stderr, "Reader info error.\n");
272 }
273 free(readerInfoResult);
274 fprintf(stderr, "\n\n");
275 }
276
277 if (AUTH)
278 {
279 fprintf(stderr, "Authenticating.\n");
280
281 authResult = Ibox_PaymentController_Authentication();
282 if (!authResult->errorCode)
283 {
284 Ibox_Account *account = authResult->account;
285 if (account)
286 {
287 fprintf(stderr, "Account data:\n%s\n", account->name);
288 fprintf(stderr, "%s\n", account->clientLegalAddress);
289 fprintf(stderr, "%s\n", account->branchPhone);
290
291 if (account->paymentOptionsCount)
292 {
293 Ibox_PaymentOption *paymentOption = account->paymentOptions[0];
294 fprintf(stderr, "First acquirer name: %s\n", paymentOption->acquirer->name);
295 fprintf(stderr, "First acquirer code: %s\n", paymentOption->acquirer->code);
296 }
297 }
298 }
299 else
300 {
301 fprintf(stderr, "Authentication error:\n%s\n", authResult->errorMessage);
302 }
303
304 fprintf(stderr, "\n\n");
305 }
306
307 if (TEST_LINKED_CARD)
308 {
309 fprintf(stderr, "Linked card payment.\n");
310
311 Ibox_Result_LinkedCards *linkedCardsResult = Ibox_PaymentController_LinkedCards();
312 if (!linkedCardsResult->errorCode)
313 {
314 for (int i = 0; i < linkedCardsResult->linkedCardsCount; i++)
315 {
316 Ibox_LinkedCard *linkedCard = linkedCardsResult->linkedCards[i];
317 fprintf(stderr, "PANMasked: %s\n", linkedCard->panMasked);
318 fprintf(stderr, "CardExp: %s\n", linkedCard->cardExpiration);
319 }
320 }
321
322 if (!Ibox_PaymentController_IsReaderConected())
323 {
324 fprintf(stderr, "Reader disconnected.\n");
325 }
326 else
327 {
328 fprintf(stderr, "Link a card.\n");
329 Ibox_Result_ReaderCheckCard *readerCheckCardResult = Ibox_PaymentController_GetCardData();
330 if (!readerCheckCardResult->errorCode)
331 {
332 Ibox_Result_AddLinkedCard *addLinkedCardResult = Ibox_PaymentController_AddLinkedCardWithReaderData(readerCheckCardResult);
333 if (!addLinkedCardResult->errorCode)
334 {
335 Ibox_LinkedCard *linkedCard = addLinkedCardResult->linkedCard;
336 fprintf(stderr, "Linked card data:\n");
337
338 fprintf(stderr, "CardholderName: %s\n", linkedCard->cardholderName);
339 fprintf(stderr, "PANMasked: %s\n", linkedCard->panMasked);
340 fprintf(stderr, "CardType: %s\n", linkedCard->cardType);
341 fprintf(stderr, "CardExp: %s\n", linkedCard->cardExpiration);
342
343 Ibox_PaymentContext *paymentContext = calloc(1, sizeof(Ibox_PaymentContext));
344 paymentContext->inputType = Ibox_PaymentController_InputType_LINKED_CARD;
345 paymentContext->amount = AMOUNT;
346 paymentContext->description = "Description of transaction";
347 paymentContext->linkedCardId = linkedCard->id;
348 paymentContext->singleStepAuth = 1;
349 paymentContext->receiptEmail = RECEIPT_EMAIL;
350 paymentContext->receiptPhone = RECEIPT_PHONE;
351 paymentContext->acquirerCode = ACQUIRER_CODE;
352
353 if (TEST_PURCHASES)
354 addPurchases(paymentContext, NULL);
355
356 if (TEST_PRODUCT)
357 addProductData(paymentContext, authResult);
358
359 Ibox_Result_Submit *submitResult = Ibox_PaymentController_StartPayment(paymentContext);
360 if (!submitResult->errorCode)
361 {
362 fprintf(stderr, "Payment done!\n");
363 }
364 else
365 {
366 fprintf(stderr, "Payment error: %s\n", submitResult->errorMessage);
367 }
368
369 free(submitResult);
370 free(paymentContext);
371
372 Ibox_Result *removeLinkedCardResult = Ibox_PaymentController_RemoveLinkedCard(linkedCard->id);
373 if (!removeLinkedCardResult->errorCode)
374 {
375 fprintf(stderr, "Remove linked card done!\n");
376 }
377 else
378 {
379 fprintf(stderr, "Remove linked card error: %s\n", removeLinkedCardResult->errorMessage);
380 }
381 free(removeLinkedCardResult);
382 }
383 else
384 {
385 fprintf(stderr, "Add linked card error:\n%s\n", addLinkedCardResult->errorMessage);
386 }
387 }
388 else
389 {
390 fprintf(stderr, "Reader check card error:\n%s\n", readerCheckCardResult->errorMessage);
391 }
392 free(readerCheckCardResult);
393 }
394
395 fprintf(stderr, "\n\n");
396 }
397
398 if (TEST_CARD_PAYMENT)
399 {
400 fprintf(stderr, "Card payment.\n");
401
402 Ibox_PaymentContext *paymentContext = calloc(1, sizeof(Ibox_PaymentContext));
403 paymentContext->inputType = Ibox_PaymentController_InputType_CARD;
404 paymentContext->currencyType = Ibox_PaymentController_CurrencyType_RUB;
405 paymentContext->amount = AMOUNT;
406 paymentContext->description = "Description of transaction";
407 paymentContext->singleStepAuth = 1;
408 paymentContext->receiptEmail = RECEIPT_EMAIL;
409 paymentContext->receiptPhone = RECEIPT_PHONE;
410 paymentContext->acquirerCode = ACQUIRER_CODE;
411
412 if (TEST_TAGS)
413 addTags(paymentContext, NULL);
414
415 if (TEST_PURCHASES)
416 addPurchases(paymentContext, NULL);
417
418 if (TEST_PRODUCT)
419 addProductData(paymentContext, authResult);
420
421 Ibox_Result_Submit *submitResult = Ibox_PaymentController_StartPayment(paymentContext);
422 if (!submitResult->errorCode)
423 fprintf(stderr, "Payment done!\n");
424 else
425 fprintf(stderr, "Payment error: %s\n", submitResult->errorMessage);
426
427 free(submitResult);
428 free(paymentContext);
429 fprintf(stderr, "\n");
430 }
431
432 if (TEST_REVERSE)
433 {
434 const char *transactionId = NULL;
435 if (TEST_REVERSE_LAST_TRANSACTION && mTransactionId)
436 transactionId = mTransactionId;
437 else
438 transactionId = TRANSACTION_ID;
439
440 if (transactionId)
441 {
442 Ibox_ReverseContext *reverseContext = calloc(1, sizeof(Ibox_ReverseContext));
443 reverseContext->transactionId = transactionId;
444 reverseContext->amountReverse = AMOUNT_REVERSE;
445 reverseContext->forceReturn = 0;
446 reverseContext->purchasesCount = 0;
447 reverseContext->purchases = NULL;
448 reverseContext->purchasesJson = NULL;
449
450 if (TEST_PURCHASES)
451 addPurchases(NULL, reverseContext);
452
453 if (TEST_TAGS)
454 addTags(NULL, reverseContext);
455
456 Ibox_Result_Reverse *reverseResult = Ibox_PaymentController_StartReverse(reverseContext);
457 if (!reverseResult->errorCode)
458 fprintf(stderr, "Reverse done!\n");
459 else
460 fprintf(stderr, "Reverse error: %s\n", reverseResult->errorMessage);
461
462 free(reverseResult);
463 free(reverseContext);
464 }
465 }
466
467 if (TEST_SCHEDULE)
468 {
469 Ibox_ScheduleContext *scheduleContext = calloc(1, sizeof(Ibox_ScheduleContext));
470 scheduleContext->currencyType = Ibox_PaymentController_CurrencyType_RUB;
471 scheduleContext->amount = AMOUNT;
472 scheduleContext->description = "Description of schedule";
473 scheduleContext->product = NULL;
474 scheduleContext->productData = NULL;
475 scheduleContext->productDataCount = 0;
476 scheduleContext->receiptPhone = NULL;
477 scheduleContext->receiptEmail = NULL;
478
479 scheduleContext->scheduleType = Ibox_Schedule_Type_WEEKLY;
480 scheduleContext->dayWeek = 1;
481 scheduleContext->day = 28;
482 scheduleContext->startDate = "2018-09-28";
483 scheduleContext->scheduleEndType = Ibox_Schedule_EndType_COUNT;
484 scheduleContext->dates = NULL;
485 scheduleContext->datesCount = 0;
486 scheduleContext->endCount = 1;
487
488 Ibox_Result_ScheduleSubmit *scheduleSubmitResult = Ibox_PaymentController_StartSchedule(scheduleContext);
489 if (!scheduleSubmitResult->errorCode)
490 fprintf(stderr, "Schedule done!\n");
491 else
492 fprintf(stderr, "Schedule error: %s\n", scheduleSubmitResult->errorMessage);
493
494 free(scheduleSubmitResult);
495 free(scheduleContext);
496 }
497
498 if (TEST_TRANSACTION)
499 {
500 Ibox_Result_Transactions *transactionResult = Ibox_PaymentController_Transaction(TRANSACTION_ID);
501 if (!transactionResult->errorCode)
502 {
503 Ibox_Transaction *transaction = NULL;
504 if (transactionResult->transactionsCount)
505 transaction = transactionResult->transactions[0];
506 if (transaction)
507 {
508 fprintf(stderr, "Transaction invoice: %s\n", transaction->invoice);
509 fprintf(stderr, "Transaction state: %d\n", transaction->state);
510 fprintf(stderr, "Transaction substate: %d\n", transaction->substate);
511
512 Ibox_FiscalInfo *fiscalInfo = transaction->fiscalInfo;
513 fprintf(stderr, "Fiscal printer serial number: %s\n", fiscalInfo->printerSerialNumber);
514 fprintf(stderr, "Fiscal date time: %s\n", fiscalInfo->dateTime);
515 }
516 }
517 }
518
519 if (TEST_FISCALIZE)
520 {
521 Ibox_Result *fiscalizeResult = Ibox_PaymentController_Fiscalize(TRANSACTION_ID);
522 if (!fiscalizeResult->errorCode)
523 {
524 fprintf(stderr, "Fiscalization done.");
525 }
526 }
527
528 if (TEST_PREPARE)
529 {
530 if (authResult && authResult->productsCount)
531 {
532 Ibox_Product *product = NULL;
533 for (int i = 0; i < authResult->productsCount; i++)
534 {
535 Ibox_Product *localProduct = authResult->products[i];
536 if (localProduct->preparable)
537 {
538 product = localProduct;
539 break;
540 }
541 }
542
543 if (product && product->fieldsCount)
544 {
545 Ibox_ProductField **productPrepareData = calloc(1, sizeof(Ibox_ProductField *));
546 Ibox_ProductField *field = product->preparableField;
547 if (field->defaultValue)
548 field->value = field->defaultValue;
549 else
550 field->value = PRODUCT_FIELD_TEST_DATA;
551 memcpy(productPrepareData, &field, sizeof(Ibox_ProductField *));
552
553 Ibox_Result_Prepare *prepareResult = Ibox_PaymentController_Prepare(product, productPrepareData, 1);
554 if (!prepareResult->errorCode)
555 {
556 Ibox_PaymentContext *paymentContext = calloc(1, sizeof(Ibox_PaymentContext));
557 paymentContext->inputType = Ibox_PaymentController_InputType_CARD;
558 paymentContext->currencyType = Ibox_PaymentController_CurrencyType_RUB;
559 paymentContext->amount = prepareResult->amount;
560 paymentContext->receiptEmail = RECEIPT_EMAIL;
561 paymentContext->receiptPhone = RECEIPT_PHONE;
562 paymentContext->acquirerCode = ACQUIRER_CODE;
563
564 if (prepareResult->fieldsCount)
565 {
566 int productDataCount = 0;
567 Ibox_ProductField **buffer = calloc(product->fieldsCount, sizeof(Ibox_ProductField *));
568
569 for (int i = 0; i < product->fieldsCount; i++)
570 {
571 Ibox_ProductField *field = product->fields[i];
572 for (int i = 0; i < prepareResult->fieldsCount; i++)
573 {
574 Ibox_ProductField *prepareField = prepareResult->fields[i];
575 if (!strcmp(field->code, prepareField->code))
576 {
577 field->value = prepareField->value;
578 memcpy(buffer + productDataCount, &field, sizeof(Ibox_ProductField *));
579 productDataCount++;
580 break;
581 }
582 }
583 }
584
585 if (productDataCount)
586 {
587 Ibox_ProductField **productData = calloc(productDataCount, sizeof(Ibox_ProductField *));
588 for (int i = 0; i < productDataCount; i++)
589 {
590 Ibox_ProductField *field = buffer[i];
591 memcpy(productData + i, &field, sizeof(Ibox_ProductField *));
592 }
593
594 paymentContext->product = product;
595 paymentContext->productData = productData;
596 paymentContext->productDataCount = productDataCount;
597
598 Ibox_Result_Submit *submitResult = Ibox_PaymentController_StartPayment(paymentContext);
599 if (!submitResult->errorCode)
600 fprintf(stderr, "Payment done!\n");
601 else
602 fprintf(stderr, "Payment error: %s\n", submitResult->errorMessage);
603 }
604
605 free(buffer);
606 }
607 }
608 else
609 fprintf(stderr, "Prepare error: %s\n", prepareResult->errorMessage);
610
611 free(prepareResult);
612 free(productPrepareData);
613 }
614 }
615 }
616
617 if (authResult)
618 free(authResult);
619
620 return 0;
621}