tonder-web-sdk 1.11.11 → 1.12.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/prettier.xml +6 -0
- package/.idea/workspace.xml +96 -11
- package/README.md +0 -3
- package/package.json +3 -1
- package/src/classes/3dsHandler.js +1 -4
- package/src/classes/BaseInlineCheckout.js +298 -0
- package/src/classes/LiteInlineCheckout.js +101 -0
- package/src/classes/inlineCheckout.js +64 -280
- package/src/data/apmApi.js +44 -0
- package/src/data/businessApi.js +19 -0
- package/src/data/cardApi.js +116 -0
- package/src/data/checkoutApi.js +81 -0
- package/src/data/customerApi.js +37 -0
- package/src/data/index.js +17 -0
- package/src/data/openPayApi.js +16 -0
- package/src/data/skyflowApi.js +18 -0
- package/src/helpers/skyflow.js +76 -15
- package/src/helpers/template.js +7 -1
- package/src/helpers/utils.js +81 -79
- package/src/index-dev.js +96 -14
- package/src/index.html +119 -8
- package/src/shared/constants/paymentMethodAPM.js +63 -0
- package/src/shared/constants/tonderUrl.js +8 -0
- package/types/index.d.ts +14 -0
- package/v1/bundle.min.js +3 -3
- package/src/data/api.js +0 -193
- package/src/helpers/constants.js +0 -64
package/.idea/workspace.xml
CHANGED
|
@@ -1,25 +1,56 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<project version="4">
|
|
3
|
+
<component name="AutoImportSettings">
|
|
4
|
+
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
|
+
</component>
|
|
3
6
|
<component name="ChangeListManager">
|
|
4
7
|
<list default="true" id="37fc62e5-7dd0-4a2e-b68c-304069cdf5bd" name="Changes" comment="">
|
|
8
|
+
<change afterPath="$PROJECT_DIR$/.idea/prettier.xml" afterDir="false" />
|
|
9
|
+
<change afterPath="$PROJECT_DIR$/src/classes/BaseInlineCheckout.js" afterDir="false" />
|
|
10
|
+
<change afterPath="$PROJECT_DIR$/src/classes/LiteInlineCheckout.js" afterDir="false" />
|
|
11
|
+
<change afterPath="$PROJECT_DIR$/src/data/apmApi.js" afterDir="false" />
|
|
12
|
+
<change afterPath="$PROJECT_DIR$/src/data/businessApi.js" afterDir="false" />
|
|
13
|
+
<change afterPath="$PROJECT_DIR$/src/data/cardApi.js" afterDir="false" />
|
|
14
|
+
<change afterPath="$PROJECT_DIR$/src/data/checkoutApi.js" afterDir="false" />
|
|
15
|
+
<change afterPath="$PROJECT_DIR$/src/data/customerApi.js" afterDir="false" />
|
|
16
|
+
<change afterPath="$PROJECT_DIR$/src/data/index.js" afterDir="false" />
|
|
17
|
+
<change afterPath="$PROJECT_DIR$/src/data/openPayApi.js" afterDir="false" />
|
|
18
|
+
<change afterPath="$PROJECT_DIR$/src/data/skyflowApi.js" afterDir="false" />
|
|
19
|
+
<change afterPath="$PROJECT_DIR$/src/shared/constants/paymentMethodAPM.js" afterDir="false" />
|
|
20
|
+
<change afterPath="$PROJECT_DIR$/src/shared/constants/tonderUrl.js" afterDir="false" />
|
|
21
|
+
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
|
5
22
|
<change beforePath="$PROJECT_DIR$/package-lock.json" beforeDir="false" afterPath="$PROJECT_DIR$/package-lock.json" afterDir="false" />
|
|
23
|
+
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
6
24
|
<change beforePath="$PROJECT_DIR$/src/classes/inlineCheckout.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/classes/inlineCheckout.js" afterDir="false" />
|
|
25
|
+
<change beforePath="$PROJECT_DIR$/src/data/api.js" beforeDir="false" />
|
|
26
|
+
<change beforePath="$PROJECT_DIR$/src/helpers/constants.js" beforeDir="false" />
|
|
27
|
+
<change beforePath="$PROJECT_DIR$/src/helpers/skyflow.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/helpers/skyflow.js" afterDir="false" />
|
|
28
|
+
<change beforePath="$PROJECT_DIR$/src/helpers/utils.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/helpers/utils.js" afterDir="false" />
|
|
29
|
+
<change beforePath="$PROJECT_DIR$/src/index-dev.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/index-dev.js" afterDir="false" />
|
|
30
|
+
<change beforePath="$PROJECT_DIR$/src/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.html" afterDir="false" />
|
|
7
31
|
</list>
|
|
8
32
|
<option name="SHOW_DIALOG" value="false" />
|
|
9
33
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
10
34
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
11
35
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
12
36
|
</component>
|
|
37
|
+
<component name="FileTemplateManagerImpl">
|
|
38
|
+
<option name="RECENT_TEMPLATES">
|
|
39
|
+
<list>
|
|
40
|
+
<option value="JavaScript File" />
|
|
41
|
+
</list>
|
|
42
|
+
</option>
|
|
43
|
+
</component>
|
|
13
44
|
<component name="Git.Settings">
|
|
14
45
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
15
46
|
</component>
|
|
16
47
|
<component name="MarkdownSettingsMigration">
|
|
17
48
|
<option name="stateVersion" value="1" />
|
|
18
49
|
</component>
|
|
19
|
-
<component name="ProjectColorInfo"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
50
|
+
<component name="ProjectColorInfo">{
|
|
51
|
+
"customColor": "",
|
|
52
|
+
"associatedIndex": 2
|
|
53
|
+
}</component>
|
|
23
54
|
<component name="ProjectId" id="2iy5RvaLleBBnn8yOfQNLpzKK66" />
|
|
24
55
|
<component name="ProjectViewState">
|
|
25
56
|
<option name="autoscrollFromSource" value="true" />
|
|
@@ -30,19 +61,41 @@
|
|
|
30
61
|
</component>
|
|
31
62
|
<component name="PropertiesComponent"><![CDATA[{
|
|
32
63
|
"keyToString": {
|
|
64
|
+
"Node.js.index-dev.js.executor": "Run",
|
|
33
65
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
|
34
66
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
35
|
-
"
|
|
67
|
+
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
|
68
|
+
"git-widget-placeholder": "develop",
|
|
69
|
+
"last_opened_file_path": "/Users/davidhernandezalmagro/Desktop/Tonder/tonder-sdk/src/shared/constants",
|
|
70
|
+
"node.js.detected.package.eslint": "true",
|
|
71
|
+
"node.js.detected.package.tslint": "true",
|
|
72
|
+
"node.js.selected.package.eslint": "(autodetect)",
|
|
73
|
+
"node.js.selected.package.tslint": "(autodetect)",
|
|
36
74
|
"nodejs_package_manager_path": "npm",
|
|
75
|
+
"prettierjs.PrettierConfiguration.Package": "/Users/davidhernandezalmagro/Desktop/Tonder/tonder-sdk/node_modules/prettier",
|
|
76
|
+
"settings.editor.selected.configurable": "settings.javascript.prettier",
|
|
77
|
+
"ts.external.directory.path": "/Applications/WebStorm.app/Contents/plugins/javascript-impl/jsLanguageServicesImpl/external",
|
|
37
78
|
"vue.rearranger.settings.migration": "true"
|
|
38
79
|
}
|
|
39
80
|
}]]></component>
|
|
40
|
-
<component name="
|
|
41
|
-
<
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
81
|
+
<component name="RecentsManager">
|
|
82
|
+
<key name="CopyFile.RECENT_KEYS">
|
|
83
|
+
<recent name="$PROJECT_DIR$/src/shared/constants" />
|
|
84
|
+
</key>
|
|
85
|
+
<key name="MoveFile.RECENT_KEYS">
|
|
86
|
+
<recent name="$PROJECT_DIR$/src/shared/constants" />
|
|
87
|
+
<recent name="$PROJECT_DIR$/src/shared" />
|
|
88
|
+
</key>
|
|
89
|
+
</component>
|
|
90
|
+
<component name="RunManager">
|
|
91
|
+
<configuration name="index-dev.js" type="NodeJSConfigurationType" temporary="true" nameIsGenerated="true" path-to-js-file="$PROJECT_DIR$/src/index-dev.js" working-dir="$PROJECT_DIR$/src">
|
|
92
|
+
<method v="2" />
|
|
93
|
+
</configuration>
|
|
94
|
+
<recent_temporary>
|
|
95
|
+
<list>
|
|
96
|
+
<item itemvalue="Node.js.index-dev.js" />
|
|
97
|
+
</list>
|
|
98
|
+
</recent_temporary>
|
|
46
99
|
</component>
|
|
47
100
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
|
48
101
|
<component name="TaskManager">
|
|
@@ -53,10 +106,42 @@
|
|
|
53
106
|
<option name="presentableId" value="Default" />
|
|
54
107
|
<updated>1720449973301</updated>
|
|
55
108
|
<workItem from="1720449976262" duration="22000" />
|
|
109
|
+
<workItem from="1723519348652" duration="9602000" />
|
|
110
|
+
<workItem from="1723696656585" duration="1227000" />
|
|
111
|
+
<workItem from="1723697920061" duration="3868000" />
|
|
112
|
+
<workItem from="1723774667217" duration="11739000" />
|
|
113
|
+
<workItem from="1723855727317" duration="20341000" />
|
|
114
|
+
<workItem from="1723952592527" duration="17418000" />
|
|
56
115
|
</task>
|
|
57
116
|
<servers />
|
|
58
117
|
</component>
|
|
59
118
|
<component name="TypeScriptGeneratedFilesManager">
|
|
60
119
|
<option name="version" value="3" />
|
|
61
120
|
</component>
|
|
121
|
+
<component name="Vcs.Log.Tabs.Properties">
|
|
122
|
+
<option name="TAB_STATES">
|
|
123
|
+
<map>
|
|
124
|
+
<entry key="MAIN">
|
|
125
|
+
<value>
|
|
126
|
+
<State />
|
|
127
|
+
</value>
|
|
128
|
+
</entry>
|
|
129
|
+
</map>
|
|
130
|
+
</option>
|
|
131
|
+
</component>
|
|
132
|
+
<component name="XDebuggerManager">
|
|
133
|
+
<breakpoint-manager>
|
|
134
|
+
<breakpoints>
|
|
135
|
+
<line-breakpoint enabled="true" type="javascript">
|
|
136
|
+
<url>file://$PROJECT_DIR$/src/classes/inlineCheckout.js</url>
|
|
137
|
+
<line>151</line>
|
|
138
|
+
<option name="timeStamp" value="1" />
|
|
139
|
+
</line-breakpoint>
|
|
140
|
+
<line-breakpoint enabled="true" type="javascript">
|
|
141
|
+
<url>file://$PROJECT_DIR$/src/shared/constants/paymentMethodAPM.js</url>
|
|
142
|
+
<option name="timeStamp" value="15" />
|
|
143
|
+
</line-breakpoint>
|
|
144
|
+
</breakpoints>
|
|
145
|
+
</breakpoint-manager>
|
|
146
|
+
</component>
|
|
62
147
|
</project>
|
package/README.md
CHANGED
|
@@ -138,14 +138,12 @@ const checkoutData = {
|
|
|
138
138
|
|
|
139
139
|
const apiKey = "4c87c36e697e65ddfe288be0afbe7967ea0ab865";
|
|
140
140
|
const returnUrl = "http://my-website:8080/checkout"
|
|
141
|
-
const successUrl = "http://my-website:8080/success"
|
|
142
141
|
|
|
143
142
|
// if using script tag, it should be initialized like this
|
|
144
143
|
// new TonderSdk.InlineCheckout
|
|
145
144
|
const inlineCheckout = new InlineCheckout({
|
|
146
145
|
apiKey,
|
|
147
146
|
returnUrl,
|
|
148
|
-
successUrl,
|
|
149
147
|
styles: customStyles
|
|
150
148
|
});
|
|
151
149
|
|
|
@@ -179,7 +177,6 @@ const response = await inlineCheckout.payment(checkoutData);
|
|
|
179
177
|
| apiKey | string | You can take this from you Tonder Dashboard |
|
|
180
178
|
| backgroundColor | string | Hex color #000000 |
|
|
181
179
|
| returnUrl | string | url where the checkout form is mounted (3ds) |
|
|
182
|
-
| successUrl | string | |
|
|
183
180
|
| backgroundColor | string | |
|
|
184
181
|
|
|
185
182
|
## setPayment params
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tonder-web-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0-beta.0",
|
|
4
4
|
"description": "tonder sdk for integrations",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"build": "webpack --config webpack.config.js --mode production"
|
|
9
9
|
},
|
|
10
10
|
"author": "",
|
|
11
|
+
"types": "types/index.d.ts",
|
|
11
12
|
"license": "ISC",
|
|
12
13
|
"dependencies": {
|
|
13
14
|
"crypto-js": "^4.1.1",
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
"css-loader": "^6.7.3",
|
|
21
22
|
"cypress": "^13.6.2",
|
|
22
23
|
"html-webpack-plugin": "^5.5.3",
|
|
24
|
+
"prettier": "^3.3.3",
|
|
23
25
|
"style-loader": "^3.3.1",
|
|
24
26
|
"terser-webpack-plugin": "^5.3.10",
|
|
25
27
|
"webpack": "^5.75.0",
|
|
@@ -3,12 +3,10 @@ export class ThreeDSHandler {
|
|
|
3
3
|
payload = null,
|
|
4
4
|
apiKey,
|
|
5
5
|
baseUrl,
|
|
6
|
-
successUrl
|
|
7
6
|
}) {
|
|
8
7
|
this.baseUrl = baseUrl,
|
|
9
8
|
this.apiKey = apiKey,
|
|
10
|
-
this.payload = payload
|
|
11
|
-
this.successUrl = successUrl
|
|
9
|
+
this.payload = payload
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
saveVerifyTransactionUrl() {
|
|
@@ -120,7 +118,6 @@ export class ThreeDSHandler {
|
|
|
120
118
|
// TODO: Remove this duplication
|
|
121
119
|
handleSuccessTransaction(response) {
|
|
122
120
|
this.removeVerifyTransactionUrl();
|
|
123
|
-
// window.location = this.successUrl
|
|
124
121
|
console.log('Transacción autorizada');
|
|
125
122
|
return response;
|
|
126
123
|
}
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { ThreeDSHandler } from "./3dsHandler.js";
|
|
2
|
+
import {createOrder, fetchBusiness, getOpenpayDeviceSessionID, registerOrFetchCustomer} from "../data";
|
|
3
|
+
import { TONDER_URL_BY_MODE } from "../shared/constants/tonderUrl";
|
|
4
|
+
import { globalLoader } from "./globalLoader";
|
|
5
|
+
import {createPayment, startCheckoutRouter} from "../data/checkoutApi";
|
|
6
|
+
import {getBrowserInfo, injectMercadoPagoSecurity} from "../helpers/utils";
|
|
7
|
+
|
|
8
|
+
export class BaseInlineCheckout {
|
|
9
|
+
baseUrl = "";
|
|
10
|
+
cartTotal = "0"
|
|
11
|
+
constructor({
|
|
12
|
+
mode = "stage",
|
|
13
|
+
apiKey,
|
|
14
|
+
returnUrl,
|
|
15
|
+
callBack = () => {},
|
|
16
|
+
sdkMode = "full",
|
|
17
|
+
}) {
|
|
18
|
+
this.apiKeyTonder = apiKey;
|
|
19
|
+
this.returnUrl = returnUrl;
|
|
20
|
+
this.callBack = callBack;
|
|
21
|
+
this.mode = mode;
|
|
22
|
+
this.baseUrl = TONDER_URL_BY_MODE[this.mode] || TONDER_URL_BY_MODE["stage"];
|
|
23
|
+
this.abortController = new AbortController();
|
|
24
|
+
this.process3ds = new ThreeDSHandler({
|
|
25
|
+
apiKey: apiKey,
|
|
26
|
+
baseUrl: this.baseUrl,
|
|
27
|
+
});
|
|
28
|
+
this.sdkMode = sdkMode;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
configureCheckout(data) {
|
|
32
|
+
if ("customer" in data) this.#handleCustomer(data["customer"]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async verify3dsTransaction() {
|
|
36
|
+
globalLoader.show(); // TODO: HOW?
|
|
37
|
+
const result3ds = await this.process3ds.verifyTransactionStatus();
|
|
38
|
+
const resultCheckout = await this.#resumeCheckout(result3ds);
|
|
39
|
+
this.process3ds.setPayload(resultCheckout);
|
|
40
|
+
globalLoader.remove(); // TODO: HOW?
|
|
41
|
+
return this.#handle3dsRedirect(resultCheckout);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
payment(data) {
|
|
45
|
+
return new Promise(async (resolve, reject) => {
|
|
46
|
+
try {
|
|
47
|
+
this.#handleCustomer(data.customer);
|
|
48
|
+
this._setCartTotal(data.cart?.total);
|
|
49
|
+
this.#setCartItems(data.cart?.items);
|
|
50
|
+
this.#handleMetadata(data);
|
|
51
|
+
this.#handleCurrency(data);
|
|
52
|
+
this.#handleCard(data);
|
|
53
|
+
const response = await this._checkout(data);
|
|
54
|
+
this.process3ds.setPayload(response);
|
|
55
|
+
this.callBack(response);
|
|
56
|
+
const payload = await this.#handle3dsRedirect(response);
|
|
57
|
+
if (payload) {
|
|
58
|
+
resolve(response);
|
|
59
|
+
}
|
|
60
|
+
} catch (error) {
|
|
61
|
+
reject(error);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async _initializeCheckout() {
|
|
67
|
+
const { mercado_pago } = await this.#fetchMerchantData();
|
|
68
|
+
|
|
69
|
+
if (!!mercado_pago && !!mercado_pago.active) {
|
|
70
|
+
injectMercadoPagoSecurity();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async _getCustomer(customer, signal) {
|
|
75
|
+
return await registerOrFetchCustomer(
|
|
76
|
+
this.baseUrl,
|
|
77
|
+
this.apiKeyTonder,
|
|
78
|
+
customer,
|
|
79
|
+
signal,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async _checkout() {
|
|
84
|
+
throw new Error(
|
|
85
|
+
"The #checkout method should be implement in child classes.",
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
_setCartTotal(total) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
"The #setCartTotal method should be implement in child classes.",
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async _handleCheckout(
|
|
96
|
+
{
|
|
97
|
+
card,
|
|
98
|
+
payment_method,
|
|
99
|
+
customer
|
|
100
|
+
}
|
|
101
|
+
) {
|
|
102
|
+
const { openpay_keys, reference, business } = this.merchantData;
|
|
103
|
+
const total = Number(this.cartTotal);
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
let deviceSessionIdTonder;
|
|
107
|
+
if (
|
|
108
|
+
!deviceSessionIdTonder &&
|
|
109
|
+
openpay_keys.merchant_id &&
|
|
110
|
+
openpay_keys.public_key
|
|
111
|
+
) {
|
|
112
|
+
deviceSessionIdTonder = await getOpenpayDeviceSessionID(
|
|
113
|
+
openpay_keys.merchant_id,
|
|
114
|
+
openpay_keys.public_key,
|
|
115
|
+
this.abortController.signal,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const { id, auth_token } = customer;
|
|
120
|
+
|
|
121
|
+
const orderItems = {
|
|
122
|
+
business: this.apiKeyTonder,
|
|
123
|
+
client: auth_token,
|
|
124
|
+
billing_address_id: null,
|
|
125
|
+
shipping_address_id: null,
|
|
126
|
+
amount: total,
|
|
127
|
+
status: "A",
|
|
128
|
+
reference: reference,
|
|
129
|
+
is_oneclick: true,
|
|
130
|
+
items: this.cartItems,
|
|
131
|
+
};
|
|
132
|
+
const jsonResponseOrder = await createOrder(
|
|
133
|
+
this.baseUrl,
|
|
134
|
+
this.apiKeyTonder,
|
|
135
|
+
orderItems,
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Create payment
|
|
139
|
+
const now = new Date();
|
|
140
|
+
const dateString = now.toISOString();
|
|
141
|
+
|
|
142
|
+
const paymentItems = {
|
|
143
|
+
business_pk: business.pk,
|
|
144
|
+
client_id: id,
|
|
145
|
+
amount: total,
|
|
146
|
+
date: dateString,
|
|
147
|
+
order_id: jsonResponseOrder.id,
|
|
148
|
+
};
|
|
149
|
+
const jsonResponsePayment = await createPayment(
|
|
150
|
+
this.baseUrl,
|
|
151
|
+
this.apiKeyTonder,
|
|
152
|
+
paymentItems,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// Checkout router
|
|
156
|
+
const routerItems = {
|
|
157
|
+
name: this.firstName || "",
|
|
158
|
+
last_name: this.lastName || "",
|
|
159
|
+
email_client: this.email,
|
|
160
|
+
phone_number: this.phone,
|
|
161
|
+
return_url: this.returnUrl,
|
|
162
|
+
id_product: "no_id",
|
|
163
|
+
quantity_product: 1,
|
|
164
|
+
id_ship: "0",
|
|
165
|
+
instance_id_ship: "0",
|
|
166
|
+
amount: total,
|
|
167
|
+
title_ship: "shipping",
|
|
168
|
+
description: "transaction",
|
|
169
|
+
device_session_id: deviceSessionIdTonder ? deviceSessionIdTonder : null,
|
|
170
|
+
token_id: "",
|
|
171
|
+
order_id: jsonResponseOrder.id,
|
|
172
|
+
business_id: business.pk,
|
|
173
|
+
payment_id: jsonResponsePayment.pk,
|
|
174
|
+
source: "sdk",
|
|
175
|
+
metadata: this.metadata,
|
|
176
|
+
browser_info: getBrowserInfo(),
|
|
177
|
+
currency: this.currency,
|
|
178
|
+
...(!!payment_method ? { payment_method } : { card }),
|
|
179
|
+
...(typeof MP_DEVICE_SESSION_ID !== "undefined"
|
|
180
|
+
? { mp_device_session_id: MP_DEVICE_SESSION_ID }
|
|
181
|
+
: {}),
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const jsonResponseRouter = await startCheckoutRouter(
|
|
185
|
+
this.baseUrl,
|
|
186
|
+
this.apiKeyTonder,
|
|
187
|
+
routerItems,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
if (jsonResponseRouter) {
|
|
191
|
+
return jsonResponseRouter;
|
|
192
|
+
} else {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.log(error);
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async #fetchMerchantData() {
|
|
202
|
+
this.merchantData = await fetchBusiness(
|
|
203
|
+
this.baseUrl,
|
|
204
|
+
this.apiKeyTonder,
|
|
205
|
+
this.abortController.signal,
|
|
206
|
+
);
|
|
207
|
+
return this.merchantData;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async #resumeCheckout(response) {
|
|
211
|
+
// Stop the routing process if the transaction is either hard declined or successful
|
|
212
|
+
if (response?.decline?.error_type === "Hard") {
|
|
213
|
+
return response;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (["Success", "Authorized"].includes(response?.transaction_status)) {
|
|
217
|
+
return response;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (response) {
|
|
221
|
+
globalLoader.show();
|
|
222
|
+
const routerItems = {
|
|
223
|
+
checkout_id: response?.checkout?.id,
|
|
224
|
+
};
|
|
225
|
+
try {
|
|
226
|
+
return await startCheckoutRouter(
|
|
227
|
+
this.baseUrl,
|
|
228
|
+
this.apiKeyTonder,
|
|
229
|
+
routerItems,
|
|
230
|
+
);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
// throw error
|
|
233
|
+
} finally {
|
|
234
|
+
globalLoader.remove();
|
|
235
|
+
}
|
|
236
|
+
return response;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
#handleCustomer(customer) {
|
|
241
|
+
if (!customer) return;
|
|
242
|
+
|
|
243
|
+
this.firstName = customer?.firstName;
|
|
244
|
+
this.lastName = customer?.lastName;
|
|
245
|
+
this.country = customer?.country;
|
|
246
|
+
this.address = customer?.street;
|
|
247
|
+
this.city = customer?.city;
|
|
248
|
+
this.state = customer?.state;
|
|
249
|
+
this.postCode = customer?.postCode;
|
|
250
|
+
this.email = customer?.email;
|
|
251
|
+
this.phone = customer?.phone;
|
|
252
|
+
this.customer = customer;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
#handleMetadata(data) {
|
|
256
|
+
this.metadata = data?.metadata;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
#handleCurrency(data) {
|
|
260
|
+
this.currency = data?.currency;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
#handleCard(data) {
|
|
264
|
+
this.card = data?.card;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
#setCartItems(items) {
|
|
268
|
+
this.cartItems = items;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async #handle3dsRedirect(response) {
|
|
272
|
+
const iframe = response?.next_action?.iframe_resources?.iframe;
|
|
273
|
+
|
|
274
|
+
if (iframe) {
|
|
275
|
+
this.process3ds
|
|
276
|
+
.loadIframe()
|
|
277
|
+
.then(() => {
|
|
278
|
+
//TODO: Check if this will be necessary on the frontend side
|
|
279
|
+
// after some the tests in production, since the 3DS process
|
|
280
|
+
// doesn't works properly on the sandbox environment
|
|
281
|
+
// setTimeout(() => {
|
|
282
|
+
// process3ds.verifyTransactionStatus();
|
|
283
|
+
// }, 10000);
|
|
284
|
+
this.process3ds.verifyTransactionStatus();
|
|
285
|
+
})
|
|
286
|
+
.catch((error) => {
|
|
287
|
+
console.log("Error loading iframe:", error);
|
|
288
|
+
});
|
|
289
|
+
} else {
|
|
290
|
+
const redirectUrl = this.process3ds.getRedirectUrl();
|
|
291
|
+
if (redirectUrl) {
|
|
292
|
+
this.process3ds.redirectToChallenge();
|
|
293
|
+
} else {
|
|
294
|
+
return response;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { BaseInlineCheckout } from "./BaseInlineCheckout";
|
|
2
|
+
import {
|
|
3
|
+
fetchCustomerAPMs,
|
|
4
|
+
fetchCustomerCards,
|
|
5
|
+
saveCustomerCard,
|
|
6
|
+
removeCustomerCard,
|
|
7
|
+
} from "../data";
|
|
8
|
+
import { buildErrorResponseFromCatch } from "../helpers/utils";
|
|
9
|
+
import { getVaultToken } from "../data/skyflowApi";
|
|
10
|
+
import { getSkyflowTokens } from "../helpers/skyflow";
|
|
11
|
+
|
|
12
|
+
export class LiteInlineCheckout extends BaseInlineCheckout {
|
|
13
|
+
constructor({ mode = "stage", apiKey, returnUrl, callBack = () => {} }) {
|
|
14
|
+
super({ mode, apiKey, returnUrl, callBack });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async injectCheckout() {
|
|
18
|
+
await this._initializeCheckout();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the list of cards associated with a customer.
|
|
23
|
+
* @param {string} authToken - The customer's authentication token.
|
|
24
|
+
* @param {string} businessId - The business primary key.
|
|
25
|
+
* @returns {Promise<Object>} A promise that resolves with the customer's card data.
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
async getCustomerCards(authToken, businessId) {
|
|
29
|
+
return await fetchCustomerCards(this.baseUrl, authToken, businessId);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Saves a card to a customer's account. This method can be used to add a new card
|
|
34
|
+
* or update an existing one.
|
|
35
|
+
* @param {string} authToken - The customer's authentication token.
|
|
36
|
+
* @param {string} businessId - The business primary key.
|
|
37
|
+
* @param {Object} cardData - The card information to be saved.
|
|
38
|
+
* @returns {Promise<Object>} A promise that resolves with the saved card data.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
async saveCustomerCard(authToken, businessId, cardData) {
|
|
42
|
+
return await saveCustomerCard(
|
|
43
|
+
this.baseUrl,
|
|
44
|
+
authToken,
|
|
45
|
+
businessId,
|
|
46
|
+
cardData,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Removes a card from a customer's account.
|
|
52
|
+
* @param {string} authToken - The customer's authentication token.
|
|
53
|
+
* @param {string} skyflowId - The unique identifier of the card to be deleted.
|
|
54
|
+
* @param {string} businessId - The business primary key.
|
|
55
|
+
* @returns {Promise<Object>} A promise that resolves when the card is successfully deleted.
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
async removeCustomerCard(authToken, skyflowId, businessId) {
|
|
59
|
+
return await removeCustomerCard(
|
|
60
|
+
this.baseUrl,
|
|
61
|
+
authToken,
|
|
62
|
+
skyflowId,
|
|
63
|
+
businessId,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Retrieves the list of available Alternative Payment Methods (APMs).
|
|
69
|
+
* @returns {Promise<Object>} A promise that resolves with the list of APMs.
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
async getCustomerAPMs() {
|
|
73
|
+
return await fetchCustomerAPMs(this.baseUrl, this.apiKeyTonder);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_setCartTotal(total) {
|
|
77
|
+
this.cartTotal = total;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async _checkout({ card, payment_method }) {
|
|
81
|
+
const customer = await this._getCustomer(
|
|
82
|
+
this.customer,
|
|
83
|
+
this.abortController.signal,
|
|
84
|
+
);
|
|
85
|
+
const { vault_id, vault_url } = this.merchantData;
|
|
86
|
+
let skyflowTokens;
|
|
87
|
+
skyflowTokens = await getSkyflowTokens({
|
|
88
|
+
vault_id: vault_id,
|
|
89
|
+
vault_url: vault_url,
|
|
90
|
+
data: card,
|
|
91
|
+
baseUrl: this.baseUrl,
|
|
92
|
+
apiKey: this.apiKeyTonder,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return await this._handleCheckout({
|
|
96
|
+
card: skyflowTokens,
|
|
97
|
+
payment_method,
|
|
98
|
+
customer,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|