This commit is contained in:
you 2024-07-27 07:50:38 +03:00
parent 06d4c96c44
commit 5b5dc15f5c
3 changed files with 366 additions and 186 deletions

11
package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"axios": "^1.6.8", "axios": "^1.6.8",
"date-fns": "^3.0.2-rc.1",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
"serialize-error": "^11.0.3", "serialize-error": "^11.0.3",
@ -710,6 +711,16 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/date-fns": {
"version": "3.0.2-rc.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.0.2-rc.1.tgz",
"integrity": "sha512-rtLgW/u9feeKuSjYjDZVDoe47sdA7QnGRbyEtFtmNB8SXVQnL3g3SIKlcQkHwk5X7uhmF9vP7/B1ZGXtGsF+IA==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/decamelize": { "node_modules/decamelize": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",

View File

@ -24,6 +24,7 @@
}, },
"dependencies": { "dependencies": {
"axios": "^1.6.8", "axios": "^1.6.8",
"date-fns": "^3.0.2-rc.1",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
"serialize-error": "^11.0.3", "serialize-error": "^11.0.3",

View File

@ -5,11 +5,18 @@
import axios from "axios"; import axios from "axios";
import { sayError, sayInfo } from "../lib/toaster"; import { sayError, sayInfo } from "../lib/toaster";
import LoadingSpinner from "../lib/loadingSpinner.svelte"; import LoadingSpinner from "../lib/loadingSpinner.svelte";
import { addMinutes, formatDistanceToNow, parseISO } from "date-fns";
import { ca, ru } from "date-fns/locale";
const apiBase = "https://24paymentgateway.ru/api/v1/"; const apiBase = "https://24paymentgateway.ru/api/v1/";
const delay = (ms) => new Promise((res) => setTimeout(res, ms)); let showAccept = false;
let showReject = false;
let showNormal = false;
let showTimeout = false;
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
//http://localhost:8080/?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJleHAiOjE3MjQzNjEzOTgsImlhdCI6MTcyMTk0MjE5OCwiaW5fY3VycmVuY3lfY29kZSI6IktHUyIsImlzcyI6Ikhvc3RhcGF5Iiwib3JkZXJfaWQiOiIxZjhjOTI2NC1lZWQ3LTRhYzMtYTEyZC0xYzEzMjg4MWM4NzQiLCJvdXRfY3VycmVuY3lfY29kZSI6IktHUyJ9.w_ki56Hb81kX2SoS9qm0Je3atBhmUWTQaYYrLX-udCM
/** /**
* hpp: * hpp:
1) GET: /api/v1/getPaymentMethods 1) GET: /api/v1/getPaymentMethods
@ -29,6 +36,36 @@
// await delay(5000); // await delay(5000);
const urlParams = new URLSearchParams(queryString); const urlParams = new URLSearchParams(queryString);
tokenURL = urlParams.get("token"); tokenURL = urlParams.get("token");
console.log(tokenURL);
validateJWT(tokenURL);
// console.log();
if (invalidURL == true) {
sayError("Неверный ID заявки");
} else {
await getOrderStatus();
switch (orderStatus) {
case 1:
getPaymentMethods();
break;
case 2:
showReject = true;
break;
case 3:
showAccept = true;
break;
case 4:
getPaymentMethods();
case 5:
getPaymentMethods();
case 6:
showTimeout = true;
default:
break;
}
// getPaymentMethods();
}
// console.log(urlParams.get("token")); // console.log(urlParams.get("token"));
} }
getTokenFromURL(); getTokenFromURL();
@ -41,17 +78,23 @@
invalidURL = false; invalidURL = false;
} catch (error) { } catch (error) {
invalidURL = true; invalidURL = true;
// console.log(error); console.log(error);
} }
} }
$: tokenURL, validateJWT(tokenURL); let timeLeft = "";
$: invalidURL, let timeLeftInterval = -1;
(() => { function calculateDate(src) {
if (!invalidURL) { const originalDate = parseISO(src);
getPaymentMethods(); const newDate = addMinutes(originalDate, 10);
timeLeftInterval = setInterval(() => {
timeLeft = formatDistanceToNow(newDate, {
addSuffix: true,
includeSeconds: true,
locale: ru,
});
}, 1000);
} }
})();
let selectedBank = ""; let selectedBank = "";
let depositTimeLeft = 60; //seconds let depositTimeLeft = 60; //seconds
@ -102,7 +145,7 @@
// }, 1000); // }, 1000);
// } // }
// function stopTimer() { // function stopTimer() {loaded-file
// clearInterval(timerInterval); // clearInterval(timerInterval);
// depositTimeLeft = 60; // depositTimeLeft = 60;
// } // }
@ -173,6 +216,7 @@
requestingReqs = true; requestingReqs = true;
disableGetReqBtn = true; disableGetReqBtn = true;
await delay(2000); await delay(2000);
try {
let result = await axios.post( let result = await axios.post(
apiBase + "getRequisites", apiBase + "getRequisites",
{ {
@ -189,34 +233,54 @@
requisites = result.data; requisites = result.data;
console.log(result); console.log(result);
showReqs = true; showReqs = true;
calculateDate(result.data["requisite_creation_time"]);
} catch (error) {
sayError("Срок заявки истёк");
showTimeout = true;
orderStatus = 6;
}
} }
// getRequisites(); // getRequisites();
let orderStatus; let orderStatus;
async function getOrderStatus() { async function getOrderStatus() {
try {
let result = await axios.get(apiBase + "getOrderStatus", { let result = await axios.get(apiBase + "getOrderStatus", {
headers: { headers: {
Authorization: "Bearer " + "jwt", Authorization: "Bearer " + tokenURL,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}); });
orderStatus = result.data.status;
console.log(result); console.log(result);
if(orderStatus === 4)
{
selectedBank = result.data["bank_id"];
}
else if (orderStatus === 5)
{
selectedBank = result.data["bank_id"];
requisites = result.data["requisites"];
calculateDate(requisites["requisite_creation_time"]);
showReqs = true;
}
} catch (error) {
orderStatus=6;
}
} }
// getOrderStatus();
async function loadReceipt() { async function loadReceipt() {
let result = await axios.post( const formData = new FormData();
apiBase + "loadDisputeReceipt", let file = document.getElementById("loaded-file").files[0];
{ // formData.append("uuid", orderID);
//data form formData.append("data", file);
}, let result = await axios.post(apiBase + "openDispute", formData, {
{
headers: { headers: {
Authorization: "Bearer " + "jwt", Authorization: "Bearer " + tokenURL,
"Content-Type": "application/json", "Content-Type": "multipart/form-data",
}, },
}, });
);
console.log(result); console.log(result);
} }
@ -260,7 +324,7 @@
}, },
{ {
headers: { headers: {
Authorization: "Bearer " + "jwt", Authorization: "Bearer " + tokenURL,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}, },
@ -268,18 +332,39 @@
console.log(result); console.log(result);
} }
async function copyToClipboard() { async function copyToClipboard() {
try { try {
await navigator.clipboard.writeText(requisites.requisite[1]); await navigator.clipboard.writeText(requisites.requisite[1]);
sayInfo('Скопировано!'); sayInfo("Скопировано!");
} catch (err) { } catch (err) {
console.error('Failed to copy: ', err); console.error("Failed to copy: ", err);
} }
} }
function startPingingStatus() {ping();}
async function ping() {
await getOrderStatus();
if (orderStatus === 2) {
showReject = true;
showLoadingScreen = false;
return;
}
if(orderStatus === 3)
{
showAccept = true;
showLoadingScreen = false;
return;
}
if(orderStatus===6)
{
showTimeout = true;
showLoadingScreen = false;
return;
}
await delay(1000);
ping();
}
</script> </script>
{#if invalidURL} {#if invalidURL}
@ -319,37 +404,6 @@
> >
<p class="text-sm flex-shrink-0">Заявка {orderID}</p> <p class="text-sm flex-shrink-0">Заявка {orderID}</p>
</div> </div>
<div class="flex flex-col w-full gap-16">
<div class="flex w-full">
<div
class="flex flex-col w-full flex-grow-0 bg-slate-900 p-8 gap-2 rounded-3xl"
>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>Дождитесь выдачи реквизитов</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>
Переведите <span class=" underline">точную сумму</span> на указанный
реквизит
</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>После успешного перевода нажмите "Я оплатил"</p>
</div>
<div class="flex items-center justify-center gap-2 text-lg mt-4">
<button
on:click={() => {
showAlertQuit = true;
}}
class="bg-slate-900 ring-2 ring-slate-800 rounded-3xl hover:ring-red-800 p-2 px-8"
>Отменить заявку</button
>
</div>
</div>
</div>
<div class="flex flex-col w-full gap-8"> <div class="flex flex-col w-full gap-8">
{#if showBankSelection} {#if showBankSelection}
<p class="text-3xl font-bold">Выбор банка</p> <p class="text-3xl font-bold">Выбор банка</p>
@ -388,9 +442,7 @@
<button <button
disabled={disableGetReqBtn} disabled={disableGetReqBtn}
on:click={() => { on:click={() => {
getRequisites(); getRequisites();
}} }}
class={"bg-indigo-800 hover:bg-indigo-700 ring-transparent disabled:bg-transparent disabled:text-gray-600 disabled:ring-2 disabled:ring-inset disabled:ring-gray-600" + class={"bg-indigo-800 hover:bg-indigo-700 ring-transparent disabled:bg-transparent disabled:text-gray-600 disabled:ring-2 disabled:ring-inset disabled:ring-gray-600" +
" w-full font-semibold text-xl flex gap-1 justify-center items-center text-center p-4 rounded-3xl transition-all duration-75 ring-2 ring-inset focus:outline-none focus:ring-inset focus:ring-1 focus:ring-white"} " w-full font-semibold text-xl flex gap-1 justify-center items-center text-center p-4 rounded-3xl transition-all duration-75 ring-2 ring-inset focus:outline-none focus:ring-inset focus:ring-1 focus:ring-white"}
@ -406,10 +458,12 @@
<div class="w-full flex p-8 rounded-3xl bg-indigo-950"> <div class="w-full flex p-8 rounded-3xl bg-indigo-950">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<p class="text-lg">Номер карты для перевода</p> <p class="text-lg">Номер карты для перевода</p>
<div class="flex gap-4 justify-center items-center"> <div class="flex gap-4 items-center">
<p class="text-2xl font-bold">{requisites.requisite[1]}</p> <p class="text-2xl font-bold">
{requisites.requisite[1]}
</p>
<button <button
on:click={()=>{ on:click={() => {
copyToClipboard(); copyToClipboard();
}} }}
class="relative w-11 h-10 p-2 rounded-full bg-indigo-900 group hover:bg-indigo-800" class="relative w-11 h-10 p-2 rounded-full bg-indigo-900 group hover:bg-indigo-800"
@ -424,13 +478,14 @@
</div> </div>
<p class="text-lg">Получатель: {requisites.requisite[0]}</p> <p class="text-lg">Получатель: {requisites.requisite[0]}</p>
<p class="text-lg mt-4"> <p class="text-lg mt-4">
Время на оплату Время на оплату: {timeLeft}
</p> </p>
</div> </div>
</div> </div>
<button <button
on:click={() => { on:click={() => {
showLoadingScreen = true; showLoadingScreen = true;
startPingingStatus();
}} }}
disabled={showHelpSection} disabled={showHelpSection}
class={(false class={(false
@ -467,7 +522,9 @@
<button <button
on:click={() => { on:click={() => {
// window.open("https://www.google.com", "__blank"); // window.open("https://www.google.com", "__blank");
showLoadingScreen = true; showLoadingScreen = true;
loadReceipt();
}} }}
disabled={loadedFile === ""} disabled={loadedFile === ""}
class={"bg-green-800 hover:bg-green-700 ring-transparent" + class={"bg-green-800 hover:bg-green-700 ring-transparent" +
@ -487,6 +544,52 @@
{/if} {/if}
{/if} {/if}
</div> </div>
<div class="flex flex-col w-full gap-4">
<div class="flex w-full">
<div
class="flex flex-col w-full flex-grow-0 bg-slate-900 p-8 gap-2 rounded-3xl"
>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>Дождитесь выдачи реквизитов</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>
Переведите <span class=" underline">точную сумму</span> на указанный
реквизит
</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<div class="w-2 h-2 bg-white rounded-full flex-shrink-0"></div>
<p>После успешного перевода нажмите "Я оплатил"</p>
</div>
<div class="flex items-center justify-center gap-2 text-lg mt-4">
<button
on:click={() => {
showAlertQuit = true;
}}
class="bg-slate-900 ring-2 ring-slate-800 rounded-3xl hover:ring-red-800 p-2 px-8"
>Отменить заявку</button
>
</div>
</div>
</div>
<div class="flex w-full">
<div
class="flex flex-col items-center w-full flex-grow-0 bg-slate-900 p-8 gap-2 rounded-3xl"
>
<div class="flex items-center justify-start gap-2 text-lg">
<p class="text-white text-lg">
<a class="underline" href="https://t.me/hosta_pay">@hosta_pay</a
>
</p>
</div>
<div class="flex items-center justify-start gap-2 text-lg">
<p>support@24paymentgateway.ru</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -496,7 +599,7 @@
class="fixed bg-slate-950 inset-0 w-full h-full bg-opacity-70 flex justify-center items-center text-white" class="fixed bg-slate-950 inset-0 w-full h-full bg-opacity-70 flex justify-center items-center text-white"
> >
<div <div
class="flex flex-col p-8 relative bg-slate-950 rounded-3xl gap-8 max-w-[30%] ring-2 ring-slate-800" class="flex flex-col p-8 relative bg-slate-950 rounded-3xl gap-8 max-w-[90%] ring-2 ring-slate-800"
> >
<p class="font-semibold text-4xl">Отмена заявки</p> <p class="font-semibold text-4xl">Отмена заявки</p>
<p class="text-2xl text-red-100"> <p class="text-2xl text-red-100">
@ -514,7 +617,9 @@
// stopTimer(); // stopTimer();
// stopTotalTimer(); // stopTotalTimer();
// showAlertQuit = false; // showAlertQuit = false;
window.open("https://www.google.com", "__blank"); // window.open("https://www.google.com", "__blank");
cancelOrder();
window.location.reload();
}} }}
class="text-xl p-4 bg-slate-950 ring-2 ring-slate-800 rounded-3xl hover:ring-red-800" class="text-xl p-4 bg-slate-950 ring-2 ring-slate-800 rounded-3xl hover:ring-red-800"
>Да, отменить</button >Да, отменить</button
@ -543,6 +648,69 @@
</div> </div>
<p class="text-white text-2xl mt-8">Ваш платёж обрабатывается</p> <p class="text-white text-2xl mt-8">Ваш платёж обрабатывается</p>
<p class="text-white opacity-50 text-xl">Это не займет много времени</p> <p class="text-white opacity-50 text-xl">Это не займет много времени</p>
<p class="text-white opacity-50 text-sm">Номер платежа: {orderID}</p>
<p class="text-white opacity-50 text-sm">
Телеграм: <a class="underline" href="https://t.me/hosta_pay"
>@hosta_pay</a
>
</p>
<p class="text-white opacity-50 text-sm">
Почта: support@24paymentgateway.ru
</p>
</div> </div>
{/if} {/if}
{/if} {/if}
{#if showAccept}
<div
class="fixed inset-0 bg-slate-950 flex justify-center items-center text-white"
>
<div class="flex flex-col gap-1 justify-center items-center">
<svg
width="64px"
height="64px"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15 10L11 14L9 12M12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21Z"
stroke="#0F0"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<p class="text-xl font-bold">Заявка исполнена</p>
<p class="text-white opacity-50 text-sm">Номер платежа: {orderID}</p>
<p class="text-white opacity-50 text-sm">
Телеграм: <a class="underline" href="https://t.me/hosta_pay"
>@hosta_pay</a
>
</p>
<p class="text-white opacity-50 text-sm">
Почта: support@24paymentgateway.ru
</p>
</div>
</div>
{:else if showTimeout}
<div
class="fixed inset-0 bg-slate-950 flex justify-center items-center text-white"
>
<div class="flex flex-col gap-1 justify-center items-center">
<svg width="64px" height="64px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 15L12 13M12 13L14 11M12 13L10 11M12 13L14 15M21 6L19 4M10 2H14M12 21C7.58172 21 4 17.4183 4 13C4 8.58172 7.58172 5 12 5C16.4183 5 20 8.58172 20 13C20 17.4183 16.4183 21 12 21Z" stroke="#f00" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<p class="text-xl font-bold">Время заявки истекло</p>
<p class="text-white opacity-50 text-sm">Номер платежа: {orderID}</p>
<p class="text-white opacity-50 text-sm">
Телеграм: <a class="underline" href="https://t.me/hosta_pay"
>@hosta_pay</a
>
</p>
<p class="text-white opacity-50 text-sm">
Почта: support@24paymentgateway.ru
</p>
</div>
</div>
{/if}