node-behind-api-client 2.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/.gitlab-ci.yml +20 -0
  2. package/README.md +65 -0
  3. package/docs/behind-api-client/easyjob/JobDescriptions/README.md +654 -0
  4. package/docs/behind-api-client/easyjob/README.md +647 -0
  5. package/docs/behind-api-client/easyjob/applicants/README.md +494 -0
  6. package/docs/behind-api-client/easyjob/applications/README.md +754 -0
  7. package/docs/behind-api-client/easyjob/candidateProfiles/README.md +940 -0
  8. package/docs/behind-api-client/easyjob/jd-candidate-questions/README.md +372 -0
  9. package/docs/behind-api-client/payments/payture/README.21.md +901 -0
  10. package/docs/behind-api-client/payments/payture/README.cards.md +1497 -0
  11. package/docs/behind-api-client/payments/payture/README.md +1497 -0
  12. package/docs/behind-api-client/payments/payture/README.rukitchen.md +396 -0
  13. package/docs/behind-api-client/payments/payture/README.subscriptions.md +1266 -0
  14. package/docs/behind-api-client/payments/stripe/README.flow.md +254 -0
  15. package/docs/behind-api-client/rag/storage/README.md +519 -0
  16. package/example.js +35 -0
  17. package/index.cjs +14 -0
  18. package/index.js +15 -0
  19. package/lib/behind-api-auth-client/BehindApiAuthClient.js +91 -0
  20. package/lib/behind-api-auth-client/authorisation/AuthorisationApp.js +9 -0
  21. package/lib/behind-api-auth-client/authorisation/AuthorisationV10.js +9 -0
  22. package/lib/behind-api-auth-client/authorisation/AuthorisationV10Code.js +30 -0
  23. package/lib/behind-api-auth-client/example.js +47 -0
  24. package/lib/behind-api-auth-client/package.json +9 -0
  25. package/lib/behind-api-client/BehindApiClient.js +137 -0
  26. package/lib/behind-api-client/chat/ChatApp.js +11 -0
  27. package/lib/behind-api-client/chat/ChatV10.js +13 -0
  28. package/lib/behind-api-client/chat/ChatV10Chat.js +87 -0
  29. package/lib/behind-api-client/chat/ChatV10Chats.js +14 -0
  30. package/lib/behind-api-client/chat/ChatV10Message.js +57 -0
  31. package/lib/behind-api-client/chat/ChatV20.js +11 -0
  32. package/lib/behind-api-client/chat/ChatV20Chat.js +14 -0
  33. package/lib/behind-api-client/chat/ChatV20Message.js +27 -0
  34. package/lib/behind-api-client/easyjob/EasyjobApp.js +9 -0
  35. package/lib/behind-api-client/easyjob/EasyjobV10.js +31 -0
  36. package/lib/behind-api-client/easyjob/EasyjobV10Answers.js +16 -0
  37. package/lib/behind-api-client/easyjob/EasyjobV10Applicants.js +29 -0
  38. package/lib/behind-api-client/easyjob/EasyjobV10Applications.js +39 -0
  39. package/lib/behind-api-client/easyjob/EasyjobV10CandidateProfileArtifacts.js +31 -0
  40. package/lib/behind-api-client/easyjob/EasyjobV10CandidateProfiles.js +99 -0
  41. package/lib/behind-api-client/easyjob/EasyjobV10Companies.js +36 -0
  42. package/lib/behind-api-client/easyjob/EasyjobV10Cv.js +15 -0
  43. package/lib/behind-api-client/easyjob/EasyjobV10Departments.js +37 -0
  44. package/lib/behind-api-client/easyjob/EasyjobV10JobDescriptionArtifacts.js +29 -0
  45. package/lib/behind-api-client/easyjob/EasyjobV10JobDescriptionCandidateQuestions.js +63 -0
  46. package/lib/behind-api-client/easyjob/EasyjobV10JobDescriptions.js +93 -0
  47. package/lib/behind-api-client/easyjob/EasyjobV10Reports.js +35 -0
  48. package/lib/behind-api-client/example.js +47 -0
  49. package/lib/behind-api-client/global/GlobalApp.js +9 -0
  50. package/lib/behind-api-client/global/GlobalV10.js +11 -0
  51. package/lib/behind-api-client/global/GlobalV10Sockets.js +16 -0
  52. package/lib/behind-api-client/global/GlobalV10Storage.js +29 -0
  53. package/lib/behind-api-client/gpt/GptApp.js +15 -0
  54. package/lib/behind-api-client/gpt/GptV10.js +15 -0
  55. package/lib/behind-api-client/gpt/GptV10Prompt.js +17 -0
  56. package/lib/behind-api-client/gpt/GptV10Request.js +16 -0
  57. package/lib/behind-api-client/gpt/GptV10Storedprompts.js +14 -0
  58. package/lib/behind-api-client/gpt/GptV10Whisper.js +23 -0
  59. package/lib/behind-api-client/gpt/GptV20.js +9 -0
  60. package/lib/behind-api-client/gpt/GptV20Prompt.js +15 -0
  61. package/lib/behind-api-client/gpt/GptV30.js +13 -0
  62. package/lib/behind-api-client/gpt/GptV30Chat.js +19 -0
  63. package/lib/behind-api-client/gpt/GptV30Prompt.js +41 -0
  64. package/lib/behind-api-client/gpt/GptV30Prompts.js +32 -0
  65. package/lib/behind-api-client/gpt/GptV40.js +11 -0
  66. package/lib/behind-api-client/gpt/GptV40Prompt.js +24 -0
  67. package/lib/behind-api-client/gpt/GptV40Prompts.js +30 -0
  68. package/lib/behind-api-client/mailer/MailerApp.js +11 -0
  69. package/lib/behind-api-client/mailer/MailerV10.js +15 -0
  70. package/lib/behind-api-client/mailer/MailerV10Bulk.js +21 -0
  71. package/lib/behind-api-client/mailer/MailerV10Message.js +83 -0
  72. package/lib/behind-api-client/mailer/MailerV10Settings.js +44 -0
  73. package/lib/behind-api-client/mailer/MailerV10Template.js +23 -0
  74. package/lib/behind-api-client/mailer/MailerV20.js +9 -0
  75. package/lib/behind-api-client/mailer/MailerV20Message.js +21 -0
  76. package/lib/behind-api-client/mastogram/MastogramApp.js +9 -0
  77. package/lib/behind-api-client/mastogram/MastogramV10.js +13 -0
  78. package/lib/behind-api-client/mastogram/MastogramV10Bluesky.js +42 -0
  79. package/lib/behind-api-client/mastogram/MastogramV10Mastodon.js +45 -0
  80. package/lib/behind-api-client/mastogram/MastogramV10Telegram.js +39 -0
  81. package/lib/behind-api-client/monitor/MonitorApp.js +9 -0
  82. package/lib/behind-api-client/monitor/MonitorV10.js +13 -0
  83. package/lib/behind-api-client/monitor/MonitorV10Finances.js +39 -0
  84. package/lib/behind-api-client/monitor/MonitorV10Record.js +15 -0
  85. package/lib/behind-api-client/monitor/MonitorV10Records.js +22 -0
  86. package/lib/behind-api-client/oauth/OauthApp.js +9 -0
  87. package/lib/behind-api-client/oauth/OauthV10.js +9 -0
  88. package/lib/behind-api-client/oauth/OauthV10Authorisation.js +15 -0
  89. package/lib/behind-api-client/package.json +9 -0
  90. package/lib/behind-api-client/payments/PaymentsApp.js +13 -0
  91. package/lib/behind-api-client/payments/PaymentsV10.js +15 -0
  92. package/lib/behind-api-client/payments/PaymentsV10Gift.js +32 -0
  93. package/lib/behind-api-client/payments/PaymentsV10Payture.js +30 -0
  94. package/lib/behind-api-client/payments/PaymentsV10Product.js +15 -0
  95. package/lib/behind-api-client/payments/PaymentsV10Telegram.js +44 -0
  96. package/lib/behind-api-client/payments/PaymentsV20.js +9 -0
  97. package/lib/behind-api-client/payments/PaymentsV20Payture.js +32 -0
  98. package/lib/behind-api-client/payments/PaymentsV21.js +15 -0
  99. package/lib/behind-api-client/payments/PaymentsV21Cards.js +14 -0
  100. package/lib/behind-api-client/payments/PaymentsV21Payture.js +29 -0
  101. package/lib/behind-api-client/payments/PaymentsV21Stripe.js +28 -0
  102. package/lib/behind-api-client/payments/PaymentsV21Subscriptions.js +21 -0
  103. package/lib/behind-api-client/questionnaire/QuestionnaireApp.js +9 -0
  104. package/lib/behind-api-client/questionnaire/QuestionnaireV10.js +9 -0
  105. package/lib/behind-api-client/questionnaire/QuestionnaireV10Form.js +22 -0
  106. package/lib/behind-api-client/raet/RaetApp.js +11 -0
  107. package/lib/behind-api-client/raet/RaetV10.js +21 -0
  108. package/lib/behind-api-client/raet/RaetV10Cv.js +87 -0
  109. package/lib/behind-api-client/raet/RaetV10Individual.js +43 -0
  110. package/lib/behind-api-client/raet/RaetV10Individuals.js +38 -0
  111. package/lib/behind-api-client/raet/RaetV10Jd.js +47 -0
  112. package/lib/behind-api-client/raet/RaetV10Project.js +61 -0
  113. package/lib/behind-api-client/raet/RaetV10Projects.js +14 -0
  114. package/lib/behind-api-client/raet/RaetV10Report.js +39 -0
  115. package/lib/behind-api-client/raet/RaetV20.js +11 -0
  116. package/lib/behind-api-client/raet/RaetV20Cv.js +31 -0
  117. package/lib/behind-api-client/raet/RaetV20Individuals.js +25 -0
  118. package/lib/behind-api-client/rag/RagApp.js +9 -0
  119. package/lib/behind-api-client/rag/RagV10.js +9 -0
  120. package/lib/behind-api-client/rag/RagV10Storage.js +27 -0
  121. package/lib/behind-api-client/ruKitchen/RuKitchenApp.js +9 -0
  122. package/lib/behind-api-client/ruKitchen/RuKitchenV10.js +11 -0
  123. package/lib/behind-api-client/ruKitchen/RuKitchenV10Importer.js +29 -0
  124. package/lib/behind-api-client/ruKitchen/RuKitchenV10SeoArticle.js +14 -0
  125. package/lib/behind-api-client/sales/SalesApp.js +11 -0
  126. package/lib/behind-api-client/sales/SalesV10.js +23 -0
  127. package/lib/behind-api-client/sales/SalesV10Catalogue.js +58 -0
  128. package/lib/behind-api-client/sales/SalesV10Categories.js +15 -0
  129. package/lib/behind-api-client/sales/SalesV10Companies.js +55 -0
  130. package/lib/behind-api-client/sales/SalesV10Company.js +120 -0
  131. package/lib/behind-api-client/sales/SalesV10Group.js +70 -0
  132. package/lib/behind-api-client/sales/SalesV10Groups.js +21 -0
  133. package/lib/behind-api-client/sales/SalesV10Logs.js +14 -0
  134. package/lib/behind-api-client/sales/SalesV10Notes.js +38 -0
  135. package/lib/behind-api-client/sales/SalesV20.js +11 -0
  136. package/lib/behind-api-client/sales/SalesV20Companies.js +26 -0
  137. package/lib/behind-api-client/sales/SalesV20Notes.js +17 -0
  138. package/lib/behind-api-client/sip/SipApp.js +9 -0
  139. package/lib/behind-api-client/sip/SipV10.js +15 -0
  140. package/lib/behind-api-client/sip/SipV10Call.js +83 -0
  141. package/lib/behind-api-client/sip/SipV10Phone.js +44 -0
  142. package/lib/behind-api-client/sip/SipV10Transcript.js +21 -0
  143. package/lib/behind-api-client/sip/SipV10Transcripts.js +21 -0
  144. package/lib/behind-api-client/storage/StorageApp.js +9 -0
  145. package/lib/behind-api-client/storage/StorageV10.js +11 -0
  146. package/lib/behind-api-client/storage/StorageV10File.js +35 -0
  147. package/lib/behind-api-client/storage/StorageV10Upload.js +21 -0
  148. package/lib/behind-api-client/tests/TestsApp.js +9 -0
  149. package/lib/behind-api-client/tests/TestsV10.js +15 -0
  150. package/lib/behind-api-client/tests/TestsV10Cases.js +29 -0
  151. package/lib/behind-api-client/tests/TestsV10CasesExtended.js +14 -0
  152. package/lib/behind-api-client/tests/TestsV10Core.js +14 -0
  153. package/lib/behind-api-client/tests/TestsV10Mail.js +14 -0
  154. package/lib/behind-api-client/tools/ToolsApp.js +9 -0
  155. package/lib/behind-api-client/tools/ToolsV10.js +9 -0
  156. package/lib/behind-api-client/tools/ToolsV10Pdf.js +30 -0
  157. package/package.json +25 -0
@@ -0,0 +1,901 @@
1
+ # Payments API V21 - Payture Endpoint
2
+
3
+ This document provides detailed information about the Payture payment gateway integration methods for the V21 Payments API.
4
+
5
+ ## Overview
6
+
7
+ The Payture Payments API V21 provides methods for initializing payment sessions through the Payture EWallet gateway. This includes creating payment sessions for both authorized and unauthorized users, managing customer accounts, and handling subscription payment flows with card registration.
8
+
9
+ ---
10
+
11
+ ## Payments API V21 - Payture Methods
12
+
13
+ ### behindAPI.V21.payments.payture.init()
14
+ Initializes a payment session for an authorized user.
15
+
16
+ **Parameters:**
17
+ - None (uses authenticated user session)
18
+
19
+ **Authorization:**
20
+ - Required: No (but uses session if available)
21
+
22
+ **Usage:**
23
+ ```javascript
24
+ const result = await behindAPI.V21.payments.payture.init();
25
+
26
+ // Response:
27
+ {
28
+ success: true,
29
+ data: {
30
+ Success: "True",
31
+ Amount: "10.00",
32
+ SessionLifeTime: "60",
33
+ AttemptsCount: "5",
34
+ SessionId: "38ff74a9-c37c-42ba-a38a-bca05afecfc9",
35
+ SessionType: "Add",
36
+ RedirectUrl: "https://sandbox3.payture.com/vwapi/Add?SessionId=38ff74a9-c37c-42ba-a38a-bca05afecfc9",
37
+ Cmd: "Init"
38
+ }
39
+ }
40
+
41
+ // Error Response:
42
+ {
43
+ success: false,
44
+ message: "Can't finish request",
45
+ e: { /* error details */ }
46
+ }
47
+ ```
48
+
49
+ ### behindAPI.V21.payments.payture.initUnauthorised(userId)
50
+ Authorizes payment for a user subscription through Payture EWallet. Creates or verifies user wallet, registers customer in Payture, and initializes payment session for card registration.
51
+
52
+ **Parameters:**
53
+ - `userId` (string, required) - User ID for payment authorization
54
+
55
+ **Authorization:**
56
+ - Required: No
57
+
58
+ **Usage:**
59
+ ```javascript
60
+ const result = await behindAPI.V21.payments.payture.initUnauthorised(
61
+ "550e8400-e29b-41d4-a716-446655440001"
62
+ );
63
+
64
+ // Response:
65
+ {
66
+ success: true,
67
+ data: {
68
+ Success: "True",
69
+ Amount: "10.00",
70
+ SessionLifeTime: "60",
71
+ AttemptsCount: "5",
72
+ SessionId: "38ff74a9-c37c-42ba-a38a-bca05afecfc9",
73
+ SessionType: "Add",
74
+ RedirectUrl: "https://sandbox3.payture.com/vwapi/Add?SessionId=38ff74a9-c37c-42ba-a38a-bca05afecfc9",
75
+ Cmd: "Init"
76
+ }
77
+ }
78
+
79
+ // Error Response:
80
+ {
81
+ success: false,
82
+ message: "Can't finish request",
83
+ e: { /* error details */ }
84
+ }
85
+ ```
86
+
87
+ ### behindAPI.V21.payments.payture.finalise()
88
+ Finalizes the payment process after card registration. Retrieves user's card list from Payture, selects the first active card that doesn't require CVV and isn't expired, and saves it to the database.
89
+
90
+ **Parameters:**
91
+ - None (uses authenticated user session)
92
+
93
+ **Authorization:**
94
+ - Required: No (but uses session)
95
+
96
+ **Usage:**
97
+ ```javascript
98
+ const result = await behindAPI.V21.payments.payture.finalise();
99
+
100
+ // Success Response (with active card):
101
+ {
102
+ success: true,
103
+ data: {
104
+ card: {
105
+ CardName: "411111******1111",
106
+ CardHolder: "JOHN DOE",
107
+ Status: "IsActive",
108
+ NoCVV: "false",
109
+ Expired: "false"
110
+ // Note: CardId is removed for security
111
+ }
112
+ }
113
+ }
114
+
115
+ // Error Response (no active card):
116
+ {
117
+ success: false,
118
+ message: "No active card found"
119
+ }
120
+
121
+ // Error Response (can't get cards):
122
+ {
123
+ success: false,
124
+ message: "Can't get card list",
125
+ e: { /* error details */ }
126
+ }
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Data Structure Reference
132
+
133
+ ### Payment Initialization Response
134
+ The `init()` and `initUnauthorised()` methods return:
135
+
136
+ **Success Response:**
137
+ - `success` (boolean) - Always `true` for successful requests
138
+ - `data` (object) - Payture response data
139
+ - `Success` (string) - Payture success indicator ("True"/"False")
140
+ - `Amount` (string) - Payment amount in rubles (e.g., "10.00")
141
+ - `SessionLifeTime` (string) - Session lifetime in minutes (e.g., "60")
142
+ - `AttemptsCount` (string) - Number of payment attempts allowed (e.g., "5")
143
+ - `SessionId` (UUID string) - Unique payment session ID
144
+ - `SessionType` (string) - Session type ("Add" for card registration)
145
+ - `RedirectUrl` (string) - URL to redirect user for payment/card registration
146
+ - `Cmd` (string) - Command type ("Init")
147
+
148
+ **Error Response:**
149
+ - `success` (boolean) - Always `false` for failed requests
150
+ - `message` (string) - Error description
151
+ - `e` (object) - Error details
152
+
153
+ ### Subscription Creation Response
154
+ The `finalise()` method returns:
155
+
156
+ **Success Response:**
157
+ - `success` (boolean) - Always `true` for successful requests
158
+ - `data` (object) - Container for response data
159
+ - `card` (object) - Selected active card information
160
+ - `CardName` (string) - Masked card number (e.g., "411111******1111")
161
+ - `CardHolder` (string) - Cardholder name
162
+ - `Status` (string) - Card status ("IsActive")
163
+ - `NoCVV` (string) - Whether CVV is required ("true"/"false")
164
+ - `Expired` (string) - Whether card is expired ("true"/"false")
165
+
166
+ **Error Response:**
167
+ - `success` (boolean) - Always `false` for failed requests
168
+ - `message` (string) - Error description ("No active card found", "Can't get card list")
169
+ - `e` (object, optional) - Error details
170
+
171
+ ---
172
+
173
+ ## Complete Usage Examples
174
+
175
+ ### Basic Payment Initialization for Guest Users
176
+
177
+ ```javascript
178
+ // Example: Initialize payment for guest user
179
+ async function initializeGuestPayment(userId) {
180
+ try {
181
+ console.log("Initializing payment session...");
182
+
183
+ const result = await behindAPI.V21.payments.payture.initUnauthorised(userId);
184
+
185
+ if (result.success) {
186
+ console.log("✓ Payment session initialized!");
187
+ console.log(`Session ID: ${result.data.SessionId}`);
188
+ console.log(`Payment URL: ${result.data.RedirectUrl}`);
189
+ console.log(`Session lifetime: ${result.data.SessionLifeTime} minutes`);
190
+
191
+ // Redirect user to Payture for card registration
192
+ window.location.href = result.data.RedirectUrl;
193
+
194
+ return result.data;
195
+ } else {
196
+ console.log(`✗ Failed to initialize payment: ${result.message}`);
197
+ return null;
198
+ }
199
+ } catch (error) {
200
+ console.error("Error initializing payment:", error);
201
+ return null;
202
+ }
203
+ }
204
+
205
+ // Usage
206
+ const sessionData = await initializeGuestPayment(
207
+ "aa0e8400-e29b-41d4-a716-446655440005"
208
+ );
209
+ ```
210
+
211
+ ### Payment Initialization for Authorized Users
212
+
213
+ ```javascript
214
+ // Example: Initialize payment for logged-in user
215
+ async function initializeUserPayment() {
216
+ try {
217
+ console.log("Initializing payment for authorized user...");
218
+
219
+ const result = await behindAPI.V21.payments.payture.init();
220
+
221
+ if (result.success) {
222
+ console.log("✓ Payment session ready!");
223
+ console.log(`Redirect URL: ${result.data.RedirectUrl}`);
224
+
225
+ // Store session ID for later reference
226
+ sessionStorage.setItem('payture_session_id', result.data.SessionId);
227
+
228
+ // Open in new window or redirect
229
+ const paymentWindow = window.open(result.data.RedirectUrl, '_blank');
230
+
231
+ if (!paymentWindow || paymentWindow.closed) {
232
+ // Fallback to same-window redirect
233
+ window.location.href = result.data.RedirectUrl;
234
+ }
235
+
236
+ return result.data;
237
+ } else {
238
+ console.error(`✗ Initialization failed: ${result.message}`);
239
+ return null;
240
+ }
241
+ } catch (error) {
242
+ console.error("Error:", error);
243
+ return null;
244
+ }
245
+ }
246
+
247
+ // Usage
248
+ const paymentData = await initializeUserPayment();
249
+ ```
250
+
251
+ ### Complete Card Registration and Finalization Flow
252
+
253
+ ```javascript
254
+ // Example: Register card and finalize after callback
255
+ async function registerAndFinalizeCard() {
256
+ try {
257
+ console.log("Step 1: Initializing card registration...");
258
+
259
+ const initResult = await behindAPI.V21.payments.payture.init();
260
+
261
+ if (!initResult.success) {
262
+ console.error(`✗ Initialization failed: ${initResult.message}`);
263
+ return null;
264
+ }
265
+
266
+ console.log("✓ Card registration session initialized!");
267
+ console.log(`Redirect URL: ${initResult.data.RedirectUrl}`);
268
+
269
+ // Store session data
270
+ sessionStorage.setItem('payture_session_id', initResult.data.SessionId);
271
+ sessionStorage.setItem('card_registration_pending', 'true');
272
+
273
+ // Redirect user to Payture
274
+ window.location.href = initResult.data.RedirectUrl;
275
+
276
+ return initResult.data;
277
+
278
+ } catch (error) {
279
+ console.error("Error:", error);
280
+ return null;
281
+ }
282
+ }
283
+
284
+ // After user returns from Payture (in callback page)
285
+ async function finalizeCardRegistration() {
286
+ try {
287
+ console.log("Step 2: Finalizing card registration...");
288
+
289
+ // Check if there's a pending registration
290
+ const isPending = sessionStorage.getItem('card_registration_pending');
291
+
292
+ if (!isPending) {
293
+ console.log("No pending card registration");
294
+ return null;
295
+ }
296
+
297
+ // Parse callback parameters
298
+ const params = new URLSearchParams(window.location.search);
299
+ const success = params.get('result');
300
+
301
+ if (success !== 'True') {
302
+ console.error("Card registration was not successful");
303
+ sessionStorage.removeItem('card_registration_pending');
304
+ return null;
305
+ }
306
+
307
+ // Finalize the registration
308
+ const finalizeResult = await behindAPI.V21.payments.payture.finalise();
309
+
310
+ if (finalizeResult.success) {
311
+ console.log("✓ Card registered successfully!");
312
+ console.log(`Card: ${finalizeResult.data.card.CardName}`);
313
+ console.log(`Holder: ${finalizeResult.data.card.CardHolder}`);
314
+
315
+ // Clear pending flag
316
+ sessionStorage.removeItem('card_registration_pending');
317
+
318
+ return {
319
+ cardInfo: {
320
+ maskedNumber: finalizeResult.data.card.CardName,
321
+ holder: finalizeResult.data.card.CardHolder
322
+ }
323
+ };
324
+ } else {
325
+ console.log(`✗ Failed to finalize: ${finalizeResult.message}`);
326
+
327
+ if (finalizeResult.message === "No active card found") {
328
+ console.log("No valid card was registered. Please try again.");
329
+ }
330
+
331
+ return null;
332
+ }
333
+ } catch (error) {
334
+ console.error("Error finalizing card registration:", error);
335
+ return null;
336
+ }
337
+ }
338
+
339
+ // Usage on main page - Start registration
340
+ await registerAndFinalizeCard();
341
+
342
+ // Usage on callback page - Complete registration
343
+ const cardData = await finalizeCardRegistration();
344
+ if (cardData) {
345
+ // Proceed with subscription creation
346
+ window.location.href = '/create-subscription';
347
+ }
348
+ ```
349
+
350
+ ### Complete Payment Flow with Two-Step Process
351
+
352
+ ```javascript
353
+ // Example: Full payment flow - card registration, finalization, and subscription creation
354
+ async function completePaymentFlow(userId, subscriptionId) {
355
+ const flow = {
356
+ step: 1,
357
+ status: "starting",
358
+ data: {}
359
+ };
360
+
361
+ try {
362
+ // Step 1: Initialize payment session
363
+ console.log("Step 1: Initializing card registration...");
364
+ flow.step = 1;
365
+
366
+ const initResult = await behindAPI.V21.payments.payture.initUnauthorised(userId);
367
+
368
+ if (!initResult.success) {
369
+ flow.status = "failed_init";
370
+ flow.error = initResult.message;
371
+ return flow;
372
+ }
373
+
374
+ flow.data.sessionId = initResult.data.SessionId;
375
+ flow.data.redirectUrl = initResult.data.RedirectUrl;
376
+ console.log("✓ Session initialized");
377
+
378
+ // Step 2: Redirect user for card registration
379
+ console.log("Step 2: Redirecting to Payture...");
380
+ flow.step = 2;
381
+
382
+ // Store flow data before redirect
383
+ sessionStorage.setItem('payment_flow', JSON.stringify(flow));
384
+ sessionStorage.setItem('pending_subscription', subscriptionId);
385
+ sessionStorage.setItem('card_registration_pending', 'true');
386
+
387
+ // Redirect user
388
+ window.location.href = initResult.data.RedirectUrl;
389
+
390
+ // AFTER USER RETURNS FROM PAYTURE (in callback handler):
391
+
392
+ // Step 3: Finalize card registration
393
+ console.log("Step 3: Finalizing card registration...");
394
+ flow.step = 3;
395
+
396
+ const finalizeResult = await behindAPI.V21.payments.payture.finalise();
397
+
398
+ if (!finalizeResult.success) {
399
+ flow.status = "failed_finalize";
400
+ flow.error = finalizeResult.message;
401
+ return flow;
402
+ }
403
+
404
+ flow.data.cardInfo = finalizeResult.data.card;
405
+ console.log("✓ Card registered and saved");
406
+
407
+ // Step 4: Create subscription instance
408
+ console.log("Step 4: Creating subscription...");
409
+ flow.step = 4;
410
+
411
+ const subscriptionResult = await behindAPI.V21.payments.subscriptions.create(
412
+ subscriptionId
413
+ );
414
+
415
+ if (!subscriptionResult.success) {
416
+ flow.status = "failed_subscription";
417
+ flow.error = subscriptionResult.message;
418
+ return flow;
419
+ }
420
+
421
+ flow.data.subscriptionId = subscriptionResult.data.subscription_instance_id;
422
+ flow.status = "completed";
423
+ console.log("✓ Payment flow completed successfully");
424
+
425
+ return flow;
426
+
427
+ } catch (error) {
428
+ console.error(`Error at step ${flow.step}:`, error);
429
+ flow.status = "error";
430
+ flow.error = error.message;
431
+ return flow;
432
+ }
433
+ }
434
+
435
+ // Usage on main page
436
+ const result = await completePaymentFlow(
437
+ "aa0e8400-e29b-41d4-a716-446655440005",
438
+ "premium-monthly"
439
+ );
440
+
441
+ // Usage on callback page (after Payture redirect)
442
+ async function handlePaymentCallback() {
443
+ const urlParams = new URLSearchParams(window.location.search);
444
+ const orderid = urlParams.get('orderid');
445
+ const success = urlParams.get('result');
446
+
447
+ if (success === 'True') {
448
+ console.log("Card registration successful, finalizing...");
449
+
450
+ // Step 1: Finalize card registration
451
+ const finalizeResult = await behindAPI.V21.payments.payture.finalise();
452
+
453
+ if (!finalizeResult.success) {
454
+ console.error("Failed to finalize card:", finalizeResult.message);
455
+ window.location.href = '/error?reason=card_finalization_failed';
456
+ return;
457
+ }
458
+
459
+ console.log("Card finalized successfully!");
460
+
461
+ // Step 2: Create subscription if there's a pending one
462
+ const subscriptionId = sessionStorage.getItem('pending_subscription');
463
+
464
+ if (subscriptionId) {
465
+ console.log("Creating subscription...");
466
+
467
+ const subscriptionResult = await behindAPI.V21.payments.subscriptions.create(
468
+ subscriptionId
469
+ );
470
+
471
+ if (subscriptionResult.success) {
472
+ console.log("Subscription created!");
473
+ sessionStorage.removeItem('pending_subscription');
474
+ sessionStorage.removeItem('card_registration_pending');
475
+ // Redirect to success page
476
+ window.location.href = '/subscription-success';
477
+ } else {
478
+ console.error("Failed to create subscription:", subscriptionResult.message);
479
+ window.location.href = '/error?reason=subscription_creation_failed';
480
+ }
481
+ } else {
482
+ // No subscription to create, just card registration
483
+ sessionStorage.removeItem('card_registration_pending');
484
+ window.location.href = '/cards-success';
485
+ }
486
+ } else {
487
+ console.log("Card registration was not successful");
488
+ sessionStorage.removeItem('card_registration_pending');
489
+ window.location.href = '/error?reason=card_registration_failed';
490
+ }
491
+ }
492
+ ```
493
+
494
+ ### Handling Card Registration Callbacks
495
+
496
+ ```javascript
497
+ // Example: Process callback after card registration using finalise
498
+ class PaytureCallbackHandler {
499
+ constructor() {
500
+ this.processCallback();
501
+ }
502
+
503
+ async processCallback() {
504
+ try {
505
+ // Parse URL parameters
506
+ const params = new URLSearchParams(window.location.search);
507
+ const orderId = params.get('orderid');
508
+ const success = params.get('result');
509
+
510
+ console.log(`Order ID: ${orderId}`);
511
+ console.log(`Success: ${success}`);
512
+
513
+ if (success !== 'True') {
514
+ this.handleFailure("Card registration was cancelled or failed");
515
+ return;
516
+ }
517
+
518
+ // Wait a bit for Payture to process
519
+ await this.sleep(2000);
520
+
521
+ // Step 1: Finalize card registration
522
+ console.log("Finalizing card registration...");
523
+ const finalizeResult = await behindAPI.V21.payments.payture.finalise();
524
+
525
+ if (!finalizeResult.success) {
526
+ this.handleFailure(finalizeResult.message);
527
+ return;
528
+ }
529
+
530
+ console.log("Card registered successfully!");
531
+
532
+ // Step 2: Check if there's a pending subscription to create
533
+ const subscriptionId = sessionStorage.getItem('pending_subscription');
534
+
535
+ if (subscriptionId) {
536
+ console.log("Creating subscription...");
537
+
538
+ const subscriptionResult = await behindAPI.V21.payments.subscriptions.create(
539
+ subscriptionId
540
+ );
541
+
542
+ if (subscriptionResult.success) {
543
+ this.handleSuccess(finalizeResult.data, subscriptionResult.data);
544
+ } else {
545
+ this.handleFailure(subscriptionResult.message);
546
+ }
547
+ } else {
548
+ // No subscription, just card registration
549
+ this.handleCardOnlySuccess(finalizeResult.data);
550
+ }
551
+
552
+ } catch (error) {
553
+ console.error("Callback processing error:", error);
554
+ this.handleFailure(error.message);
555
+ }
556
+ }
557
+
558
+ handleSuccess(cardData, subscriptionData) {
559
+ console.log("✓ Subscription activated!");
560
+ console.log(`Subscription ID: ${subscriptionData.subscription_instance_id}`);
561
+ console.log(`Card: ${cardData.card.CardName}`);
562
+
563
+ // Clear session data
564
+ sessionStorage.removeItem('pending_subscription');
565
+ sessionStorage.removeItem('payment_flow');
566
+ sessionStorage.removeItem('card_registration_pending');
567
+
568
+ // Show success message
569
+ this.showMessage(
570
+ `Your subscription has been activated! Card: ${cardData.card.CardName}`,
571
+ 'success'
572
+ );
573
+
574
+ // Redirect after delay
575
+ setTimeout(() => {
576
+ window.location.href = '/dashboard';
577
+ }, 3000);
578
+ }
579
+
580
+ handleCardOnlySuccess(cardData) {
581
+ console.log("✓ Card registered successfully!");
582
+ console.log(`Card: ${cardData.card.CardName}`);
583
+
584
+ // Clear session data
585
+ sessionStorage.removeItem('card_registration_pending');
586
+
587
+ // Show success message
588
+ this.showMessage(
589
+ `Card registered successfully: ${cardData.card.CardName}`,
590
+ 'success'
591
+ );
592
+
593
+ // Redirect after delay
594
+ setTimeout(() => {
595
+ window.location.href = '/cards';
596
+ }, 3000);
597
+ }
598
+
599
+ handleFailure(message = "Payment failed") {
600
+ console.error("✗ Process failed:", message);
601
+
602
+ // Clear pending flags
603
+ sessionStorage.removeItem('card_registration_pending');
604
+
605
+ this.showMessage(
606
+ `Failed: ${message}. Please try again.`,
607
+ 'error'
608
+ );
609
+
610
+ // Redirect after delay
611
+ setTimeout(() => {
612
+ window.location.href = '/subscribe';
613
+ }, 3000);
614
+ }
615
+
616
+ showMessage(text, type = 'info') {
617
+ // Implement your UI message display
618
+ console.log(`[${type.toUpperCase()}] ${text}`);
619
+ }
620
+
621
+ sleep(ms) {
622
+ return new Promise(resolve => setTimeout(resolve, ms));
623
+ }
624
+ }
625
+
626
+ // Initialize on callback page
627
+ if (window.location.pathname === '/payment/callback') {
628
+ new PaytureCallbackHandler();
629
+ }
630
+ ```
631
+
632
+ ---
633
+
634
+ ## Internal Process Flow
635
+
636
+ ### Customer Registration Process
637
+ 1. **Check Wallet**: System verifies user has RUB wallet
638
+ 2. **Create Wallet**: Creates RUB wallet if needed
639
+ 3. **Register Customer**: Registers customer in Payture with credentials
640
+ - Username: `customer-{user_id}`
641
+ - Password: MD5 hash of `{user_id}{salt}`
642
+ 4. **Initialize Session**: Creates payment session for card registration
643
+
644
+ ### Card Selection Logic
645
+ The `createSubscription()` method selects cards based on:
646
+ - `Status`: Must be "IsActive"
647
+ - `NoCVV`: Must be "false" (CVV not required for recurring)
648
+ - `Expired`: Must be "false"
649
+ - Selection: First matching card is used
650
+
651
+ ### Session Parameters
652
+ Payment sessions are initialized with:
653
+ - **Amount**: 1000 kopecks (10.00 RUB) - test amount for card verification
654
+ - **SessionType**: "Add" - for card registration
655
+ - **Product**: "Ru-kitchen.ru"
656
+ - **Description**: "Monthly subscription for premium content"
657
+
658
+ ---
659
+
660
+ ## Testing
661
+
662
+ ### Test Environment Setup
663
+ ```javascript
664
+ // Configure test environment
665
+ const TEST_CONFIG = {
666
+ testUserId: "test-user-000000000000000000000001",
667
+ testSubscriptionId: "test-premium-monthly",
668
+ callbackUrl: "http://localhost:3000/payment/callback"
669
+ };
670
+
671
+ // Test payment initialization
672
+ async function testPaymentInit() {
673
+ console.log("=== TESTING PAYMENT INITIALIZATION ===\n");
674
+
675
+ // Test 1: Unauthorized init
676
+ console.log("Test 1: Initialize payment for guest...");
677
+ const initResult = await behindAPI.V21.payments.payture.initUnauthorised(
678
+ TEST_CONFIG.testUserId
679
+ );
680
+
681
+ console.log(initResult.success ? "✓ PASS" : "✗ FAIL");
682
+ if (initResult.success) {
683
+ console.log(`Session ID: ${initResult.data.SessionId}`);
684
+ console.log(`Redirect URL: ${initResult.data.RedirectUrl}\n`);
685
+ }
686
+
687
+ // Test 2: Authorized init
688
+ console.log("Test 2: Initialize payment for authorized user...");
689
+ const authInitResult = await behindAPI.V21.payments.payture.init();
690
+
691
+ console.log(authInitResult.success ? "✓ PASS" : "✗ FAIL\n");
692
+
693
+ console.log("=== TESTS COMPLETE ===");
694
+ }
695
+
696
+ // Test subscription creation
697
+ async function testSubscriptionCreation() {
698
+ console.log("=== TESTING SUBSCRIPTION CREATION ===\n");
699
+
700
+ console.log("Test: Create subscription with card...");
701
+ const result = await behindAPI.V21.payments.payture.createSubscription(
702
+ TEST_CONFIG.testSubscriptionId
703
+ );
704
+
705
+ if (result.success) {
706
+ console.log("✓ PASS");
707
+ console.log(`Subscription ID: ${result.data.subscription_instance_id}`);
708
+ console.log(`Card: ${result.data.card.CardName}`);
709
+ } else {
710
+ console.log("✗ FAIL");
711
+ console.log(`Error: ${result.message}`);
712
+ }
713
+
714
+ console.log("\n=== TEST COMPLETE ===");
715
+ }
716
+
717
+ // Run tests
718
+ testPaymentInit();
719
+ ```
720
+
721
+ ---
722
+
723
+ ## Troubleshooting
724
+
725
+ ### Common Issues and Solutions
726
+
727
+ **Issue: Payment session expired before user completed registration**
728
+ ```javascript
729
+ // Solution: Check session lifetime and warn user
730
+ async function initWithExpiryWarning(userId) {
731
+ const result = await behindAPI.V21.payments.payture.initUnauthorised(userId);
732
+
733
+ if (result.success) {
734
+ const sessionMinutes = parseInt(result.data.SessionLifeTime);
735
+
736
+ alert(`Please complete payment within ${sessionMinutes} minutes`);
737
+
738
+ // Set warning timer
739
+ setTimeout(() => {
740
+ alert("Payment session will expire soon!");
741
+ }, (sessionMinutes - 5) * 60 * 1000); // Warn 5 minutes before expiry
742
+
743
+ window.location.href = result.data.RedirectUrl;
744
+ }
745
+ }
746
+ ```
747
+
748
+ **Issue: No active cards found when finalizing**
749
+ ```javascript
750
+ // Solution: Guide user to register a new card
751
+ async function finalizeWithFallback() {
752
+ const result = await behindAPI.V21.payments.payture.finalise();
753
+
754
+ if (!result.success && result.message === "No active card found") {
755
+ console.log("No card was registered. Redirecting to card registration...");
756
+
757
+ // Initialize new card registration session
758
+ const initResult = await behindAPI.V21.payments.payture.init();
759
+
760
+ if (initResult.success) {
761
+ window.location.href = initResult.data.RedirectUrl;
762
+ }
763
+ } else if (result.success) {
764
+ console.log("Card finalized successfully!");
765
+ return result.data;
766
+ }
767
+ }
768
+ ```
769
+
770
+ **Issue: Wallet not created for user**
771
+ ```javascript
772
+ // Solution: Ensure wallet creation is successful
773
+ async function verifyWalletBeforePayment(userId) {
774
+ try {
775
+ // The initUnauthorised method handles wallet creation automatically,
776
+ // but you can verify by checking the response
777
+ const result = await behindAPI.V21.payments.payture.initUnauthorised(userId);
778
+
779
+ if (!result.success) {
780
+ console.error("Failed to initialize payment. Wallet may not exist.");
781
+ // Attempt manual wallet creation through separate API if available
782
+ }
783
+
784
+ return result;
785
+ } catch (error) {
786
+ console.error("Wallet verification error:", error);
787
+ return { success: false, message: error.message };
788
+ }
789
+ }
790
+ ```
791
+
792
+ **Issue: Callback URL parameters not being processed**
793
+ ```javascript
794
+ // Solution: Robust parameter parsing
795
+ function parseCallbackParams() {
796
+ const params = new URLSearchParams(window.location.search);
797
+
798
+ const data = {
799
+ orderId: params.get('orderid'),
800
+ success: params.get('result'),
801
+ timestamp: Date.now()
802
+ };
803
+
804
+ // Validate parameters
805
+ if (!data.orderId) {
806
+ console.error("Missing order ID in callback");
807
+ return null;
808
+ }
809
+
810
+ // Normalize success value
811
+ data.success = data.success === 'True' || data.success === 'true' || data.success === '1';
812
+
813
+ console.log("Callback parameters:", data);
814
+ return data;
815
+ }
816
+
817
+ // Usage in callback handler
818
+ const callbackData = parseCallbackParams();
819
+ if (callbackData && callbackData.success) {
820
+ // Process successful payment
821
+ }
822
+ ```
823
+
824
+ ---
825
+
826
+ ## Security Considerations
827
+
828
+ 1. **Customer Credentials**: User passwords are hashed with MD5 and salt
829
+ 2. **Session Security**: Payment sessions have limited lifetime (typically 60 minutes)
830
+ 3. **Card Storage**: Card IDs are removed from responses for security
831
+ 4. **HTTPS Required**: All redirect URLs must use HTTPS in production
832
+ 5. **Rate Limiting**: Implement rate limiting on payment initialization
833
+ 6. **Input Validation**: Always validate UUIDs and user IDs
834
+ 7. **Error Handling**: Don't expose sensitive error details to users
835
+ 8. **Audit Logging**: Log all payment operations
836
+
837
+ ```javascript
838
+ // Example: Secure payment initialization with validation
839
+ async function securePaymentInit(userId) {
840
+ // Validate UUID format
841
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
842
+
843
+ if (!uuidRegex.test(userId)) {
844
+ return {
845
+ success: false,
846
+ message: "Invalid user ID format"
847
+ };
848
+ }
849
+
850
+ // Check rate limit
851
+ const rateLimitKey = `payment_init_${userId}`;
852
+ const attempts = parseInt(sessionStorage.getItem(rateLimitKey) || '0');
853
+
854
+ if (attempts >= 5) {
855
+ return {
856
+ success: false,
857
+ message: "Too many attempts. Please try again later."
858
+ };
859
+ }
860
+
861
+ // Increment attempt counter
862
+ sessionStorage.setItem(rateLimitKey, (attempts + 1).toString());
863
+
864
+ // Initialize payment
865
+ const result = await behindAPI.V21.payments.payture.initUnauthorised(userId);
866
+
867
+ // Log the operation (send to your logging service)
868
+ logPaymentOperation({
869
+ action: 'payment_init',
870
+ userId: userId,
871
+ success: result.success,
872
+ timestamp: new Date().toISOString()
873
+ });
874
+
875
+ return result;
876
+ }
877
+ ```
878
+
879
+ ---
880
+
881
+ ## API Reference Summary
882
+
883
+ | Method | Authorization Required | Parameters | Returns |
884
+ |--------|----------------------|------------|---------|
885
+ | `init` | No | None | SessionId, RedirectUrl, SessionLifeTime |
886
+ | `initUnauthorised` | No | userId | SessionId, RedirectUrl, SessionLifeTime |
887
+ | `finalise` | No (uses session) | None | card |
888
+
889
+ ---
890
+
891
+ ## Support and Resources
892
+
893
+ For additional help:
894
+ - **API Documentation**: Refer to the main Payments API V21 documentation
895
+ - **Payture Documentation**: Check Payture's official EWallet API documentation
896
+ - **Database Procedures**:
897
+ - `escrow.tr_account_get_default` - Get user wallet
898
+ - `public.create_simple_wallet` - Create wallet
899
+ - `escrow.payment_method_create` - Save payment method
900
+ - **Support**: Contact your technical support team for integration assistance
901
+ - **Testing**: Always use sandbox environment before production deployment