@tonder.io/ionic-lite-sdk 0.0.26-beta → 0.0.29-beta

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.
package/README.md CHANGED
@@ -437,6 +437,84 @@ const jsonResponseRouter = await liteCheckout.startCheckoutRouter(
437
437
 
438
438
  ## Take actions on base to the checkout router response
439
439
 
440
+ # Checkout router full
441
+
442
+ <font size="4">This method integrate the create order, create payment and checkout router methods into one method, the info required to this method is:</font>
443
+
444
+ ```typescript
445
+
446
+ const returnUrl = "http://localhost:8100/payment/success";
447
+
448
+ let checkoutData = {
449
+ customer: {
450
+ name: "Jhon",
451
+ lastname: "Doe",
452
+ email: "john.c.calhoun@examplepetstore.com",
453
+ phone: "+58452258525"
454
+ },
455
+ order: {
456
+ items: [
457
+ {
458
+ description: "Test product description",
459
+ quantity: 1,
460
+ price_unit: 25,
461
+ discount: 1,
462
+ taxes: 12,
463
+ product_reference: 89456123,
464
+ name: "Test product",
465
+ amount_total: 25
466
+ }
467
+ ]
468
+ },
469
+ return_url: returnUrl,
470
+ total: 25,
471
+ isSandbox: true,
472
+ metadata: {},
473
+ currency: "MXN",
474
+ skyflowTokens: {
475
+ cardholder_name: "",
476
+ card_number: "",
477
+ expiration_year: "",
478
+ expiration_month: "",
479
+ cvv: "",
480
+ skyflow_id: ""
481
+ }
482
+ }
483
+
484
+ ```
485
+
486
+ <font size="4">It is required get the skyflow tokens to add it to the checkout router method, the values of the variable skyflowFields come from your html form</font>
487
+
488
+ ```typescript
489
+
490
+ const merchantData: any = await liteCheckout.getBusiness();
491
+
492
+ const { vault_id, vault_url } = merchantData;
493
+
494
+ const skyflowFields = {
495
+ card_number: this.paymentForm.value.cardNumber,
496
+ cvv: this.paymentForm.value.cvv,
497
+ expiration_month: this.paymentForm.value.month,
498
+ expiration_year: this.paymentForm.value.expirationYear,
499
+ cardholder_name: this.paymentForm.value.name
500
+ }
501
+
502
+ const skyflowTokens = await liteCheckout.getSkyflowTokens({
503
+ vault_id: vault_id,
504
+ vault_url: vault_url,
505
+ data: skyflowFields
506
+ })
507
+
508
+ checkoutData.skyflowTokens = skyflowTokens;
509
+
510
+ const jsonResponseRouter: any = await liteCheckout.startCheckoutRouterFull(
511
+ checkoutData
512
+ );
513
+
514
+ ```
515
+
516
+ <font size="4">The response is the same to the startCheckoutRouter method. Take actions on base to the checkout router response</font>
517
+
440
518
  # Customer Cards(Register)
441
519
 
442
520
  ## Register customer card
@@ -1,5 +1,5 @@
1
1
  import CollectContainer from "skyflow-js/types/core/external/collect/collect-container";
2
- import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest } from "../types/requests";
2
+ import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest, StartCheckoutFullRequest } from "../types/requests";
3
3
  import { GetBusinessResponse, CustomerRegisterResponse, CreateOrderResponse, CreatePaymentResponse, StartCheckoutResponse, GetCustomerCardsResponse, RegisterCustomerCardResponse } from "../types/responses";
4
4
  import { ErrorResponse } from "./errorResponse";
5
5
  declare global {
@@ -23,6 +23,7 @@ export declare class LiteCheckout implements LiteCheckoutConstructor {
23
23
  createOrder(orderItems: CreateOrderRequest): Promise<CreateOrderResponse | ErrorResponse>;
24
24
  createPayment(paymentItems: CreatePaymentRequest): Promise<CreatePaymentResponse | ErrorResponse>;
25
25
  startCheckoutRouter(routerData: StartCheckoutRequest): Promise<StartCheckoutResponse | ErrorResponse>;
26
+ startCheckoutRouterFull(routerFullData: StartCheckoutFullRequest): Promise<StartCheckoutResponse | ErrorResponse>;
26
27
  getSkyflowTokens({ vault_id, vault_url, data, }: TokensRequest): Promise<any | ErrorResponse>;
27
28
  getVaultToken(): Promise<string>;
28
29
  getFieldsPromise(data: any, collectContainer: CollectContainer): Promise<Promise<boolean>[]>;
@@ -1,3 +1,9 @@
1
- export declare const createObserver: ({ target }: {
2
- target: string;
3
- }) => Promise<any>;
1
+ export declare const getBrowserInfo: () => {
2
+ javascript_enabled: boolean;
3
+ time_zone: number;
4
+ language: string;
5
+ color_depth: number | null;
6
+ screen_width: number | null;
7
+ screen_height: number | null;
8
+ user_agent: string;
9
+ };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import e from"skyflow-js";function t(e,t,o,r){return new(o||(o=Promise))((function(i,n){function s(e){try{a(r.next(e))}catch(e){n(e)}}function d(e){try{a(r.throw(e))}catch(e){n(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(s,d)}a((r=r.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class o{constructor({code:e,body:t,name:o,message:r,stack:i}){this.code=e,this.body=t,this.name=o,this.message=r,this.stack=i}}class r{constructor({signal:e,baseUrlTonder:t,apiKeyTonder:o}){this.baseUrlTonder=t,this.signal=e,this.apiKeyTonder=o}getOpenpayDeviceSessionID(e,o,r){return t(this,void 0,void 0,(function*(){try{let t=yield window.OpenPay;return t.setId(e),t.setApiKey(o),t.setSandboxMode(r),yield t.deviceData.setup({signal:this.signal})}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getBusiness(){return t(this,void 0,void 0,(function*(){try{const e=yield fetch(`${this.baseUrlTonder}/api/v1/payments/business/${this.apiKeyTonder}`,{headers:{Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal});if(e.ok)return yield e.json();throw yield this.buildErrorResponse(e)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}customerRegister(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/customer/`,o={email:e},r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal,body:JSON.stringify(o)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}createOrder(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/orders/`,o=e,r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(o)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}createPayment(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/business/${e.business_pk}/payments/`,o=e,r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(o)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}startCheckoutRouter(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/checkout-router/`,o=e,r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(o)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getSkyflowTokens({vault_id:o,vault_url:r,data:i}){return t(this,void 0,void 0,(function*(){const n=e.init({vaultID:o,vaultURL:r,getBearerToken:()=>t(this,void 0,void 0,(function*(){return yield this.getVaultToken()})),options:{logLevel:e.LogLevel.ERROR,env:e.Env.DEV}}).container(e.ContainerType.COLLECT),s=yield this.getFieldsPromise(i,n);if((yield Promise.all(s)).some((e=>!e)))throw this.buildErrorResponseFromCatch(Error("Ocurrió un error al montar los campos de la tarjeta"));try{const e=yield n.collect();if(e)return e.records[0].fields;throw this.buildErrorResponseFromCatch(Error("Por favor, verifica todos los campos de tu tarjeta"))}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getVaultToken(){var e;return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/vault-token/`,{method:"GET",headers:{Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal});if(t.ok)return null===(e=yield t.json())||void 0===e?void 0:e.token;throw new Error(`HTTPCODE: ${t.status}`)}catch(e){throw new Error(`Failed to retrieve bearer token; ${"string"==typeof e?e:e.message}`)}}))}getFieldsPromise(e,o){return t(this,void 0,void 0,(function*(){const t=yield this.getFields(e,o);return t?t.map((t=>new Promise((o=>{var r;const i=document.createElement("div");i.hidden=!0,i.id=`id-${t.key}`,null===(r=document.querySelector("body"))||void 0===r||r.appendChild(i),setTimeout((()=>{t.element.mount(`#id-${t.key}`),setInterval((()=>{if(t.element.isMounted()){const r=e[t.key];return t.element.update({value:r}),o(t.element.isMounted())}}),120)}),120)})))):[]}))}registerCustomerCard(e,o){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/`,{method:"POST",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal,body:JSON.stringify(o)});if(t.ok)return yield t.json();throw yield this.buildErrorResponse(t)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getCustomerCards(e,o=""){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/${o}`,{method:"GET",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal});if(t.ok)return yield t.json();throw yield this.buildErrorResponse(t)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}deleteCustomerCard(e,o=""){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/${o}`,{method:"DELETE",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal});if(t.ok)return!0;throw yield this.buildErrorResponse(t)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}buildErrorResponseFromCatch(e){return new o({code:(null==e?void 0:e.status)?e.status:e.code,body:null==e?void 0:e.body,name:e?"string"==typeof e?"catch":e.name:"Error",message:e?"string"==typeof e?e:e.message:"Error",stack:"string"==typeof e?void 0:e.stack})}buildErrorResponse(e,r=void 0){return t(this,void 0,void 0,(function*(){let t,i,n="Error";e&&"json"in e&&(t=yield null==e?void 0:e.json()),e&&"status"in e&&(i=e.status.toString()),e&&"text"in e&&(n=yield e.text());return new o({code:i,body:t,name:i,message:n,stack:r})}))}getFields(o,r){return t(this,void 0,void 0,(function*(){return yield Promise.all(Object.keys(o).map((o=>t(this,void 0,void 0,(function*(){return{element:yield r.create({table:"cards",column:o,type:e.ElementType.INPUT_FIELD}),key:o}})))))}))}}export{r as LiteCheckout};
1
+ import e from"skyflow-js";function t(e,t,i,r){return new(i||(i=Promise))((function(o,n){function s(e){try{a(r.next(e))}catch(e){n(e)}}function d(e){try{a(r.throw(e))}catch(e){n(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(s,d)}a((r=r.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class i{constructor({code:e,body:t,name:i,message:r,stack:o}){this.code=e,this.body=t,this.name=i,this.message=r,this.stack=o}}class r{constructor({signal:e,baseUrlTonder:t,apiKeyTonder:i}){this.baseUrlTonder=t,this.signal=e,this.apiKeyTonder=i}getOpenpayDeviceSessionID(e,i,r){return t(this,void 0,void 0,(function*(){try{let t=yield window.OpenPay;return t.setId(e),t.setApiKey(i),t.setSandboxMode(r),yield t.deviceData.setup({signal:this.signal})}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getBusiness(){return t(this,void 0,void 0,(function*(){try{const e=yield fetch(`${this.baseUrlTonder}/api/v1/payments/business/${this.apiKeyTonder}`,{headers:{Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal});if(e.ok)return yield e.json();throw yield this.buildErrorResponse(e)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}customerRegister(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/customer/`,i={email:e},r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal,body:JSON.stringify(i)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}createOrder(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/orders/`,i=e,r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(i)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}createPayment(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/business/${e.business_pk}/payments/`,i=e,r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(i)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}startCheckoutRouter(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/checkout-router/`,i=e,r=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(i)});if(r.ok)return yield r.json();throw yield this.buildErrorResponse(r)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}startCheckoutRouterFull(e){return t(this,void 0,void 0,(function*(){try{const{order:t,total:r,customer:o,skyflowTokens:n,return_url:s,isSandbox:d,metadata:a,currency:l}=e,h=yield this.getBusiness(),c=yield this.customerRegister(o.email);if(c&&"auth_token"in c&&h&&"reference"in h){const e={business:this.apiKeyTonder,client:c.auth_token,billing_address_id:null,shipping_address_id:null,amount:r,reference:h.reference,is_oneclick:!0,items:t.items},u=yield this.createOrder(e),y=(new Date).toISOString();if("id"in u&&"id"in c&&"business"in h){const e={business_pk:h.business.pk,amount:r,date:y,order_id:u.id,client_id:c.id},t=yield this.createPayment(e);let i;const{openpay_keys:p,business:m}=h;p.merchant_id&&p.public_key&&(i=yield this.getOpenpayDeviceSessionID(p.merchant_id,p.public_key,d));const v={card:n,name:n.cardholder_name,last_name:o.lastname,email_client:o.email,phone_number:o.phone,return_url:s,id_product:"no_id",quantity_product:1,id_ship:"0",instance_id_ship:"0",amount:r,title_ship:"shipping",description:"transaction",device_session_id:i||null,token_id:"",order_id:"id"in u&&u.id,business_id:m.pk,payment_id:"pk"in t&&t.pk,source:"sdk",metadata:a,browser_info:{javascript_enabled:!0,time_zone:(new Date).getTimezoneOffset(),language:navigator.language||"en-US",color_depth:window.screen?window.screen.colorDepth:null,screen_width:window.screen?window.screen.width*window.devicePixelRatio||window.screen.width:null,screen_height:window.screen?window.screen.height*window.devicePixelRatio||window.screen.height:null,user_agent:navigator.userAgent},currency:l};return yield this.startCheckoutRouter(v)}throw new i({code:"500",body:u,name:"Keys error",message:"Order response errors"})}throw new i({code:"500",body:h,name:"Keys error",message:"Merchant or customer reposne errors"})}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getSkyflowTokens({vault_id:i,vault_url:r,data:o}){return t(this,void 0,void 0,(function*(){const n=e.init({vaultID:i,vaultURL:r,getBearerToken:()=>t(this,void 0,void 0,(function*(){return yield this.getVaultToken()})),options:{logLevel:e.LogLevel.ERROR,env:e.Env.DEV}}).container(e.ContainerType.COLLECT),s=yield this.getFieldsPromise(o,n);if((yield Promise.all(s)).some((e=>!e)))throw this.buildErrorResponseFromCatch(Error("Ocurrió un error al montar los campos de la tarjeta"));try{const e=yield n.collect();if(e)return e.records[0].fields;throw this.buildErrorResponseFromCatch(Error("Por favor, verifica todos los campos de tu tarjeta"))}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getVaultToken(){var e;return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/vault-token/`,{method:"GET",headers:{Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal});if(t.ok)return null===(e=yield t.json())||void 0===e?void 0:e.token;throw new Error(`HTTPCODE: ${t.status}`)}catch(e){throw new Error(`Failed to retrieve bearer token; ${"string"==typeof e?e:e.message}`)}}))}getFieldsPromise(e,i){return t(this,void 0,void 0,(function*(){const t=yield this.getFields(e,i);return t?t.map((t=>new Promise((i=>{var r;const o=document.createElement("div");o.hidden=!0,o.id=`id-${t.key}`,null===(r=document.querySelector("body"))||void 0===r||r.appendChild(o),setTimeout((()=>{t.element.mount(`#id-${t.key}`),setInterval((()=>{if(t.element.isMounted()){const r=e[t.key];return t.element.update({value:r}),i(t.element.isMounted())}}),120)}),120)})))):[]}))}registerCustomerCard(e,i){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/`,{method:"POST",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal,body:JSON.stringify(i)});if(t.ok)return yield t.json();throw yield this.buildErrorResponse(t)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}getCustomerCards(e,i=""){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/${i}`,{method:"GET",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal});if(t.ok)return yield t.json();throw yield this.buildErrorResponse(t)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}deleteCustomerCard(e,i=""){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/${i}`,{method:"DELETE",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal});if(t.ok)return!0;throw yield this.buildErrorResponse(t)}catch(e){throw this.buildErrorResponseFromCatch(e)}}))}buildErrorResponseFromCatch(e){return new i({code:(null==e?void 0:e.status)?e.status:e.code,body:null==e?void 0:e.body,name:e?"string"==typeof e?"catch":e.name:"Error",message:e?"string"==typeof e?e:e.message:"Error",stack:"string"==typeof e?void 0:e.stack})}buildErrorResponse(e,r=void 0){return t(this,void 0,void 0,(function*(){let t,o,n="Error";e&&"json"in e&&(t=yield null==e?void 0:e.json()),e&&"status"in e&&(o=e.status.toString()),e&&"text"in e&&(n=yield e.text());return new i({code:o,body:t,name:o,message:n,stack:r})}))}getFields(i,r){return t(this,void 0,void 0,(function*(){return yield Promise.all(Object.keys(i).map((i=>t(this,void 0,void 0,(function*(){return{element:yield r.create({table:"cards",column:i,type:e.ElementType.INPUT_FIELD}),key:i}})))))}))}}export{r as LiteCheckout};
@@ -57,3 +57,27 @@ export type TokensRequest = {
57
57
  [key: string]: any;
58
58
  };
59
59
  };
60
+ export type StartCheckoutFullRequest = {
61
+ order: {
62
+ items: OrderItem[];
63
+ };
64
+ total: number;
65
+ customer: {
66
+ name: string;
67
+ lastname: string;
68
+ email: string;
69
+ phone: string;
70
+ };
71
+ skyflowTokens: {
72
+ cardholder_name: string;
73
+ card_number: string;
74
+ cvv: string;
75
+ expiration_year: string;
76
+ expiration_month: string;
77
+ skyflow_id: string;
78
+ };
79
+ return_url: string;
80
+ isSandbox: boolean;
81
+ metadata: any;
82
+ currency: string;
83
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonder.io/ionic-lite-sdk",
3
- "version": "0.0.26-beta",
3
+ "version": "0.0.29-beta",
4
4
  "description": "Tonder ionic lite SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -2,9 +2,10 @@ import Skyflow from "skyflow-js";
2
2
  import CollectContainer from "skyflow-js/types/core/external/collect/collect-container";
3
3
  import CollectElement from "skyflow-js/types/core/external/collect/collect-element";
4
4
  import { Business } from "../types/commons";
5
- import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest } from "../types/requests";
5
+ import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest, StartCheckoutFullRequest } from "../types/requests";
6
6
  import { GetBusinessResponse, CustomerRegisterResponse, CreateOrderResponse, CreatePaymentResponse, StartCheckoutResponse, GetVaultTokenResponse, IErrorResponse, GetCustomerCardsResponse, RegisterCustomerCardResponse } from "../types/responses";
7
7
  import { ErrorResponse } from "./errorResponse";
8
+ import { getBrowserInfo } from "../helpers/utils";
8
9
 
9
10
  declare global {
10
11
  interface Window {
@@ -149,6 +150,127 @@ export class LiteCheckout implements LiteCheckoutConstructor {
149
150
  }
150
151
  }
151
152
 
153
+ async startCheckoutRouterFull(routerFullData: StartCheckoutFullRequest): Promise<StartCheckoutResponse | ErrorResponse> {
154
+
155
+ try {
156
+
157
+ const {
158
+ order,
159
+ total,
160
+ customer,
161
+ skyflowTokens,
162
+ return_url,
163
+ isSandbox,
164
+ metadata,
165
+ currency
166
+ } = routerFullData;
167
+
168
+ const merchantResult = await this.getBusiness();
169
+
170
+ const customerResult : CustomerRegisterResponse | ErrorResponse = await this.customerRegister(customer.email);
171
+
172
+ if(customerResult && "auth_token" in customerResult && merchantResult && "reference" in merchantResult) {
173
+
174
+ const orderData: CreateOrderRequest = {
175
+ business: this.apiKeyTonder,
176
+ client: customerResult.auth_token,
177
+ billing_address_id: null,
178
+ shipping_address_id: null,
179
+ amount: total,
180
+ reference: merchantResult.reference,
181
+ is_oneclick: true,
182
+ items: order.items,
183
+ };
184
+
185
+ const orderResult = await this.createOrder(orderData);
186
+
187
+ const now = new Date();
188
+
189
+ const dateString = now.toISOString();
190
+
191
+ if("id" in orderResult && "id" in customerResult && "business" in merchantResult) {
192
+
193
+ const paymentItems: CreatePaymentRequest = {
194
+ business_pk: merchantResult.business.pk,
195
+ amount: total,
196
+ date: dateString,
197
+ order_id: orderResult.id,
198
+ client_id: customerResult.id
199
+ };
200
+
201
+ const paymentResult = await this.createPayment(
202
+ paymentItems
203
+ );
204
+
205
+ let deviceSessionIdTonder: any;
206
+
207
+ const { openpay_keys, business } = merchantResult
208
+
209
+ if (openpay_keys.merchant_id && openpay_keys.public_key) {
210
+ deviceSessionIdTonder = await this.getOpenpayDeviceSessionID(
211
+ openpay_keys.merchant_id,
212
+ openpay_keys.public_key,
213
+ isSandbox
214
+ );
215
+ }
216
+
217
+ const routerItems: StartCheckoutRequest = {
218
+ card: skyflowTokens,
219
+ name: skyflowTokens.cardholder_name,
220
+ last_name: customer.lastname,
221
+ email_client: customer.email,
222
+ phone_number: customer.phone,
223
+ return_url: return_url,
224
+ id_product: "no_id",
225
+ quantity_product: 1,
226
+ id_ship: "0",
227
+ instance_id_ship: "0",
228
+ amount: total,
229
+ title_ship: "shipping",
230
+ description: "transaction",
231
+ device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
232
+ token_id: "",
233
+ order_id: ("id" in orderResult) && orderResult.id,
234
+ business_id: business.pk,
235
+ payment_id: ("pk" in paymentResult) && paymentResult.pk,
236
+ source: 'sdk',
237
+ metadata: metadata,
238
+ browser_info: getBrowserInfo(),
239
+ currency: currency
240
+ };
241
+
242
+ const checkoutResult = await this.startCheckoutRouter(routerItems);
243
+
244
+ return checkoutResult;
245
+
246
+ } else {
247
+
248
+ throw new ErrorResponse({
249
+ code: "500",
250
+ body: orderResult as any,
251
+ name: "Keys error",
252
+ message: "Order response errors"
253
+ } as IErrorResponse)
254
+
255
+ }
256
+
257
+ } else {
258
+
259
+ throw new ErrorResponse({
260
+ code: "500",
261
+ body: merchantResult as any,
262
+ name: "Keys error",
263
+ message: "Merchant or customer reposne errors"
264
+ } as IErrorResponse)
265
+
266
+ }
267
+ } catch (e) {
268
+
269
+ throw this.buildErrorResponseFromCatch(e);
270
+
271
+ }
272
+ }
273
+
152
274
  async getSkyflowTokens({
153
275
  vault_id,
154
276
  vault_url,
@@ -1,37 +1,12 @@
1
- export const createObserver = ({ target }: { target: string }): Promise<any> => {
2
-
3
- return new Promise((resolve, reject) => {
4
-
5
- let hasChanged = false;
6
-
7
- // Select the node that will be observed for mutations
8
- const targetNode: any = document.querySelector(target);
9
-
10
- // Options for the observer (which mutations to observe)
11
- const config = { attributes: true, childList: true, subtree: true };
12
-
13
- // Callback function to execute when mutations are observed
14
- const callback = (mutationList: any, observer: MutationObserver) => {
15
- for (const mutation of mutationList) {
16
- if (mutation.type === "childList") {
17
- hasChanged = true;
18
- resolve(mutation)
19
- }
20
- }
21
- };
22
-
23
- // Create an observer instance linked to the callback function
24
- const observer = new MutationObserver(callback);
25
-
26
- // Start observing the target node for configured mutations
27
- observer.observe(targetNode, config);
28
-
29
- window.setTimeout(() => {
30
- if (!hasChanged) {
31
- reject("Mounting error");
32
- }
33
- }, 5000);
34
-
35
- })
36
-
37
- }
1
+ export const getBrowserInfo = () => {
2
+ const browserInfo = {
3
+ javascript_enabled: true, // Assumed since JavaScript is running
4
+ time_zone: new Date().getTimezoneOffset(),
5
+ language: navigator.language || 'en-US', // Fallback to 'en-US'
6
+ color_depth: window.screen ? window.screen.colorDepth : null,
7
+ screen_width: window.screen ? window.screen.width * window.devicePixelRatio || window.screen.width : null,
8
+ screen_height: window.screen ? window.screen.height * window.devicePixelRatio || window.screen.height : null,
9
+ user_agent: navigator.userAgent,
10
+ };
11
+ return browserInfo;
12
+ }
@@ -62,4 +62,29 @@ export type TokensRequest = {
62
62
  data: {
63
63
  [key: string]: any;
64
64
  }
65
+ }
66
+
67
+ export type StartCheckoutFullRequest = {
68
+ order: {
69
+ items: OrderItem[];
70
+ };
71
+ total: number;
72
+ customer: {
73
+ name: string;
74
+ lastname: string;
75
+ email: string;
76
+ phone: string;
77
+ };
78
+ skyflowTokens: {
79
+ cardholder_name: string;
80
+ card_number: string;
81
+ cvv: string;
82
+ expiration_year: string;
83
+ expiration_month: string;
84
+ skyflow_id: string;
85
+ };
86
+ return_url: string;
87
+ isSandbox: boolean;
88
+ metadata: any;
89
+ currency: string;
65
90
  }
@@ -0,0 +1,139 @@
1
+ import "../utils/defaultMock";
2
+ import { LiteCheckout } from "../../src";
3
+ import { ErrorResponse } from "../../src/classes/errorResponse";
4
+ import { LiteCheckoutConstructor } from "../../src/classes/liteCheckout";
5
+ import { IErrorResponse } from "../../src/types/responses";
6
+ import { constructorFields } from "../utils/defaultMock";
7
+ import { StartCheckoutResponseClass, StartCheckoutFullRequestClass, BusinessClass, CustomerRegisterClass, OrderResponseClass, CreatePaymentResponseClass } from "../utils/mockClasses";
8
+
9
+ declare global {
10
+ interface Window {
11
+ OpenPay: any;
12
+ Skyflow: any;
13
+ }
14
+ }
15
+
16
+ describe("startCheckoutRouterFull", () => {
17
+ let checkoutConstructor: LiteCheckoutConstructor,
18
+ liteCheckout: LiteCheckout,
19
+ fetchSpy: jest.SpyInstance,
20
+ liteCheckoutSpy: jest.SpyInstance;
21
+
22
+ beforeEach(async () => {
23
+ window.fetch = jest.fn();
24
+
25
+ checkoutConstructor = {
26
+ ...constructorFields,
27
+ };
28
+
29
+ liteCheckout = new LiteCheckout(constructorFields);
30
+
31
+ fetchSpy = jest.spyOn(global, "fetch");
32
+ });
33
+
34
+ afterEach(() => {
35
+ jest.restoreAllMocks();
36
+ });
37
+
38
+ it("startCheckoutRouterFull success", async () => {
39
+
40
+ liteCheckout.getBusiness = jest
41
+ .fn()
42
+ .mockImplementation(() => Promise.resolve({ ...new BusinessClass().mockObject }));
43
+
44
+ liteCheckout.customerRegister = jest
45
+ .fn()
46
+ .mockImplementation(() => Promise.resolve({ ...new CustomerRegisterClass().mockObject }));
47
+
48
+ liteCheckout.createOrder = jest
49
+ .fn()
50
+ .mockImplementation(() => Promise.resolve({ ...new OrderResponseClass().mockObject }));
51
+
52
+ liteCheckout.createPayment = jest
53
+ .fn()
54
+ .mockImplementation(() => Promise.resolve({ ...new CreatePaymentResponseClass().mockObject }));
55
+
56
+ liteCheckoutSpy = jest.spyOn(liteCheckout, "startCheckoutRouterFull");
57
+
58
+ fetchSpy.mockImplementation(() =>
59
+ Promise.resolve({
60
+ json: () => Promise.resolve([{ ...new StartCheckoutResponseClass() }]),
61
+ ok: true,
62
+ })
63
+ );
64
+
65
+ const response = await liteCheckout.startCheckoutRouterFull({ ...new StartCheckoutFullRequestClass().mockObject, });
66
+
67
+ expect(response).toStrictEqual([{ ...new StartCheckoutResponseClass() }]);
68
+ expect(liteCheckoutSpy).toHaveBeenCalled();
69
+ });
70
+
71
+ it("startCheckoutRouterFull empty", async () => {
72
+ liteCheckoutSpy = jest.spyOn(liteCheckout, "startCheckoutRouterFull");
73
+
74
+ fetchSpy.mockImplementation(() =>
75
+ Promise.resolve({
76
+ json: () => Promise.resolve(),
77
+ ok: true,
78
+ })
79
+ );
80
+
81
+ let error: ErrorResponse;
82
+
83
+ try {
84
+ const response = (await liteCheckout.startCheckoutRouterFull({
85
+ ...new StartCheckoutFullRequestClass().mockObject,
86
+ })) as IErrorResponse;
87
+ } catch (e: any) {
88
+ error = e;
89
+ expect(error.code).toStrictEqual("500");
90
+ expect(error).toBeInstanceOf(ErrorResponse);
91
+ }
92
+
93
+ });
94
+
95
+ it("startCheckoutRouterFull errorResponse", async () => {
96
+ liteCheckoutSpy = jest.spyOn(liteCheckout, "startCheckoutRouterFull");
97
+
98
+ fetchSpy.mockImplementation(() =>
99
+ Promise.resolve({
100
+ json: () => Promise.resolve(),
101
+ ok: false,
102
+ status: 400,
103
+ })
104
+ );
105
+
106
+ let error: ErrorResponse;
107
+
108
+ try {
109
+ const response = (await liteCheckout.startCheckoutRouterFull({
110
+ ...new StartCheckoutFullRequestClass(),
111
+ })) as IErrorResponse;
112
+ } catch (e: any) {
113
+ error = e;
114
+ expect(error.code).toStrictEqual("400");
115
+ expect(error).toBeInstanceOf(ErrorResponse);
116
+ }
117
+ });
118
+
119
+ it("startCheckoutRouterFull errorCatch", async () => {
120
+ liteCheckoutSpy = jest.spyOn(liteCheckout, "startCheckoutRouterFull");
121
+
122
+ fetchSpy.mockRejectedValue("error");
123
+
124
+ let error: ErrorResponse;
125
+
126
+ try {
127
+ const response = (await liteCheckout.startCheckoutRouterFull({
128
+ ...new StartCheckoutFullRequestClass(),
129
+ })) as IErrorResponse;
130
+ } catch (e: any) {
131
+ error = e;
132
+ expect(error.message).toStrictEqual("error");
133
+ expect(error.name).toStrictEqual("catch");
134
+ }
135
+
136
+ expect(liteCheckoutSpy).toHaveBeenCalled();
137
+ expect(liteCheckoutSpy).rejects.toThrow();
138
+ });
139
+ });
@@ -4,7 +4,8 @@ import {
4
4
  CreatePaymentRequest,
5
5
  RegisterCustomerCardRequest,
6
6
  StartCheckoutRequest,
7
- TokensRequest
7
+ TokensRequest,
8
+ StartCheckoutFullRequest
8
9
  } from "../../src/types/requests";
9
10
  import {
10
11
  CreateOrderResponse,
@@ -499,6 +500,55 @@ export class StartCheckoutResponseClass implements StartCheckoutResponse {
499
500
  }
500
501
  }
501
502
 
503
+ export class StartCheckoutFullRequestClass implements StartCheckoutFullRequest {
504
+ order!: { items: OrderItem[]; };
505
+ return_url!: string;
506
+ total!: number;
507
+ skyflowTokens!: { cardholder_name: string; card_number: string; cvv: string; expiration_year: string; expiration_month: string; skyflow_id: string; };
508
+ customer!: { name: string; lastname: string; email: string; phone: string; };
509
+ isSandbox!: boolean;
510
+ currency!: string;
511
+ metadata!: any;
512
+
513
+ get mockObject(): StartCheckoutFullRequest {
514
+ return {
515
+ order: {
516
+ items: [
517
+ {
518
+ description: "string",
519
+ quantity: 25,
520
+ price_unit: 25,
521
+ discount: 0,
522
+ taxes: 0,
523
+ product_reference: 25,
524
+ name: "Product text",
525
+ amount_total: 25
526
+ }
527
+ ]
528
+ },
529
+ return_url: "string",
530
+ total: 25,
531
+ skyflowTokens: {
532
+ cardholder_name: "string",
533
+ card_number: "string",
534
+ cvv: "string",
535
+ expiration_year: "string",
536
+ expiration_month: "string",
537
+ skyflow_id: "string",
538
+ },
539
+ customer: {
540
+ name: "string",
541
+ lastname: "string",
542
+ email: "string",
543
+ phone: "string",
544
+ },
545
+ isSandbox: true,
546
+ currency: "MXN",
547
+ metadata: null
548
+ };
549
+ }
550
+ }
551
+
502
552
  export class TokensRequestClass implements TokensRequest {
503
553
  vault_id!: string;
504
554
  vault_url!: string;