@tonder.io/ionic-lite-sdk 0.0.32-beta → 0.0.34-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.
Files changed (40) hide show
  1. package/.gitlab-ci.yml +28 -28
  2. package/README.md +202 -193
  3. package/dist/classes/3dsHandler.d.ts +33 -0
  4. package/dist/classes/liteCheckout.d.ts +16 -6
  5. package/dist/data/api.d.ts +1 -0
  6. package/dist/helpers/constants.d.ts +62 -0
  7. package/dist/helpers/utils.d.ts +8 -0
  8. package/dist/index.js +1 -1
  9. package/dist/types/commons.d.ts +16 -0
  10. package/dist/types/requests.d.ts +14 -2
  11. package/dist/types/responses.d.ts +1 -0
  12. package/jest.config.ts +14 -14
  13. package/package.json +38 -38
  14. package/rollup.config.js +16 -16
  15. package/src/classes/3dsHandler.ts +241 -0
  16. package/src/classes/errorResponse.ts +16 -16
  17. package/src/classes/liteCheckout.ts +521 -462
  18. package/src/data/api.ts +21 -0
  19. package/src/helpers/constants.ts +64 -0
  20. package/src/helpers/utils.ts +315 -12
  21. package/src/index.ts +4 -4
  22. package/src/types/commons.ts +80 -62
  23. package/src/types/requests.ts +105 -89
  24. package/src/types/responses.ts +188 -187
  25. package/src/types/skyflow.ts +17 -17
  26. package/tests/classes/liteCheckout.test.ts +57 -57
  27. package/tests/methods/createOrder.test.ts +142 -142
  28. package/tests/methods/createPayment.test.ts +122 -122
  29. package/tests/methods/customerRegister.test.ts +119 -119
  30. package/tests/methods/getBusiness.test.ts +115 -115
  31. package/tests/methods/getCustomerCards.test.ts +117 -117
  32. package/tests/methods/getOpenpayDeviceSessionID.test.ts +94 -94
  33. package/tests/methods/getSkyflowToken.test.ts +154 -154
  34. package/tests/methods/getVaultToken.test.ts +106 -106
  35. package/tests/methods/registerCustomerCard.test.ts +117 -117
  36. package/tests/methods/startCheckoutRouter.test.ts +119 -119
  37. package/tests/methods/startCheckoutRouterFull.test.ts +138 -138
  38. package/tests/utils/defaultMock.ts +20 -20
  39. package/tests/utils/mockClasses.ts +652 -649
  40. package/tsconfig.json +18 -18
package/dist/index.js CHANGED
@@ -1 +1 @@
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:o.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};
1
+ import e from"skyflow-js";function t(e,t,n,o){return new(n||(n=Promise))((function(r,i){function s(e){try{d(o.next(e))}catch(e){i(e)}}function a(e){try{d(o.throw(e))}catch(e){i(e)}}function d(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,a)}d((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class n{constructor({code:e,body:t,name:n,message:o,stack:r}){this.code=e,this.body=t,this.name=n,this.message=o,this.stack=r}}var o;!function(e){e.SORIANA="SORIANA",e.OXXO="OXXO",e.SPEI="SPEI",e.CODI="CODI",e.MERCADOPAGO="MERCADOPAGO",e.PAYPAL="PAYPAL",e.COMERCIALMEXICANA="COMERCIALMEXICANA",e.BANCOMER="BANCOMER",e.WALMART="WALMART",e.BODEGA="BODEGA",e.SAMSCLUB="SAMSCLUB",e.SUPERAMA="SUPERAMA",e.CALIMAX="CALIMAX",e.EXTRA="EXTRA",e.CIRCULOK="CIRCULOK",e.SEVEN11="7ELEVEN",e.TELECOMM="TELECOMM",e.BANORTE="BANORTE",e.BENAVIDES="BENAVIDES",e.DELAHORRO="DELAHORRO",e.ELASTURIANO="ELASTURIANO",e.WALDOS="WALDOS",e.ALSUPER="ALSUPER",e.KIOSKO="KIOSKO",e.STAMARIA="STAMARIA",e.LAMASBARATA="LAMASBARATA",e.FARMROMA="FARMROMA",e.FARMUNION="FARMUNION",e.FARMATODO="FARMATODO",e.SFDEASIS="SFDEASIS",e.FARM911="FARM911",e.FARMECONOMICAS="FARMECONOMICAS",e.FARMMEDICITY="FARMMEDICITY",e.RIANXEIRA="RIANXEIRA",e.WESTERNUNION="WESTERNUNION",e.ZONAPAGO="ZONAPAGO",e.CAJALOSANDES="CAJALOSANDES",e.CAJAPAITA="CAJAPAITA",e.CAJASANTA="CAJASANTA",e.CAJASULLANA="CAJASULLANA",e.CAJATRUJILLO="CAJATRUJILLO",e.EDPYME="EDPYME",e.KASNET="KASNET",e.NORANDINO="NORANDINO",e.QAPAQ="QAPAQ",e.RAIZ="RAIZ",e.PAYSER="PAYSER",e.WUNION="WUNION",e.BANCOCONTINENTAL="BANCOCONTINENTAL",e.GMONEY="GMONEY",e.GOPAY="GOPAY",e.WU="WU",e.PUNTOSHEY="PUNTOSHEY",e.AMPM="AMPM",e.JUMBOMARKET="JUMBOMARKET",e.SMELPUEBLO="SMELPUEBLO",e.BAM="BAM",e.REFACIL="REFACIL",e.ACYVALORES="ACYVALORES"}(o||(o={}));const r=e=>new n({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}),i=(e,o=void 0)=>t(void 0,void 0,void 0,(function*(){let t,r,i="Error";e&&"json"in e&&(t=yield null==e?void 0:e.json()),e&&"status"in e&&(r=e.status.toString()),e&&"text"in e&&(i=yield e.text());return new n({code:r,body:t,name:r,message:i,stack:o})})),s=e=>e.trim().replace(/\s+/g,"");class a{constructor({payload:e=null,apiKey:t,baseUrl:n,successUrl:o}){this.localStorageKey="verify_transaction_status_url",this.setPayload=e=>{this.payload=e},this.baseUrl=n,this.apiKey=t,this.payload=e,this.successUrl=o}setStorageItem(e){return localStorage.setItem(this.localStorageKey,JSON.stringify(e))}getStorageItem(){return localStorage.getItem(this.localStorageKey)}removeStorageItem(){return localStorage.removeItem(this.localStorageKey)}saveVerifyTransactionUrl(){var e,t,n,o,r,i;const s=null===(n=null===(t=null===(e=this.payload)||void 0===e?void 0:e.next_action)||void 0===t?void 0:t.redirect_to_url)||void 0===n?void 0:n.verify_transaction_status_url;if(s)this.saveUrlWithExpiration(s);else{const e=null===(i=null===(r=null===(o=this.payload)||void 0===o?void 0:o.next_action)||void 0===r?void 0:r.iframe_resources)||void 0===i?void 0:i.verify_transaction_status_url;e?this.saveUrlWithExpiration(e):console.log("No verify_transaction_status_url found")}}saveUrlWithExpiration(e){try{const t={url:e,expires:(new Date).getTime()+12e5};this.setStorageItem(t)}catch(e){console.log("error: ",e)}}getUrlWithExpiration(){const e=this.getStorageItem();if(e){const t=JSON.parse(e);if(!t)return;return(new Date).getTime()>t.expires?(this.removeVerifyTransactionUrl(),null):t.url}return null}removeVerifyTransactionUrl(){return this.removeStorageItem()}getVerifyTransactionUrl(){return this.getStorageItem()}loadIframe(){var e,t,n;if(null===(n=null===(t=null===(e=this.payload)||void 0===e?void 0:e.next_action)||void 0===t?void 0:t.iframe_resources)||void 0===n?void 0:n.iframe)return new Promise(((e,t)=>{var n,o,r;const i=null===(r=null===(o=null===(n=this.payload)||void 0===n?void 0:n.next_action)||void 0===o?void 0:o.iframe_resources)||void 0===r?void 0:r.iframe;if(i){this.saveVerifyTransactionUrl();const n=document.createElement("div");n.innerHTML=i,document.body.appendChild(n);const o=document.createElement("script");o.textContent='document.getElementById("tdsMmethodForm").submit();',n.appendChild(o);const r=document.getElementById("tdsMmethodTgtFrame");r?r.onload=()=>e(!0):(console.log("No redirection found"),t(!1))}else console.log("No redirection found"),t(!1)}))}getRedirectUrl(){var e,t,n;return null===(n=null===(t=null===(e=this.payload)||void 0===e?void 0:e.next_action)||void 0===t?void 0:t.redirect_to_url)||void 0===n?void 0:n.url}redirectToChallenge(){const e=this.getRedirectUrl();e?(this.saveVerifyTransactionUrl(),window.location=e):console.log("No redirection found")}getURLParameters(){const e={},t=new URLSearchParams(window.location.search);for(const[n,o]of t)e[n]=o;return e}handleSuccessTransaction(e){return this.removeVerifyTransactionUrl(),console.log("Transacción autorizada."),e}handleDeclinedTransaction(e){return this.removeVerifyTransactionUrl(),e}handle3dsChallenge(e){return t(this,void 0,void 0,(function*(){const t=document.createElement("form");t.name="frm",t.method="POST",t.action=e.redirect_post_url;const n=document.createElement("input");n.type="hidden",n.name=e.creq,n.value=e.creq,t.appendChild(n);const o=document.createElement("input");o.type="hidden",o.name=e.term_url,o.value=e.TermUrl,t.appendChild(o),document.body.appendChild(t),t.submit(),yield this.verifyTransactionStatus()}))}handleTransactionResponse(e){return t(this,void 0,void 0,(function*(){const t=yield e.json();return"Pending"===t.status&&t.redirect_post_url?yield this.handle3dsChallenge(t):["Success","Authorized"].includes(t.status)?this.handleSuccessTransaction(t):(this.handleDeclinedTransaction(e),t)}))}verifyTransactionStatus(){return t(this,void 0,void 0,(function*(){const e=this.getUrlWithExpiration();if(e){const t=`${this.baseUrl}${e}`;try{const e=yield fetch(t,{method:"GET",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKey}`}});return 200!==e.status?(console.error("La verificación de la transacción falló."),this.removeVerifyTransactionUrl(),e):yield this.handleTransactionResponse(e)}catch(e){console.error("Error al verificar la transacción:",e),this.removeVerifyTransactionUrl()}}else console.log("No verify_transaction_status_url found")}))}}class d{constructor({signal:e,baseUrlTonder:t,apiKeyTonder:n,successUrl:o}){this.activeAPMs=[],this.baseUrlTonder=t,this.signal=e,this.apiKeyTonder=n,this.successUrl=o,this.process3ds=new a({apiKey:this.apiKeyTonder,baseUrl:this.baseUrlTonder,successUrl:o}),this.getActiveAPMs()}getOpenpayDeviceSessionID(e,n,o){return t(this,void 0,void 0,(function*(){try{let t=yield window.OpenPay;return t.setId(e),t.setApiKey(n),t.setSandboxMode(o),yield t.deviceData.setup({signal:this.signal})}catch(e){throw r(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 i(e)}catch(e){throw r(e)}}))}verify3dsTransaction(){return t(this,void 0,void 0,(function*(){const e=yield this.process3ds.verifyTransactionStatus(),t=yield this.resumeCheckout(e);return this.process3ds.setPayload(t),t&&"is_route_finished"in t&&"provider"in t&&"tonder"===t.provider?t:this.handle3dsRedirect(t)}))}resumeCheckout(e){var n;return t(this,void 0,void 0,(function*(){if(["Failed","Declined","Cancelled"].includes(null==e?void 0:e.status)){const t={checkout_id:null===(n=e.checkout)||void 0===n?void 0:n.id};return yield this.handleCheckoutRouter(t)}return e}))}handle3dsRedirect(e){var n,o;return t(this,void 0,void 0,(function*(){if(e&&"next_action"in e?null===(o=null===(n=null==e?void 0:e.next_action)||void 0===n?void 0:n.iframe_resources)||void 0===o?void 0:o.iframe:null)this.process3ds.loadIframe().then((()=>{this.process3ds.verifyTransactionStatus()})).catch((e=>{console.log("Error loading iframe:",e)}));else{if(!this.process3ds.getRedirectUrl())return e;this.process3ds.redirectToChallenge()}}))}customerRegister(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/customer/`,n={email:e},o=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},signal:this.signal,body:JSON.stringify(n)});if(o.ok)return yield o.json();throw yield i(o)}catch(e){throw r(e)}}))}createOrder(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/orders/`,n=e,o=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(n)});if(o.ok)return yield o.json();throw yield i(o)}catch(e){throw r(e)}}))}createPayment(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/business/${e.business_pk}/payments/`,n=e,o=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(n)});if(o.ok)return yield o.json();throw yield i(o)}catch(e){throw r(e)}}))}handleCheckoutRouter(e){return t(this,void 0,void 0,(function*(){try{const t=`${this.baseUrlTonder}/api/v1/checkout-router/`,n=e,o=yield fetch(t,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Token ${this.apiKeyTonder}`},body:JSON.stringify(n)});if(o.ok)return yield o.json();throw yield i(o)}catch(e){throw r(e)}}))}startCheckoutRouter(e){return t(this,void 0,void 0,(function*(){const t=yield this.handleCheckoutRouter(e);if(yield this.init3DSRedirect(t))return t}))}startCheckoutRouterFull(e){return t(this,void 0,void 0,(function*(){try{const{order:t,total:o,customer:r,skyflowTokens:i,return_url:s,isSandbox:a,metadata:d,currency:l,payment_method:c}=e,u=yield this.getBusiness(),p=yield this.customerRegister(r.email);if(!(p&&"auth_token"in p&&u&&"reference"in u))throw new n({code:"500",body:u,name:"Keys error",message:"Merchant or customer reposne errors"});{const e={business:this.apiKeyTonder,client:p.auth_token,billing_address_id:null,shipping_address_id:null,amount:o,reference:u.reference,is_oneclick:!0,items:t.items},h=yield this.createOrder(e),y=(new Date).toISOString();if(!("id"in h&&"id"in p&&"business"in u))throw new n({code:"500",body:h,name:"Keys error",message:"Order response errors"});{const e={business_pk:u.business.pk,amount:o,date:y,order_id:h.id,client_id:p.id},t=yield this.createPayment(e);let n;const{openpay_keys:m,business:A}=u;m.merchant_id&&m.public_key&&(n=yield this.getOpenpayDeviceSessionID(m.merchant_id,m.public_key,a));const g=Object.assign({name:r.name,last_name:r.lastname,email_client:r.email,phone_number:r.phone,return_url:s,id_product:"no_id",quantity_product:1,id_ship:"0",instance_id_ship:"0",amount:o,title_ship:"shipping",description:"transaction",device_session_id:n||null,token_id:"",order_id:"id"in h&&h.id,business_id:A.pk,payment_id:"pk"in t&&t.pk,source:"sdk",metadata:d,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},c?{payment_method:c}:{card:i}),f=yield this.handleCheckoutRouter(g);if(yield this.init3DSRedirect(f))return f}}}catch(e){throw r(e)}}))}init3DSRedirect(e){return t(this,void 0,void 0,(function*(){return this.process3ds.setPayload(e),yield this.handle3dsRedirect(e)}))}getSkyflowTokens({vault_id:n,vault_url:o,data:i}){return t(this,void 0,void 0,(function*(){const s=e.init({vaultID:n,vaultURL:o,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),a=yield this.getFieldsPromise(i,s);if((yield Promise.all(a)).some((e=>!e)))throw r(Error("Ocurrió un error al montar los campos de la tarjeta"));try{const e=yield s.collect();if(e)return e.records[0].fields;throw r(Error("Por favor, verifica todos los campos de tu tarjeta"))}catch(e){throw r(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,n){return t(this,void 0,void 0,(function*(){const t=yield this.getFields(e,n);return t?t.map((t=>new Promise((n=>{var o;const r=document.createElement("div");r.hidden=!0,r.id=`id-${t.key}`,null===(o=document.querySelector("body"))||void 0===o||o.appendChild(r),setTimeout((()=>{t.element.mount(`#id-${t.key}`),setInterval((()=>{if(t.element.isMounted()){const o=e[t.key];return t.element.update({value:o}),n(t.element.isMounted())}}),120)}),120)})))):[]}))}registerCustomerCard(e,n){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(n)});if(t.ok)return yield t.json();throw yield i(t)}catch(e){throw r(e)}}))}getCustomerCards(e,n=""){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/${n}`,{method:"GET",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal});if(t.ok)return yield t.json();throw yield i(t)}catch(e){throw r(e)}}))}deleteCustomerCard(e,n=""){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${this.baseUrlTonder}/api/v1/cards/${n}`,{method:"DELETE",headers:{Authorization:`Token ${e}`,"Content-Type":"application/json"},signal:this.signal});if(t.ok)return!0;throw yield i(t)}catch(e){throw r(e)}}))}getFields(n,o){return t(this,void 0,void 0,(function*(){return yield Promise.all(Object.keys(n).map((n=>t(this,void 0,void 0,(function*(){return{element:yield o.create({table:"cards",column:n,type:e.ElementType.INPUT_FIELD}),key:n}})))))}))}getActiveAPMs(){return t(this,void 0,void 0,(function*(){try{const e=yield function(e,n,o="?status=active&page_size=10000&country=México",s=null){return t(this,void 0,void 0,(function*(){try{const t=yield fetch(`${e}/api/v1/payment_methods${o}`,{method:"GET",headers:{Authorization:`Token ${n}`,"Content-Type":"application/json"},signal:s});if(t.ok)return yield t.json();throw yield i(t)}catch(e){throw r(e)}}))}(this.baseUrlTonder,this.apiKeyTonder),n=e&&e.results&&e.results.length>0?e.results:[];return this.activeAPMs=n.filter((e=>"cards"!==e.category.toLowerCase())).map((e=>Object.assign({id:e.pk,payment_method:e.payment_method,priority:e.priority,category:e.category},(e=>{const t=s(e.toUpperCase());return{[o.SORIANA]:{label:"Soriana",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/soriana.png"},[o.OXXO]:{label:"Oxxo",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/oxxo.png"},[o.CODI]:{label:"CoDi",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/codi.png"},[o.SPEI]:{label:"SPEI",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/spei.png"},[o.PAYPAL]:{label:"Paypal",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/paypal.png"},[o.COMERCIALMEXICANA]:{label:"Comercial Mexicana",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/comercial_exicana.png"},[o.BANCOMER]:{label:"Bancomer",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/bancomer.png"},[o.WALMART]:{label:"Walmart",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/walmart.png"},[o.BODEGA]:{label:"Bodega Aurrera",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/bodega_aurrera.png"},[o.SAMSCLUB]:{label:"Sam´s Club",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/sams_club.png"},[o.SUPERAMA]:{label:"Superama",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/superama.png"},[o.CALIMAX]:{label:"Calimax",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/calimax.png"},[o.EXTRA]:{label:"Tiendas Extra",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/tiendas_extra.png"},[o.CIRCULOK]:{label:"Círculo K",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/circulo_k.png"},[o.SEVEN11]:{label:"7 Eleven",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/7_eleven.png"},[o.TELECOMM]:{label:"Telecomm",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/telecomm.png"},[o.BANORTE]:{label:"Banorte",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/banorte.png"},[o.BENAVIDES]:{label:"Farmacias Benavides",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_benavides.png"},[o.DELAHORRO]:{label:"Farmacias del Ahorro",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_ahorro.png"},[o.ELASTURIANO]:{label:"El Asturiano",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/asturiano.png"},[o.WALDOS]:{label:"Waldos",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/waldos.png"},[o.ALSUPER]:{label:"Alsuper",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/al_super.png"},[o.KIOSKO]:{label:"Kiosko",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/kiosko.png"},[o.STAMARIA]:{label:"Farmacias Santa María",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_santa_maria.png"},[o.LAMASBARATA]:{label:"Farmacias la más barata",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_barata.png"},[o.FARMROMA]:{label:"Farmacias Roma",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_roma.png"},[o.FARMUNION]:{label:"Pago en Farmacias Unión",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_union.png"},[o.FARMATODO]:{label:"Pago en Farmacias Farmatodo",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_farmatodo.png\t"},[o.SFDEASIS]:{label:"Pago en Farmacias San Francisco de Asís",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/farmacias_san_francisco.png"},[o.FARM911]:{label:"Farmacias 911",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.FARMECONOMICAS]:{label:"Farmacias Economicas",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.FARMMEDICITY]:{label:"Farmacias Medicity",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.RIANXEIRA]:{label:"Rianxeira",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.WESTERNUNION]:{label:"Western Union",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.ZONAPAGO]:{label:"Zona Pago",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.CAJALOSANDES]:{label:"Caja Los Andes",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.CAJAPAITA]:{label:"Caja Paita",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.CAJASANTA]:{label:"Caja Santa",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.CAJASULLANA]:{label:"Caja Sullana",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.CAJATRUJILLO]:{label:"Caja Trujillo",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.EDPYME]:{label:"Edpyme",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.KASNET]:{label:"KasNet",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.NORANDINO]:{label:"Norandino",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.QAPAQ]:{label:"Qapaq",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.RAIZ]:{label:"Raiz",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.PAYSER]:{label:"Paysera",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.WUNION]:{label:"Western Union",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.BANCOCONTINENTAL]:{label:"Banco Continental",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.GMONEY]:{label:"Go money",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.GOPAY]:{label:"Go pay",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.WU]:{label:"Western Union",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.PUNTOSHEY]:{label:"Puntoshey",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.AMPM]:{label:"Ampm",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.JUMBOMARKET]:{label:"Jumbomarket",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.SMELPUEBLO]:{label:"Smelpueblo",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.BAM]:{label:"Bam",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.REFACIL]:{label:"Refacil",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"},[o.ACYVALORES]:{label:"Acyvalores",icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png"}}[t]||{icon:"https://d35a75syrgujp0.cloudfront.net/payment_methods/store.png",label:""}})(e.payment_method)))).sort(((e,t)=>e.priority-t.priority)),this.activeAPMs}catch(e){return console.error("Error getting APMS",e),[]}}))}}export{d as LiteCheckout};
@@ -57,3 +57,19 @@ export type PaymentData = {
57
57
  items: OrderItem[];
58
58
  };
59
59
  };
60
+ export type TonderAPM = {
61
+ pk: string;
62
+ payment_method: string;
63
+ priority: number;
64
+ category: string;
65
+ unavailable_countries: string[];
66
+ status: string;
67
+ };
68
+ export type APM = {
69
+ id: string;
70
+ payment_method: string;
71
+ priority: number;
72
+ category: string;
73
+ icon: string;
74
+ label: string;
75
+ };
@@ -18,8 +18,7 @@ export type CreatePaymentRequest = {
18
18
  order_id?: string | number;
19
19
  client_id?: string | number;
20
20
  };
21
- export type StartCheckoutRequest = {
22
- card: any;
21
+ export type StartCheckoutRequestBase = {
23
22
  name: any;
24
23
  last_name: string;
25
24
  email_client: any;
@@ -42,6 +41,18 @@ export type StartCheckoutRequest = {
42
41
  metadata: any;
43
42
  currency: string;
44
43
  };
44
+ export type StartCheckoutRequestWithCard = StartCheckoutRequestBase & {
45
+ card: any;
46
+ payment_method?: never;
47
+ };
48
+ export type StartCheckoutRequestWithPaymentMethod = StartCheckoutRequestBase & {
49
+ card?: never;
50
+ payment_method: string;
51
+ };
52
+ export type StartCheckoutRequest = StartCheckoutRequestWithCard | StartCheckoutRequestWithPaymentMethod;
53
+ export type StartCheckoutIdRequest = {
54
+ checkout_id: any;
55
+ };
45
56
  export interface VaultRequest extends SkyflowRecord {
46
57
  records: SkyflowRecord[];
47
58
  continueOnError?: boolean;
@@ -80,4 +91,5 @@ export type StartCheckoutFullRequest = {
80
91
  isSandbox: boolean;
81
92
  metadata: any;
82
93
  currency: string;
94
+ payment_method?: string;
83
95
  };
@@ -133,6 +133,7 @@ export type StartCheckoutResponse = {
133
133
  method: string;
134
134
  object: string;
135
135
  };
136
+ is_route_finished: Boolean;
136
137
  transaction_status: string;
137
138
  transaction_id: number;
138
139
  payment_id: number;
package/jest.config.ts CHANGED
@@ -1,15 +1,15 @@
1
- import type { JestConfigWithTsJest } from 'ts-jest'
2
-
3
- const jestConfig: JestConfigWithTsJest = {
4
- testEnvironment: "jsdom",
5
- preset: 'ts-jest',
6
- transform: {
7
- '^.+\\.tsx?$': [
8
- 'ts-jest',
9
- {
10
- },
11
- ],
12
- },
13
- }
14
-
1
+ import type { JestConfigWithTsJest } from 'ts-jest'
2
+
3
+ const jestConfig: JestConfigWithTsJest = {
4
+ testEnvironment: "jsdom",
5
+ preset: 'ts-jest',
6
+ transform: {
7
+ '^.+\\.tsx?$': [
8
+ 'ts-jest',
9
+ {
10
+ },
11
+ ],
12
+ },
13
+ }
14
+
15
15
  export default jestConfig
package/package.json CHANGED
@@ -1,38 +1,38 @@
1
- {
2
- "name": "@tonder.io/ionic-lite-sdk",
3
- "version": "0.0.32-beta",
4
- "description": "Tonder ionic lite SDK",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "tsc -noEmit && rollup --config",
9
- "test": "jest",
10
- "ts-coverage": "typescript-coverage-report"
11
- },
12
- "author": "",
13
- "license": "ISC",
14
- "dependencies": {
15
- "skyflow-js": "^1.34.1",
16
- "ts-node": "^10.9.2"
17
- },
18
- "publishConfig": {
19
- "access": "public",
20
- "registry": "https://registry.npmjs.org/"
21
- },
22
- "devDependencies": {
23
- "@rollup/plugin-terser": "^0.4.4",
24
- "@rollup/plugin-typescript": "11.1.6",
25
- "@types/crypto-js": "^4.2.2",
26
- "@types/jest": "^29.5.11",
27
- "@types/node": "^20.11.5",
28
- "jest": "^29.7.0",
29
- "jest-environment-jsdom": "^29.7.0",
30
- "jsdom": "^24.0.0",
31
- "rollup": "4.9.6",
32
- "ts-jest": "^29.1.2",
33
- "ts-loader": "^9.5.1",
34
- "tslib": "^2.6.2",
35
- "typescript": "^5.3.3",
36
- "typescript-coverage-report": "^0.8.0"
37
- }
38
- }
1
+ {
2
+ "name": "@tonder.io/ionic-lite-sdk",
3
+ "version": "0.0.34-beta",
4
+ "description": "Tonder ionic lite SDK",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc -noEmit && rollup --config",
9
+ "test": "jest",
10
+ "ts-coverage": "typescript-coverage-report"
11
+ },
12
+ "author": "",
13
+ "license": "ISC",
14
+ "dependencies": {
15
+ "skyflow-js": "^1.34.1",
16
+ "ts-node": "^10.9.2"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public",
20
+ "registry": "https://registry.npmjs.org/"
21
+ },
22
+ "devDependencies": {
23
+ "@rollup/plugin-terser": "^0.4.4",
24
+ "@rollup/plugin-typescript": "11.1.6",
25
+ "@types/crypto-js": "^4.2.2",
26
+ "@types/jest": "^29.5.11",
27
+ "@types/node": "^20.11.5",
28
+ "jest": "^29.7.0",
29
+ "jest-environment-jsdom": "^29.7.0",
30
+ "jsdom": "^24.0.0",
31
+ "rollup": "4.9.6",
32
+ "ts-jest": "^29.1.2",
33
+ "ts-loader": "^9.5.1",
34
+ "tslib": "^2.6.2",
35
+ "typescript": "^5.3.3",
36
+ "typescript-coverage-report": "^0.8.0"
37
+ }
38
+ }
package/rollup.config.js CHANGED
@@ -1,17 +1,17 @@
1
- const typescript = require('@rollup/plugin-typescript');
2
- const terser = require('@rollup/plugin-terser');
3
-
4
- module.exports = {
5
- input: './src/index.ts',
6
- output: {
7
- dir: 'dist',
8
- format: 'es',
9
- plugins: [terser()]
10
- },
11
- plugins: [
12
- typescript({
13
- exclude: ["tests/**", "jest.config.ts"]
14
- })
15
- ],
16
- external: ["skyflow-js", "crypto-js"]
1
+ const typescript = require('@rollup/plugin-typescript');
2
+ const terser = require('@rollup/plugin-terser');
3
+
4
+ module.exports = {
5
+ input: './src/index.ts',
6
+ output: {
7
+ dir: 'dist',
8
+ format: 'es',
9
+ plugins: [terser()]
10
+ },
11
+ plugins: [
12
+ typescript({
13
+ exclude: ["tests/**", "jest.config.ts"]
14
+ })
15
+ ],
16
+ external: ["skyflow-js", "crypto-js"]
17
17
  };
@@ -0,0 +1,241 @@
1
+ type ThreeDSHandlerContructor = {
2
+ payload?: any,
3
+ apiKey?: string,
4
+ baseUrl?: string,
5
+ successUrl?: Location | string
6
+ }
7
+
8
+ export class ThreeDSHandler {
9
+
10
+ baseUrl?: string
11
+ apiKey?: string
12
+ payload?: any
13
+ successUrl?: Location | string
14
+ localStorageKey: string = "verify_transaction_status_url"
15
+
16
+ constructor({
17
+ payload = null,
18
+ apiKey,
19
+ baseUrl,
20
+ successUrl
21
+ }: ThreeDSHandlerContructor) {
22
+ this.baseUrl = baseUrl,
23
+ this.apiKey = apiKey,
24
+ this.payload = payload,
25
+ this.successUrl = successUrl
26
+ }
27
+
28
+ setStorageItem (data: any) {
29
+ return localStorage.setItem(this.localStorageKey, JSON.stringify(data))
30
+ }
31
+
32
+ getStorageItem () {
33
+ return localStorage.getItem(this.localStorageKey)
34
+ }
35
+
36
+ removeStorageItem () {
37
+ return localStorage.removeItem(this.localStorageKey)
38
+ }
39
+
40
+ saveVerifyTransactionUrl() {
41
+ const url = this.payload?.next_action?.redirect_to_url?.verify_transaction_status_url
42
+ if (url) {
43
+ this.saveUrlWithExpiration(url)
44
+ } else {
45
+ const url = this.payload?.next_action?.iframe_resources?.verify_transaction_status_url
46
+ if (url) {
47
+ this.saveUrlWithExpiration(url)
48
+ } else {
49
+ console.log('No verify_transaction_status_url found');
50
+ }
51
+ }
52
+ }
53
+
54
+ saveUrlWithExpiration(url: string) {
55
+ try {
56
+ const now = new Date()
57
+ const item = {
58
+ url: url,
59
+ // Expires after 20 minutes
60
+ expires: now.getTime() + 20 * 60 * 1000
61
+ }
62
+ this.setStorageItem(item)
63
+ } catch (error) {
64
+ console.log('error: ', error)
65
+ }
66
+ }
67
+
68
+ getUrlWithExpiration() {
69
+ const status = this.getStorageItem();
70
+ if(status) {
71
+ const item = JSON.parse(status)
72
+ if (!item) return
73
+ const now = new Date()
74
+ if (now.getTime() > item.expires) {
75
+ this.removeVerifyTransactionUrl()
76
+ return null
77
+ } else {
78
+ return item.url
79
+ }
80
+ } else {
81
+ return null
82
+ }
83
+ }
84
+
85
+ removeVerifyTransactionUrl() {
86
+ return this.removeStorageItem()
87
+ }
88
+
89
+ getVerifyTransactionUrl() {
90
+ return this.getStorageItem()
91
+ }
92
+
93
+ loadIframe() {
94
+ const iframe = this.payload?.next_action?.iframe_resources?.iframe
95
+
96
+ if (iframe) {
97
+ return new Promise((resolve, reject) => {
98
+ const iframe = this.payload?.next_action?.iframe_resources?.iframe
99
+
100
+ if (iframe) {
101
+ this.saveVerifyTransactionUrl()
102
+ const container = document.createElement('div')
103
+ container.innerHTML = iframe
104
+ document.body.appendChild(container)
105
+
106
+ // Create and append the script tag manually
107
+ const script = document.createElement('script')
108
+ script.textContent = 'document.getElementById("tdsMmethodForm").submit();'
109
+ container.appendChild(script)
110
+
111
+ // Resolve the promise when the iframe is loaded
112
+ const iframeElement = document.getElementById('tdsMmethodTgtFrame')
113
+ if(iframeElement) {
114
+ iframeElement.onload = () => resolve(true)
115
+ } else {
116
+ console.log('No redirection found');
117
+ reject(false)
118
+ }
119
+ } else {
120
+ console.log('No redirection found');
121
+ reject(false)
122
+ }
123
+ })
124
+ }
125
+ }
126
+
127
+ getRedirectUrl() {
128
+ return this.payload?.next_action?.redirect_to_url?.url
129
+ }
130
+
131
+ redirectToChallenge() {
132
+ const url = this.getRedirectUrl()
133
+ if (url) {
134
+ this.saveVerifyTransactionUrl()
135
+ window.location = url;
136
+ } else {
137
+ console.log('No redirection found');
138
+ }
139
+ }
140
+
141
+ // Returns an object
142
+ // https://example.com/?name=John&age=30&city=NewYork
143
+ // { name: "John", age: "30", city: "NewYork" }
144
+ getURLParameters() {
145
+ const parameters: any = {};
146
+ const urlParams: any = new URLSearchParams(window.location.search);
147
+
148
+ for (const [key, value] of urlParams) {
149
+ parameters[key] = value;
150
+ }
151
+
152
+ return parameters;
153
+ }
154
+
155
+ handleSuccessTransaction(response: any) {
156
+ this.removeVerifyTransactionUrl();
157
+ console.log('Transacción autorizada.');
158
+ return response;
159
+ }
160
+
161
+ handleDeclinedTransaction(response: any) {
162
+ this.removeVerifyTransactionUrl();
163
+ return response;
164
+ }
165
+
166
+ // TODO: the method below needs to be tested with a real 3DS challenge
167
+ // since we couldn't get a test card that works with this feature
168
+ async handle3dsChallenge(response_json: any) {
169
+ // Create the form element:
170
+ const form = document.createElement('form');
171
+ form.name = 'frm';
172
+ form.method = 'POST';
173
+ form.action = response_json.redirect_post_url;
174
+
175
+ // Add hidden fields:
176
+ const creqInput = document.createElement('input');
177
+ creqInput.type = 'hidden';
178
+ creqInput.name = response_json.creq;
179
+ creqInput.value = response_json.creq;
180
+ form.appendChild(creqInput);
181
+
182
+ const termUrlInput = document.createElement('input');
183
+ termUrlInput.type = 'hidden';
184
+ termUrlInput.name = response_json.term_url;
185
+ termUrlInput.value = response_json.TermUrl;
186
+ form.appendChild(termUrlInput);
187
+
188
+ // Append the form to the body:
189
+ document.body.appendChild(form);
190
+ form.submit();
191
+
192
+ await this.verifyTransactionStatus();
193
+ }
194
+
195
+ // TODO: This method could be removed
196
+ async handleTransactionResponse(response: any) {
197
+ const response_json = await response.json();
198
+ if (response_json.status === "Pending" && response_json.redirect_post_url) {
199
+ return await this.handle3dsChallenge(response_json);
200
+ } else if (["Success", "Authorized"].includes(response_json.status)) {
201
+ return this.handleSuccessTransaction(response_json);
202
+ } else {
203
+ this.handleDeclinedTransaction(response);
204
+ return response_json
205
+ }
206
+ }
207
+
208
+ async verifyTransactionStatus() {
209
+ const verifyUrl = this.getUrlWithExpiration();
210
+ if (verifyUrl) {
211
+ const url = `${this.baseUrl}${verifyUrl}`;
212
+ try {
213
+ const response = await fetch(url, {
214
+ method: "GET",
215
+ headers: {
216
+ "Content-Type": "application/json",
217
+ Authorization: `Token ${this.apiKey}`,
218
+ },
219
+ // body: JSON.stringify(data),
220
+ });
221
+
222
+ if (response.status !== 200) {
223
+ console.error('La verificación de la transacción falló.');
224
+ this.removeVerifyTransactionUrl();
225
+ return response
226
+ }
227
+
228
+ return await this.handleTransactionResponse(response);
229
+ } catch (error) {
230
+ console.error('Error al verificar la transacción:', error);
231
+ this.removeVerifyTransactionUrl();
232
+ }
233
+ } else {
234
+ console.log('No verify_transaction_status_url found');
235
+ }
236
+ }
237
+
238
+ setPayload = (payload: any) => {
239
+ this.payload = payload
240
+ }
241
+ }
@@ -1,17 +1,17 @@
1
- import { IErrorResponse } from "../types/responses";
2
-
3
- export class ErrorResponse implements IErrorResponse {
4
- code?: string | undefined;
5
- body?: string | undefined;
6
- name!: string;
7
- message!: string;
8
- stack?: string | undefined;
9
-
10
- constructor({ code, body, name, message, stack }: IErrorResponse) {
11
- this.code = code;
12
- this.body = body;
13
- this.name = name;
14
- this.message = message;
15
- this.stack = stack;
16
- }
1
+ import { IErrorResponse } from "../types/responses";
2
+
3
+ export class ErrorResponse implements IErrorResponse {
4
+ code?: string | undefined;
5
+ body?: string | undefined;
6
+ name!: string;
7
+ message!: string;
8
+ stack?: string | undefined;
9
+
10
+ constructor({ code, body, name, message, stack }: IErrorResponse) {
11
+ this.code = code;
12
+ this.body = body;
13
+ this.name = name;
14
+ this.message = message;
15
+ this.stack = stack;
16
+ }
17
17
  }