skyflow-js 1.0.1 → 1.2.0

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 (39) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +388 -44
  3. package/dist/sdkNodeBuild/index.js +2 -1
  4. package/dist/sdkNodeBuild/index.js.LICENSE.txt +27 -0
  5. package/dist/sdkNodeBuild/index.js.LICENSE.txt.gz +0 -0
  6. package/dist/sdkNodeBuild/index.js.gz +0 -0
  7. package/package.json +9 -2
  8. package/types/Skyflow.d.ts +38 -8
  9. package/types/client/index.d.ts +2 -3
  10. package/types/container/constants.d.ts +26 -7
  11. package/types/container/external/CollectContainer.d.ts +14 -6
  12. package/types/container/external/PureJsController.d.ts +5 -3
  13. package/types/container/external/RevealContainer.d.ts +8 -6
  14. package/types/container/external/element/index.d.ts +3 -0
  15. package/types/container/external/reveal/RevealElement.d.ts +4 -1
  16. package/types/container/internal/iFrameForm/index.d.ts +15 -15
  17. package/types/container/internal/index.d.ts +2 -2
  18. package/types/container/internal/pureJs/PureJsFrameController.d.ts +2 -0
  19. package/types/container/internal/reveal/RevealFrameController.d.ts +1 -1
  20. package/types/core/collect.d.ts +1 -1
  21. package/types/core/reveal.d.ts +15 -6
  22. package/types/event-emitter/index.d.ts +1 -1
  23. package/types/iframe-libs/iframer.d.ts +3 -3
  24. package/types/index-internal.d.ts +1 -2
  25. package/types/index-node.d.ts +1 -1
  26. package/types/index.d.ts +1 -1
  27. package/types/libs/Bus.d.ts +3 -3
  28. package/types/libs/element-options.d.ts +1 -1
  29. package/types/libs/jss-styles.d.ts +1 -1
  30. package/types/libs/objectParse.d.ts +2 -0
  31. package/types/libs/regex.d.ts +2 -1
  32. package/types/libs/strings.d.ts +1 -1
  33. package/types/libs/styles.d.ts +2 -2
  34. package/types/properties.d.ts +2 -1
  35. package/types/utils/busEvents/index.d.ts +3 -0
  36. package/types/utils/helpers/index.d.ts +5 -0
  37. package/types/utils/jwtUtils/index.d.ts +2 -1
  38. package/types/utils/validators/index.d.ts +7 -2
  39. package/types/libs/NewBus.d.ts +0 -13
package/CHANGELOG.md ADDED
@@ -0,0 +1,39 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.2.0] - 2021-10-05
6
+
7
+ ### Added
8
+
9
+ - invokeGateway method to work with inbound/outbound integrations using Skyflow Gateway
10
+
11
+ ### Changed
12
+ - `table` and `column` are optional in CollectElementInput, when using invokeGateway
13
+ - `token` and `redaction` are optional in RevealElementInput, when using invokeGateway
14
+
15
+
16
+ ## [1.1.0] - 2021-09-22
17
+
18
+ ### Fixed:
19
+
20
+ - fix console errors
21
+
22
+ ### Added
23
+
24
+ - getById method to reveal fields using SkyflowID's
25
+ - support for Non-PCI fields, data can be passed as additional fields in container.collect method
26
+ - altText for CollectElement
27
+ - labelStyles for CollectElement
28
+ - errorTextStyles for CollectElement
29
+ - altText for RevealElement
30
+ - labelStyles for RevealElement
31
+ - errorTextStyles for RevealElement
32
+ - default error message for RevealElement
33
+
34
+ ### Changed
35
+
36
+ - Renamed get method to `detokenize`
37
+ - Renamed styles to inputStyles in CollectElement
38
+ - Renamed styles to inputStyles in RevealElement
39
+ - Renamed id to token in request and response of detokenize and `container.reveal()`
package/README.md CHANGED
@@ -8,6 +8,7 @@ Skyflow’s Javascript SDK can be used to securely collect, tokenize, and reveal
8
8
  - [**Initializing Skyflow.js**](#Initializing-Skyflowjs)
9
9
  - [**Securely collecting data client-side**](#Securely-collecting-data-client-side)
10
10
  - [**Securely revealing data client-side**](#Securely-revealing-data-client-side)
11
+ - [**Securely invoking gateway client-side**](#Securely-invoking-gateway-client-side)
11
12
 
12
13
  ---
13
14
 
@@ -115,14 +116,16 @@ skyflowClient.insert(records, options={})
115
116
 
116
117
  An example of an insert call:
117
118
  ```javascript
118
- skyflowClient.insert([
119
+ skyflowClient.insert({
120
+ "records": [
119
121
  {
120
122
  "table": "cards",
121
123
  "fields": {
122
124
  "cardNumber": "41111111111",
123
125
  "cvv": "123",
124
126
  }
125
- }]);
127
+ }]
128
+ });
126
129
  ```
127
130
 
128
131
  The sample response:
@@ -158,17 +161,22 @@ A Skyflow collect Element is defined as shown below:
158
161
 
159
162
  ```javascript
160
163
  var collectElement = {
161
- table: "string", //the table this data belongs to
162
- column: "string", //the column into which this data should be inserted
163
- styles: {}, //optional styles that should be applied to the form element
164
+ table: "string", //optional, the table this data belongs to
165
+ column: "string", //optional, the column into which this data should be inserted
166
+ type: Skyflow.ElementType, //Skyflow.ElementType enum
167
+ inputStyles: {}, //optional styles that should be applied to the form element
168
+ labelStyles: {}, //optional styles that will be applied to the label of the collect element
169
+ errorTextStyles:{}, //optional styles that will be applied to the errorText of the collect element
164
170
  label: "string", //optional label for the form element
165
171
  placeholder: "string", //optional placeholder for the form element
166
- type: Skyflow.ElementType //Skyflow.ElementType enum
172
+ altText: "string" //optional string that acts as an initial value for the collect element
167
173
  }
168
174
  ```
169
- The `table` and `column` fields indicate which table and column in the vault the Element corresponds to. **Note**: Use dot delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`).
175
+ The `table` and `column` fields indicate which table and column in the vault the Element corresponds to. **Note**:
176
+ - Use dot delimited strings to specify columns nested inside JSON fields (e.g. `address.street.line1`)
177
+ - `table` and `column` are optional only if the element is being used in invokeGateway()
170
178
 
171
- The `styles` field accepts a style object which consists of CSS properties that should be applied to the form element in the following states:
179
+ The `inputStyles` field accepts a style object which consists of CSS properties that should be applied to the form element in the following states:
172
180
  - `base`: all other variants inherit from these styles
173
181
  - `complete`: applied when the Element has valid input
174
182
  - `empty`: applied when the Element has no input
@@ -177,9 +185,9 @@ The `styles` field accepts a style object which consists of CSS properties that
177
185
 
178
186
  Styles are specified with [JSS](https://cssinjs.org/?v=v10.7.1).
179
187
 
180
- An example of a styles object:
188
+ An example of a inputStyles object:
181
189
  ```javascript
182
- styles:{
190
+ inputStyles:{
183
191
  base: {
184
192
  border: "1px solid #eae8ee",
185
193
  padding: "10px 16px",
@@ -197,6 +205,33 @@ styles:{
197
205
  }
198
206
  }
199
207
  ```
208
+ The states that are available for `labelStyles` are `base` and `focus`.
209
+
210
+ An example of a labelStyles object:
211
+
212
+ ```javascript
213
+ labelStyles: {
214
+ base: {
215
+ fontSize: "12px",
216
+ fontWeight: "bold"
217
+ },
218
+ focus: {
219
+ color: "#1d1d1d"
220
+ }
221
+ }
222
+ ```
223
+
224
+ The state that is available for `errorTextStyles` is only the `base` state, it shows up when there is some error in the collect element.
225
+
226
+ An example of a errorTextStyles object:
227
+
228
+ ```javascript
229
+ errorTextStyles: {
230
+ base: {
231
+ color: "#f44336"
232
+ }
233
+ }
234
+ ```
200
235
 
201
236
  Finally, the `type` field takes a Skyflow ElementType. Each type applies the appropriate regex and validations to the form element. There are currently 4 types:
202
237
  - `CARDHOLDER_NAME`
@@ -210,10 +245,13 @@ Once the Element object has been defined, add it to the container using the `cre
210
245
  var collectElement = {
211
246
  table: "string", //the table this data belongs to
212
247
  column: "string", //the column into which this data should be inserted
213
- styles: {}, //optional styles that should be applied to the form element
248
+ type: Skyflow.ElementType, //Skyflow.ElementType enum
249
+ inputStyles: {}, //optional styles that should be applied to the form element
250
+ labelStyles: {}, //optional styles that will be applied to the label of the collect element
251
+ errorTextStyles:{}, //optional styles that will be applied to the errorText of the collect element
214
252
  label: "string", //optional label for the form element
215
253
  placeholder: "string", //optional placeholder for the form element
216
- type: Skyflow.ElementType //Skyflow.ElementType enum
254
+ altText: "string" //optional string that acts as an initial value for the collect element
217
255
  }
218
256
 
219
257
  var options = {
@@ -251,9 +289,24 @@ element.mount("#cardNumber")
251
289
 
252
290
  When the form is ready to be submitted, call the `collect(options?)` method on the container object. The `options` parameter takes a dictionary of optional parameters as shown below:
253
291
 
292
+ - `tokens`: indicates whether tokens for the collected data should be returned or not. Defaults to 'true'
293
+ - `additionalFields`: Non-PCI elements data to be inserted into the vault which should be in the `records` object format as described in the above [Inserting data into vault](#inserting-data-into-the-vault) section.
294
+
254
295
  ```javascript
255
296
  var options = {
256
- tokens: true //indicates whether tokens for the collected data should be returned. Defaults to 'true'
297
+ tokens: true //optional, indicates whether tokens for the collected data should be returned. Defaults to 'true'
298
+ additionalFields: {
299
+ records: [
300
+ {
301
+ table: "string", //table into which record should be inserted
302
+ fields: {
303
+ column1: "value", //column names should match vault column names
304
+ //...additional fields here
305
+ }
306
+ }
307
+ //...additional records here
308
+ ]
309
+ } //optional
257
310
  }
258
311
 
259
312
  container.collect(options={})
@@ -271,11 +324,22 @@ const container = skyflowClient.container(Skyflow.ContainerType.COLLECT)
271
324
  const element = container.create({
272
325
  table: "cards",
273
326
  column: "cardNumber",
274
- styles: {
327
+ inputstyles: {
275
328
  base: {
276
329
  color: "#1d1d1d",
277
330
  },
278
- },
331
+ },
332
+ labelStyles: {
333
+ base: {
334
+ fontSize: "12px",
335
+ fontWeight: "bold"
336
+ }
337
+ },
338
+ errorTextStyles: {
339
+ base: {
340
+ color: "#f44336"
341
+ }
342
+ },
279
343
  placeholder: "Card Number",
280
344
  label: "card_number",
281
345
  type: Skyflow.ElementType.CARD_NUMBER
@@ -285,7 +349,22 @@ const element = container.create({
285
349
  element.mount("#cardNumber") //assumes there is a div with id="#cardNumber" in the webpage
286
350
 
287
351
  // Step 4
288
- container.collect()
352
+
353
+ const nonPCIRecords = {
354
+ "records": [
355
+ {
356
+ "table": "cards",
357
+ "fields": {
358
+ "gender": "MALE"
359
+ }
360
+ }
361
+ ]
362
+ }
363
+
364
+ container.collect({
365
+ tokens: true,
366
+ additionalFields: nonPCIRecords
367
+ })
289
368
  ```
290
369
 
291
370
  **Sample Response :**
@@ -295,7 +374,8 @@ container.collect()
295
374
  {
296
375
  "table": "cards",
297
376
  "fields": {
298
- "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1"
377
+ "cardNumber": "f3907186-e7e2-466f-91e5-48e12c2bcbc1",
378
+ "gender": "12f670af-6c7d-4837-83fb-30365fbc0b1e"
299
379
  }
300
380
  }
301
381
  ]
@@ -311,17 +391,22 @@ container.collect()
311
391
 
312
392
  ## Retrieving data from the vault
313
393
 
314
- For non-PCI use cases, to retrieve data from the vault and reveal it in the browser, use the `get(records)` method of the Skyflow client. The `records` parameter takes an array of records to be fetched as shown below.
394
+ For non-PCI use-cases, retrieving data from the vault and revealing it in the browser can be done either using the SkyflowID's or tokens as described below
395
+
396
+ - ### Using Skyflow tokens
397
+ For retrieving using tokens, use the `detokenize(records)` method. The records parameter takes a JSON object that contains `records` to be fetched as shown below.
315
398
 
316
399
  ```javascript
317
- var records = [
318
- {
319
- id: "string", //Token for the record to be fetched
320
- redaction: Skyflow.RedactionType //redaction to be applied to the retrieved data
321
- }
322
- ]
400
+ var records = {
401
+ "records": [
402
+ {
403
+ token: "string", // token for the record to be fetched
404
+ redaction: Skyflow.RedactionType //redaction to be applied to retrieved data
405
+ }
406
+ ]
407
+ }
323
408
 
324
- skyflow.get(records)
409
+ skyflow.detokenize(records)
325
410
  ```
326
411
 
327
412
  There are 4 accepted values in Skyflow.RedactionTypes:
@@ -333,12 +418,14 @@ There are 4 accepted values in Skyflow.RedactionTypes:
333
418
  An example of a get call:
334
419
 
335
420
  ```javascript
336
- skyflow.get([
337
- {
338
- id: "131e70dc-6f76-4319-bdd3-96281e051051",
339
- redaction: Skyflow.RedactionType.PLAIN_TEXT
340
- }
341
- ])
421
+ skyflow.detokenize({
422
+ "records": [
423
+ {
424
+ token: "131e70dc-6f76-4319-bdd3-96281e051051",
425
+ redaction: Skyflow.RedactionType.PLAIN_TEXT
426
+ }
427
+ ]
428
+ })
342
429
  ```
343
430
 
344
431
  The sample response:
@@ -346,13 +433,76 @@ The sample response:
346
433
  {
347
434
  "records": [
348
435
  {
349
- "id": "131e70dc-6f76-4319-bdd3-96281e051051",
436
+ "token": "131e70dc-6f76-4319-bdd3-96281e051051",
350
437
  "date_of_birth": "1990-01-01",
351
438
  }
352
439
  ]
353
440
  }
354
441
  ```
355
442
 
443
+ - ### Using Skyflow ID's
444
+ For retrieving using SkyflowID's, use the `getById(records)` method.The records parameter takes a JSON object that contains `records` to be fetched as shown below.
445
+
446
+ ```javascript
447
+ {
448
+ "records": [
449
+ {
450
+ ids: string[], // array of SkyflowID's of the records to be fetched
451
+ table: string // table holding the above skyflow_id's
452
+ redaction: Skyflow.RedactionType // redaction to be applied to retrieved data
453
+ }
454
+ ]
455
+ }
456
+ ```
457
+
458
+ An example of getById call:
459
+
460
+ ```javascript
461
+
462
+ skyflow.getById({
463
+ records: [
464
+ {
465
+ ids: ["f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"],
466
+ table: "cards",
467
+ redaction: Skyflow.RedactionType.PLAIN_TEXT,
468
+ },
469
+ {
470
+ ids: ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"],
471
+ table: "contacts",
472
+ redaction: Skyflow.RedactionType.PLAIN_TEXT,
473
+ },
474
+ ],
475
+ });
476
+ ```
477
+
478
+ The sample response:
479
+
480
+ ```javascript
481
+ {
482
+ "records": [
483
+ {
484
+ "fields": {
485
+ "card_number": "4111111111111111",
486
+ "cvv": "127",
487
+ "expiry_date": "11/2035",
488
+ "fullname": "myname",
489
+ "id": "f8d8a622-b557-4c6b-a12c-c5ebe0b0bfd9"
490
+ },
491
+ "table": "cards"
492
+ }
493
+ ],
494
+ "errors": [
495
+ {
496
+ "error": {
497
+ "code": "404",
498
+ "description": "No Records Found"
499
+ },
500
+ "ids": ["da26de53-95d5-4bdb-99db-8d8c66a35ff9"]
501
+ }
502
+ ]
503
+ }
504
+ ```
505
+
356
506
  ## Using Skyflow Elements to reveal data
357
507
 
358
508
  Skyflow Elements can be used to securely reveal data in a browser without exposing your front end to the sensitive data. This is great for use cases like card issuance where you may want to reveal the card number to a user without increasing your PCI compliance scope.
@@ -370,14 +520,52 @@ Then define a Skyflow Element to reveal data as shown below.
370
520
 
371
521
  ```javascript
372
522
  var revealElement = {
373
- id: "string", //token of the data being revealed
523
+ token: "string", //optional, token of the data being revealed
374
524
  redaction: Skyflow.RedactionType, //redaction type to be applied to the data when revealed
375
- styles: {}, //optional styles to be applied to the element
376
- label: "string" //label for the form element
525
+ inputStyles: {}, //optional styles to be applied to the element
526
+ labelStyles: {}, //optional, styles to be applied to the label of the reveal element
527
+ errorTextStyles: {}, //optional styles that will be applied to the errorText of the reveal element
528
+ label: "string", //label for the form element
529
+ altText: "string" //optional, string that is shown before reveal, will show token if altText is not provided
530
+ }
531
+ ```
532
+ `Note`:
533
+ - `token` is optional only if it is being used in invokeGateway()
534
+
535
+ For a list of acceptable RedactionTypes, see the [section above](#Retrieving-data-from-the-vault).
536
+
537
+ The `inputStyles`, `labelStyles` and `errorTextStyles` parameters accepts a styles object as described in the [previous section](#step-2-create-a-collect-element) for collecting data but only a single variant is available i.e. base.
538
+
539
+ An example of a inputStyles object:
540
+
541
+ ```javascript
542
+ inputStyles: {
543
+ base: {
544
+ color: "#1d1d1d"
545
+ }
546
+ }
547
+ ```
548
+
549
+ An example of a labelStyles object:
550
+
551
+ ```javascript
552
+ labelStyles: {
553
+ base: {
554
+ fontSize: "12px",
555
+ fontWeight: "bold"
556
+ }
377
557
  }
378
558
  ```
379
559
 
380
- The `styles` parameter accepts a styles object as described in the [previous section](#step-2-create-a-collect-element) for collecting data. For a list of acceptable RedactionTypes, see the [section above](#Retrieving-data-from-the-vault).
560
+ An example of a errorTextStyles object:
561
+
562
+ ```javascript
563
+ errorTextStyles: {
564
+ base: {
565
+ color: "#f44336"
566
+ }
567
+ }
568
+ ```
381
569
 
382
570
  Once you've defined a Skyflow Element, you can use the `create(element)` method of the container to create the Element as shown below:
383
571
 
@@ -412,25 +600,37 @@ const container = skyflowClient.container(Skyflow.ContainerType.REVEAL)
412
600
 
413
601
  //Step 2
414
602
  const cardNumberElement = container.create({
415
- id: "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
603
+ token: "b63ec4e0-bbad-4e43-96e6-6bd50f483f75",
416
604
  redaction: Skyflow.RedactionType.DEFAULT,
417
- styles: {
605
+ inputStyles: {
418
606
  base: {
419
607
  color: "#1d1d1d",
420
608
  },
421
- },
609
+ },
610
+ labelStyles: {
611
+ base: {
612
+ fontSize: "12px",
613
+ }
614
+ },
615
+ errorTextStyles: {
616
+ base: {
617
+ color: "#f44336"
618
+ }
619
+ },
422
620
  label: "card_number",
621
+ altText: "XXXX XXXX XXXX XXXX"
423
622
  })
424
623
 
425
624
  const cvvElement = container.create({
426
- id: "89024714-6a26-4256-b9d4-55ad69aa4047",
625
+ token: "89024714-6a26-4256-b9d4-55ad69aa4047",
427
626
  redaction: Skyflow.RedactionType.DEFAULT,
428
- styles: {
627
+ inputStyles: {
429
628
  base: {
430
629
  color: "#1d1d1d",
431
630
  },
432
631
  },
433
632
  label: "cvv",
633
+ altText: "XXX"
434
634
  })
435
635
 
436
636
  //Step 3
@@ -456,12 +656,12 @@ The response below shows that some tokens assigned to the reveal elements get re
456
656
  {
457
657
  "success": [
458
658
  {
459
- "id": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75"
659
+ "token": "b63ec4e0-bbad-4e43-96e6-6bd50f483f75"
460
660
  }
461
661
  ],
462
662
  "errors": [
463
663
  {
464
- "id": "89024714-6a26-4256-b9d4-55ad69aa4047",
664
+ "token": "89024714-6a26-4256-b9d4-55ad69aa4047",
465
665
  "error": {
466
666
  "code": 404,
467
667
  "description": "Tokens not found for 89024714-6a26-4256-b9d4-55ad69aa4047"
@@ -469,4 +669,148 @@ The response below shows that some tokens assigned to the reveal elements get re
469
669
  }
470
670
  ]
471
671
  }
472
- ```
672
+ ```
673
+
674
+ # Securely invoking gateway client-side
675
+ Using Skyflow gateway, end-user applications can integrate checkout/card issuance flow without any of their apps/systems touching the PCI compliant fields like cvv, card number. To invoke gateway, use the `invokeGateway(gatewayConfig)` method of the Skyflow client.
676
+
677
+ ```javascript
678
+ const gatewayConfig = {
679
+ gatewayURL: string, // gateway url recevied when creating a skyflow gateway integration
680
+ methodName: Skyflow.RequestMethod,
681
+ pathParams: any, // optional
682
+ queryParams: any, // optional
683
+ requestHeader: any, // optional
684
+ requestBody: any, // optional
685
+ responseBody: any // optional
686
+ }
687
+
688
+ const response = skyflowClient.invokeGateway(gatewayConfig);
689
+ ```
690
+ `methodName` supports the following methods:
691
+
692
+ - GET
693
+ - POST
694
+ - PUT
695
+ - PATCH
696
+ - DELETE
697
+
698
+ **pathParams, queryParams, requestHeader, requestBody** are the JSON objects that will be sent through the gateway integration url.
699
+
700
+ The values in the above parameters can contain collect elements, reveal elements or actual values. When elements are provided inplace of values, they get replaced with the value entered in the collect elements or value present in the reveal elements
701
+
702
+ **responseBody**:
703
+ It is a JSON object that specifies where to render the response in the UI. The values in the responseBody can contain collect elements or reveal elements.
704
+
705
+ Sample use-cases on using invokeGateway():
706
+
707
+ ### Sample use-case 1:
708
+
709
+ Merchant acceptance - customers should be able to complete payment checkout without cvv touching their application. This means that the merchant should be able to receive a CVV and process a payment without exposing their front-end to any PCI data
710
+
711
+ ```javascript
712
+ // step 1
713
+ const skyflowClient = skyflow.init({
714
+ vaultID: <vault_Id>,
715
+ vaultURL: <vault_url>,
716
+ getBearerToken: <helperFunc>
717
+ });
718
+
719
+ // step 2
720
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT)
721
+
722
+ // step 3
723
+ const cardNumberElement = collectContainer.create({
724
+ type: skyflow.ElementType.CARD_NUMBER
725
+ })
726
+ cardNumberElement.mount("#cardNumber")
727
+
728
+ const cvvElement = collectContainer.create({
729
+ type: skyflow.ElementType.CVV
730
+ })
731
+ cvvElement.mount("#cvv")
732
+
733
+ // step 4
734
+ const gatewayConfig = {
735
+ gatewayURL: "https://area51.gateway.skyflow.com/v1/gateway/inboundRoutes/abc-1213/v2/pay”,
736
+ methodName: Skyflow.RequestMethod.POST,
737
+ requestBody: {
738
+ card_number: cardNumberElement, //it can be skyflow element(collect or reveal) or actual value
739
+ cvv: cvvElement,
740
+ }
741
+ }
742
+
743
+ const response = skyflowClient.invokeGateway(gatewayConfig);
744
+ ```
745
+
746
+ Sample Response:
747
+ ```javascript
748
+ {
749
+ "receivedTimestamp": "2019-05-29 21:49:56.625",
750
+ "processingTimeinMs": 116
751
+ }
752
+ ```
753
+ In the above example, CVV is being collected from the user input at the time of checkout and not stored anywhere in the vault
754
+
755
+ `Note:`
756
+ - card_number can be either container element or plain text value (tokens or actual value)
757
+ - `table` and `column` names are not required for creating collect element, if it is used for invokeGateway method, since they will not be stored in the vault
758
+
759
+ ### Sample use-case 2:
760
+
761
+ Card issuance - customers want to issue cards from card issuer service and should generate the CVV dynamically without increasing their PCI scope.
762
+ ```javascript
763
+ // step 1
764
+ const skyflowClient = skyflow.init({
765
+ vaultID: <vault_Id>,
766
+ vaultURL: <vault_url>,
767
+ getBearerToken: <helperFunc>
768
+ });
769
+
770
+ // step 2
771
+ const revealContainer = skyflowClient.container(Skyflow.ContainerType.REVEAL)
772
+ const collectContainer = skyflowClient.container(Skyflow.ContainerType.COLLECT)
773
+
774
+ // step 3
775
+ const cvvElement = revealContainer.create({
776
+ type: skyflow.RedactionType.PLAIN_TEXT,
777
+ })
778
+ cvvElement.mount("#cvv")
779
+
780
+ const expiryDateElement = collectContainer.create({
781
+ type: skyflow.ElementType.EXPIRATION_DATE
782
+ })
783
+ expiryDateElement.mount("#expirationDate")
784
+
785
+ //step 4
786
+ const gatewayConfig = {
787
+ gatewayURL: "https://area51.gateway.skyflow.com/v1/gateway/inboundRoutes/abc-1213/cards/{card_number}/cvv2generation",
788
+ methodName: Skyflow.RequestMethod.POST,
789
+ pathParams: {
790
+ card_number: "0905-8672-0773-0628" //it can be skyflow element(collect/reveal) or token or actual value
791
+ },
792
+ requestBody: {
793
+ expirationDate: expiryDateElement //it can be skyflow element(collect/reveal) or token or actual value
794
+ },
795
+ responseBody: {
796
+ resource: {
797
+ cvv2: cvvElement // pass the element where the cvv response from the gateway will be mounted
798
+ }
799
+ }
800
+ }
801
+ }
802
+
803
+ const response = skyflowClient.invokeGateway(gatewayConfig);
804
+ ```
805
+
806
+ Sample Response:
807
+ ```javascript
808
+ {
809
+ "receivedTimestamp": "2019-05-29 21:49:56.625",
810
+ "processingTimeinMs": 116
811
+ }
812
+ ```
813
+
814
+ `Note`:
815
+ - `token` and `redaction` are optional for creating reveal element, if it is used for invokeGateway
816
+ - responseBody contains collect or reveal elements to render the response from the gateway on UI