@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.
- package/.gitlab-ci.yml +28 -28
- package/README.md +202 -193
- package/dist/classes/3dsHandler.d.ts +33 -0
- package/dist/classes/liteCheckout.d.ts +16 -6
- package/dist/data/api.d.ts +1 -0
- package/dist/helpers/constants.d.ts +62 -0
- package/dist/helpers/utils.d.ts +8 -0
- package/dist/index.js +1 -1
- package/dist/types/commons.d.ts +16 -0
- package/dist/types/requests.d.ts +14 -2
- package/dist/types/responses.d.ts +1 -0
- package/jest.config.ts +14 -14
- package/package.json +38 -38
- package/rollup.config.js +16 -16
- package/src/classes/3dsHandler.ts +241 -0
- package/src/classes/errorResponse.ts +16 -16
- package/src/classes/liteCheckout.ts +521 -462
- package/src/data/api.ts +21 -0
- package/src/helpers/constants.ts +64 -0
- package/src/helpers/utils.ts +315 -12
- package/src/index.ts +4 -4
- package/src/types/commons.ts +80 -62
- package/src/types/requests.ts +105 -89
- package/src/types/responses.ts +188 -187
- package/src/types/skyflow.ts +17 -17
- package/tests/classes/liteCheckout.test.ts +57 -57
- package/tests/methods/createOrder.test.ts +142 -142
- package/tests/methods/createPayment.test.ts +122 -122
- package/tests/methods/customerRegister.test.ts +119 -119
- package/tests/methods/getBusiness.test.ts +115 -115
- package/tests/methods/getCustomerCards.test.ts +117 -117
- package/tests/methods/getOpenpayDeviceSessionID.test.ts +94 -94
- package/tests/methods/getSkyflowToken.test.ts +154 -154
- package/tests/methods/getVaultToken.test.ts +106 -106
- package/tests/methods/registerCustomerCard.test.ts +117 -117
- package/tests/methods/startCheckoutRouter.test.ts +119 -119
- package/tests/methods/startCheckoutRouterFull.test.ts +138 -138
- package/tests/utils/defaultMock.ts +20 -20
- package/tests/utils/mockClasses.ts +652 -649
- 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};
|
package/dist/types/commons.d.ts
CHANGED
|
@@ -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
|
+
};
|
package/dist/types/requests.d.ts
CHANGED
|
@@ -18,8 +18,7 @@ export type CreatePaymentRequest = {
|
|
|
18
18
|
order_id?: string | number;
|
|
19
19
|
client_id?: string | number;
|
|
20
20
|
};
|
|
21
|
-
export type
|
|
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
|
};
|
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.
|
|
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
|
}
|