This commit is contained in:
parent
2984e3780a
commit
2e01f58e67
@ -1,29 +1,3 @@
|
||||
@use 'typography' as *;
|
||||
@use 'utils' as *;
|
||||
|
||||
// Typography
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
line-height: 100%;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@include h1('h1');
|
||||
}
|
||||
|
||||
h2 {
|
||||
@include h2('h2');
|
||||
}
|
||||
|
||||
h3 {
|
||||
@include h3('h3');
|
||||
}
|
||||
|
||||
//скроллбар
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
|
||||
5
assets/scss/mixins.scss
Normal file
5
assets/scss/mixins.scss
Normal file
@ -0,0 +1,5 @@
|
||||
@mixin mobile {
|
||||
@media (max-width: 768px) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
@ -1,121 +0,0 @@
|
||||
@use 'utils' as *;
|
||||
|
||||
// Font Face Declarations
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src:
|
||||
url('/fonts/Inter-Regular.woff2') format('woff2'),
|
||||
url('/fonts/Inter-Regular.woff') format('woff');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src:
|
||||
url('/fonts/Inter-Medium.woff2') format('woff2'),
|
||||
url('/fonts/Inter-Medium.woff') format('woff');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Inter';
|
||||
src:
|
||||
url('/fonts/Inter-SemiBold.woff2') format('woff2'),
|
||||
url('/fonts/Inter-SemiBold.woff') format('woff');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// Font Variables
|
||||
$font-family-base:
|
||||
'Inter',
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
Roboto,
|
||||
sans-serif;
|
||||
|
||||
// Font Weights
|
||||
$font-weight-regular: 400;
|
||||
$font-weight-medium: 500;
|
||||
$font-weight-semibold: 600;
|
||||
|
||||
// Custom type
|
||||
@mixin font($size, $weight, $lineHeight, $namespace: null, $onlyVars: false) {
|
||||
@if ($namespace) {
|
||||
@if ($onlyVars) {
|
||||
--#{$namespace}-font-size: #{$size};
|
||||
--#{$namespace}-font-weight: #{$weight};
|
||||
--#{$namespace}-line-height: #{$lineHeight};
|
||||
} @else {
|
||||
font-size: var(--#{$namespace}-font-size, $size);
|
||||
font-weight: var(--#{$namespace}-font-weight, $weight);
|
||||
line-height: var(--#{$namespace}-line-height, $lineHeight);
|
||||
}
|
||||
} @else {
|
||||
font-size: $size;
|
||||
font-weight: $weight;
|
||||
line-height: $lineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/* Headline */
|
||||
@mixin h1($namespace: null, $onlyVars: false) {
|
||||
@include font(32px, $font-weight-semibold, 100%, $namespace, $onlyVars);
|
||||
@include mobile {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
@mixin h2($namespace: null, $onlyVars: false) {
|
||||
@include font(24px, $font-weight-semibold, 100%, $namespace, $onlyVars);
|
||||
@include mobile {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
@mixin h3($namespace: null, $onlyVars: false) {
|
||||
@include font(16px, $font-weight-semibold, 140%, $namespace, $onlyVars);
|
||||
}
|
||||
|
||||
/* Text */
|
||||
// 16 medium-(medium/bold)
|
||||
@mixin txt-m($namespace: null, $onlyVars: false) {
|
||||
@include font(16px, $font-weight-regular, 100%, $namespace, $onlyVars);
|
||||
}
|
||||
@mixin txt-m-m($namespace: null, $onlyVars: false) {
|
||||
@include font(16px, $font-weight-medium, 100%, $namespace, $onlyVars);
|
||||
}
|
||||
@mixin txt-m-b($namespace: null, $onlyVars: false) {
|
||||
@include font(16px, $font-weight-semibold, 100%, $namespace, $onlyVars);
|
||||
}
|
||||
|
||||
// 14 regular-(medium/bold)
|
||||
@mixin txt-r($namespace: null, $onlyVars: false) {
|
||||
@include font(14px, $font-weight-regular, 20px, $namespace, $onlyVars);
|
||||
}
|
||||
@mixin txt-r-m($namespace: null, $onlyVars: false) {
|
||||
@include font(14px, $font-weight-medium, 20px, $namespace, $onlyVars);
|
||||
}
|
||||
@mixin txt-r-b($namespace: null, $onlyVars: false) {
|
||||
@include font(14px, $font-weight-semibold, 20px, $namespace, $onlyVars);
|
||||
}
|
||||
|
||||
// 12 text small-(medium/bold)
|
||||
@mixin txt-s($namespace: null, $onlyVars: false) {
|
||||
@include font(12px, $font-weight-regular, 18px, $namespace, $onlyVars);
|
||||
}
|
||||
@mixin txt-s-m($namespace: null, $onlyVars: false) {
|
||||
@include font(12px, $font-weight-medium, 18px, $namespace, $onlyVars);
|
||||
}
|
||||
@mixin txt-s-b($namespace: null, $onlyVars: false) {
|
||||
@include font(12px, $font-weight-semibold, 18px, $namespace, $onlyVars);
|
||||
}
|
||||
|
||||
// 10 text-tiny
|
||||
@mixin txt-t($namespace: null, $onlyVars: false) {
|
||||
@include font(10px, $font-weight-medium, 15px, $namespace, $onlyVars);
|
||||
}
|
||||
@ -1,148 +0,0 @@
|
||||
@use 'sass:color';
|
||||
|
||||
@mixin mobile {
|
||||
@media (max-width: 768px) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
$indents: 0 2 4 5 6 8 10 12 15 16 18 20 24 25 28 30 32 36 40 48 50 52 60 64;
|
||||
|
||||
@each $i in $indents {
|
||||
.m#{$i} {
|
||||
margin: #{$i}px;
|
||||
}
|
||||
|
||||
.mx#{$i} {
|
||||
margin-left: #{$i}px;
|
||||
margin-right: #{$i}px;
|
||||
}
|
||||
|
||||
.my#{$i} {
|
||||
margin-top: #{$i}px;
|
||||
margin-bottom: #{$i}px;
|
||||
}
|
||||
|
||||
.mt#{$i} {
|
||||
margin-top: #{$i}px;
|
||||
}
|
||||
|
||||
.mb#{$i} {
|
||||
margin-bottom: #{$i}px;
|
||||
}
|
||||
|
||||
.ml#{$i} {
|
||||
margin-left: #{$i}px;
|
||||
}
|
||||
|
||||
.mr#{$i} {
|
||||
margin-right: #{$i}px;
|
||||
}
|
||||
|
||||
.p#{$i} {
|
||||
padding: #{$i}px;
|
||||
}
|
||||
|
||||
.px#{$i} {
|
||||
padding-left: #{$i}px;
|
||||
padding-right: #{$i}px;
|
||||
}
|
||||
|
||||
.py#{$i} {
|
||||
padding-top: #{$i}px;
|
||||
padding-bottom: #{$i}px;
|
||||
}
|
||||
|
||||
.pt#{$i} {
|
||||
padding-top: #{$i}px;
|
||||
}
|
||||
|
||||
.pb#{$i} {
|
||||
padding-bottom: #{$i}px;
|
||||
}
|
||||
|
||||
.pl#{$i} {
|
||||
padding-left: #{$i}px;
|
||||
}
|
||||
|
||||
.pr#{$i} {
|
||||
padding-right: #{$i}px;
|
||||
}
|
||||
}
|
||||
|
||||
.mla {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.mra {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
@each $align in ('left', 'right', 'center') {
|
||||
.text-align-#{$align} {
|
||||
text-align: #{$align};
|
||||
}
|
||||
}
|
||||
|
||||
.w-25 { width: 25% !important; }
|
||||
.w-50 { width: 50% !important; }
|
||||
.w-75 { width: 75% !important; }
|
||||
.w-100 { width: 100% !important; }
|
||||
|
||||
.d-none { display: none !important; }
|
||||
.d-inline { display: inline !important; }
|
||||
.d-inline-block { display: inline-block !important; }
|
||||
.d-block { display: block !important; }
|
||||
.d-table { display: table !important; }
|
||||
.d-table-row { display: table-row !important; }
|
||||
.d-table-cell { display: table-cell !important; }
|
||||
.d-flex { display: flex !important; }
|
||||
.d-inline-flex { display: inline-flex !important; }
|
||||
|
||||
.flex-row { flex-direction: row !important; }
|
||||
.flex-column { flex-direction: column !important; }
|
||||
.flex-row-reverse { flex-direction: row-reverse !important; }
|
||||
.flex-column-reverse { flex-direction: column-reverse !important; }
|
||||
|
||||
.flex-wrap { flex-wrap: wrap !important; }
|
||||
.flex-nowrap { flex-wrap: nowrap !important; }
|
||||
.flex-wrap-reverse { flex-wrap: wrap-reverse !important; }
|
||||
|
||||
.justify-content-start { justify-content: flex-start !important; }
|
||||
.justify-content-end { justify-content: flex-end !important; }
|
||||
.justify-content-center { justify-content: center !important; }
|
||||
.justify-content-between { justify-content: space-between !important; }
|
||||
.justify-content-around { justify-content: space-around !important; }
|
||||
|
||||
.align-items-start { align-items: flex-start !important; }
|
||||
.align-items-end { align-items: flex-end !important; }
|
||||
.align-items-center { align-items: center !important; }
|
||||
.align-items-baseline { align-items: baseline !important; }
|
||||
.align-items-stretch { align-items: stretch !important; }
|
||||
|
||||
.align-content-start { align-content: flex-start !important; }
|
||||
.align-content-end { align-content: flex-end !important; }
|
||||
.align-content-center { align-content: center !important; }
|
||||
.align-content-between { align-content: space-between !important; }
|
||||
.align-content-around { align-content: space-around !important; }
|
||||
.align-content-stretch { align-content: stretch !important; }
|
||||
|
||||
.align-self-auto { align-self: auto !important; }
|
||||
.align-self-start { align-self: flex-start !important; }
|
||||
.align-self-end { align-self: flex-end !important; }
|
||||
.align-self-center { align-self: center !important; }
|
||||
.align-self-baseline { align-self: baseline !important; }
|
||||
.align-self-stretch { align-self: stretch !important; }
|
||||
|
||||
.text-align-center { text-align: center !important; }
|
||||
.text-align-left { text-align: left !important; }
|
||||
.text-align-right { text-align: right !important; }
|
||||
|
||||
.cursor-pointer { cursor: pointer !important; }
|
||||
.cursor-not-allowed { cursor: not-allowed !important; }
|
||||
.cursor-progress { cursor: progress !important; }
|
||||
@ -38,8 +38,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PickupPoint } from '#shared/yandex_pvz'
|
||||
import type { PropType } from 'vue'
|
||||
import type { PickupPoint } from '~/server/shared/types/yandex_pvz'
|
||||
import { defineEmits } from 'vue'
|
||||
|
||||
defineProps<{ filteredPoints: PickupPoint[] }>()
|
||||
@ -59,8 +59,6 @@ const onSelectPoint = (pickupPoint: PickupPoint) => {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.pickup-point-card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { IBspb } from '~/server/shared/types/bspb'
|
||||
import type { BsbpCreateResponse } from '#shared/bsbp_create'
|
||||
import { useMediaQuery } from '@vueuse/core'
|
||||
|
||||
defineProps({
|
||||
@ -73,7 +73,7 @@ const isMobile = useMediaQuery('(max-width: 1280px)', {
|
||||
const { cart, cartSum } = useCart()
|
||||
|
||||
const createOrder = async () => {
|
||||
const { data } = await useFetch<IBspb>('/api/bspb', {
|
||||
const { data } = await useFetch<BsbpCreateResponse>('/api/bsbp_create', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
order: {
|
||||
|
||||
@ -93,8 +93,6 @@ function addToCartBtn() {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.product-description {
|
||||
width: 100%;
|
||||
padding: 30px 30px 0;
|
||||
|
||||
@ -53,11 +53,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PickupPoint } from '#shared/yandex_pvz'
|
||||
import type { LngLatBounds, YMap } from '@yandex/ymaps3-types'
|
||||
import type { YMapLocationRequest } from '@yandex/ymaps3-types/imperative/YMap'
|
||||
import type { YMapClusterer } from '@yandex/ymaps3-types/packages/clusterer'
|
||||
import type { PropType } from 'vue'
|
||||
import type { PickupPoint } from '~/server/shared/types/yandex_pvz'
|
||||
import { IPvzMapFittingTabs, IPvzMapTabs } from '#shared/types'
|
||||
import { useGeolocation, useMediaQuery } from '@vueuse/core'
|
||||
import { computed, defineEmits, shallowRef } from 'vue'
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import type { PickupPoint } from '~/server/shared/types/yandex_pvz'
|
||||
import type { PickupPoint } from '#shared/yandex_pvz'
|
||||
import { createSharedComposable, useMediaQuery, useStorage } from '@vueuse/core'
|
||||
|
||||
export const useCheckout = createSharedComposable(() => {
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
import { createResolver } from '@nuxt/kit'
|
||||
|
||||
const { resolve } = createResolver(import.meta.url)
|
||||
|
||||
export default defineNuxtConfig({
|
||||
ssr: true,
|
||||
compatibilityDate: '2025-05-15',
|
||||
@ -40,4 +44,13 @@ export default defineNuxtConfig({
|
||||
],
|
||||
},
|
||||
},
|
||||
vite: {
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
additionalData: `@use "${resolve('./assets/scss/mixins')}" as *;`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { WooOrderCreateResponse } from '#shared/woo_orders_create'
|
||||
import { useCart } from '~/composables'
|
||||
import PayBlock from '../components/PayBlock.vue'
|
||||
|
||||
@ -27,11 +28,15 @@ const route = useRoute()
|
||||
const { cart, cartRemoveAllItems } = useCart()
|
||||
const { checkoutContacts, checkoutPickupPoint } = useCheckout()
|
||||
|
||||
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
// Зарпос должен быть в админке bsbp, ждём доступов. Текущее решение просто создает order в WooCommerce
|
||||
onMounted(async () => {
|
||||
if (!route?.query?.ID || cart.value.line_items.length === 0)
|
||||
return
|
||||
|
||||
await $fetch('/api/create', {
|
||||
await wait(5000)
|
||||
await useFetch<WooOrderCreateResponse>('/api/woo_orders_create', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
payment_method: 'bacs',
|
||||
@ -58,8 +63,6 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.cart {
|
||||
margin-top: 120px;
|
||||
margin-inline: auto;
|
||||
|
||||
@ -199,8 +199,6 @@ definePageMeta({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.contacts {
|
||||
margin-inline: auto;
|
||||
max-width: 400px;
|
||||
|
||||
@ -89,7 +89,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PickupPoint, YandexPvzResponse } from '~/server/shared/types/yandex_pvz'
|
||||
import type { YandexLocationDetectResponse } from '#shared/yandex_location_detect'
|
||||
import type { YandexPvzPoint, YandexPvzResponse } from '#shared/yandex_pvz'
|
||||
import { IPvzMapFittingTabs, IPvzMapTabs } from '#shared/types'
|
||||
import { useGeolocation, useMediaQuery } from '@vueuse/core'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
@ -128,7 +129,7 @@ onMounted(async () => {
|
||||
const openstreetmap = await response.json()
|
||||
|
||||
// получение geo_id из названию города
|
||||
const { data: yandexLocation } = await useFetch('/api/yandex_location', {
|
||||
const { data: yandexLocation } = await useFetch<YandexLocationDetectResponse>('/api/yandex_location_detect', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
location: openstreetmap?.address?.city,
|
||||
@ -146,7 +147,7 @@ onMounted(async () => {
|
||||
yandexPvz.value = yandexPvzApi.value
|
||||
})
|
||||
|
||||
const filteredPoints = computed<PickupPoint[]>(() => {
|
||||
const filteredPoints = computed<YandexPvzPoint[]>(() => {
|
||||
const points = yandexPvz.value?.points || []
|
||||
const term = searchTerm.value?.toLowerCase() || ''
|
||||
|
||||
@ -178,8 +179,6 @@ definePageMeta({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.delivery {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@ -77,8 +77,6 @@ definePageMeta({
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.summary {
|
||||
max-width: 1200px;
|
||||
margin-inline: auto;
|
||||
|
||||
@ -34,8 +34,6 @@ const router = useRouter()
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.cards-list {
|
||||
padding: 15px;
|
||||
|
||||
|
||||
@ -102,8 +102,6 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@use '~/assets/scss/utils' as *;
|
||||
|
||||
.product {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
38
server/api/bsbp_create.ts
Normal file
38
server/api/bsbp_create.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import type { BsbpCreateRequest, BsbpCreateResponse } from '#shared/bsbp_create'
|
||||
import https from 'node:https'
|
||||
import axios from 'axios'
|
||||
import { defineEventHandler, readBody } from 'h3'
|
||||
|
||||
export default defineEventHandler(async (event): Promise<BsbpCreateResponse | { error: string }> => {
|
||||
const merchantId = import.meta.env.BSPB_MERCHANT_ID!
|
||||
const merchantPassword = import.meta.env.BSPB_MERCHANT_PASSWORD!
|
||||
const apiUrl = import.meta.env.BSPB_API_URL!
|
||||
|
||||
const assetsStorage = useStorage('assets:server')
|
||||
const bspbKey = await assetsStorage.getItem<string>('pgtest_key.key')
|
||||
const bspbCert = await assetsStorage.getItem<string>('pgtest_cer_2025.pem')
|
||||
|
||||
const agent = new https.Agent({
|
||||
key: bspbKey!,
|
||||
cert: bspbCert!,
|
||||
rejectUnauthorized: false,
|
||||
})
|
||||
|
||||
const orderData = await readBody<BsbpCreateRequest>(event)
|
||||
|
||||
try {
|
||||
const response = await axios.post<BsbpCreateResponse>(`${apiUrl}/order`, orderData, {
|
||||
httpsAgent: agent,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Basic ${Buffer.from(`TerminalSys/${merchantId}:${merchantPassword}`).toString('base64')}`,
|
||||
},
|
||||
})
|
||||
|
||||
return response.data
|
||||
}
|
||||
catch (e: any) {
|
||||
return { error: e?.message ?? 'Unknown BSPB error' }
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -1,32 +0,0 @@
|
||||
import https from 'node:https'
|
||||
import axios from 'axios'
|
||||
import { defineEventHandler, readBody } from 'h3'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const merchantId = import.meta.env.BSPB_MERCHANT_ID!
|
||||
const merchantPassword = import.meta.env.BSPB_MERCHANT_PASSWORD!
|
||||
const apiUrl = import.meta.env.BSPB_API_URL!
|
||||
|
||||
const assetsStorage = useStorage('assets:server')
|
||||
|
||||
const bspbKey = await assetsStorage.getItem<string>('pgtest_key.key')
|
||||
const bspbCert = await assetsStorage.getItem<string>('pgtest_cer_2025.pem')
|
||||
|
||||
const agent = new https.Agent({
|
||||
key: bspbKey!,
|
||||
cert: bspbCert!,
|
||||
rejectUnauthorized: false,
|
||||
})
|
||||
|
||||
const orderData = await readBody(event)
|
||||
|
||||
const response = await axios.post(`${apiUrl}/order`, orderData, {
|
||||
httpsAgent: agent,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Basic ${Buffer.from(`TerminalSys/${merchantId}:${merchantPassword}`).toString('base64')}`,
|
||||
},
|
||||
})
|
||||
|
||||
return response?.data || []
|
||||
})
|
||||
@ -1,9 +1,10 @@
|
||||
import type { WooOrderCreateRequest, WooOrderCreateResponse } from '#shared/woo_orders_create'
|
||||
import axios from 'axios'
|
||||
import { defineEventHandler, readBody } from 'h3'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
export default defineEventHandler(async (event): Promise<WooOrderCreateResponse | { error: string }> => {
|
||||
try {
|
||||
const orderData = await readBody(event)
|
||||
const orderData = await readBody<WooOrderCreateRequest>(event)
|
||||
|
||||
const requestUrl = 'https://wp.koptilnya.xyz/wp-json/wc/v3/orders'
|
||||
const consumerKey = 'ck_8b5477a1573ce6038ef1367f25d95cede1de4559'
|
||||
@ -11,7 +12,7 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
const encodedAuth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64')
|
||||
|
||||
const response = await axios.post(requestUrl, orderData, {
|
||||
const response = await axios.post<WooOrderCreateResponse>(requestUrl, orderData, {
|
||||
headers: {
|
||||
'Authorization': `Basic ${encodedAuth}`,
|
||||
'Content-Type': 'application/json',
|
||||
@ -1,13 +1,14 @@
|
||||
import type { YandexLocationDetectRequest, YandexLocationDetectResponse } from '#shared/yandex_location_detect'
|
||||
import axios from 'axios'
|
||||
import { defineEventHandler, readBody } from 'h3'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
export default defineEventHandler(async (event): Promise<YandexLocationDetectResponse | { error: string }> => {
|
||||
try {
|
||||
const data = await readBody(event)
|
||||
const data = await readBody<YandexLocationDetectRequest>(event)
|
||||
const apiUrl = import.meta.env.VITE_YANDEX_B2B_BASE_URL!
|
||||
const token = import.meta.env.VITE_YANDEX_B2B_TOKEN!
|
||||
|
||||
const response = await axios.post(
|
||||
const response = await axios.post<YandexLocationDetectResponse>(
|
||||
`${apiUrl}/location/detect`,
|
||||
{
|
||||
location: data?.location,
|
||||
@ -1,10 +1,10 @@
|
||||
import type { YandexPvzResponse } from '~/server/shared/types/yandex_pvz'
|
||||
import type { YandexPvzRequest, YandexPvzResponse } from '#shared/yandex_pvz'
|
||||
import axios from 'axios'
|
||||
import { defineEventHandler, readBody } from 'h3'
|
||||
|
||||
export default defineEventHandler(async (event): Promise<YandexPvzResponse | { error: string }> => {
|
||||
try {
|
||||
const data = await readBody(event)
|
||||
const data = await readBody<YandexPvzRequest>(event)
|
||||
const apiUrl = import.meta.env.VITE_YANDEX_B2B_BASE_URL!
|
||||
const token = import.meta.env.VITE_YANDEX_B2B_TOKEN!
|
||||
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
export interface IBspb {
|
||||
order: {
|
||||
id: number
|
||||
hppUrl: string
|
||||
password: string
|
||||
accessToken: string
|
||||
status: string
|
||||
cvv2AuthStatus: string
|
||||
}
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
export interface GeoPosition {
|
||||
latitude: number
|
||||
longitude: number
|
||||
}
|
||||
|
||||
export interface PvzAddress {
|
||||
apartment: string
|
||||
building: string
|
||||
comment: string
|
||||
country: string
|
||||
full_address: string
|
||||
geoId: number
|
||||
house: string
|
||||
housing: string
|
||||
locality: string
|
||||
postal_code: string
|
||||
region: string
|
||||
street: string
|
||||
subRegion: string
|
||||
}
|
||||
|
||||
export interface Contact {
|
||||
phone: string
|
||||
}
|
||||
|
||||
export interface TimeObject {
|
||||
hours: number
|
||||
minutes: number
|
||||
}
|
||||
|
||||
export interface ScheduleRestriction {
|
||||
days: number[]
|
||||
time_from: TimeObject
|
||||
time_to: TimeObject
|
||||
}
|
||||
|
||||
export interface Schedule {
|
||||
time_zone: number
|
||||
restrictions: ScheduleRestriction[]
|
||||
}
|
||||
|
||||
export interface PickupServices {
|
||||
is_fitting_allowed: boolean
|
||||
is_partial_refuse_allowed: boolean
|
||||
is_paperless_pickup_allowed: boolean
|
||||
is_unboxing_allowed: boolean
|
||||
}
|
||||
|
||||
export interface PickupPoint {
|
||||
id: string
|
||||
operator_station_id: string
|
||||
operator_id: string
|
||||
name: string
|
||||
type: 'pickup_point'
|
||||
address: PvzAddress
|
||||
position: GeoPosition
|
||||
instruction: string
|
||||
available_for_dropoff: boolean
|
||||
available_for_c2c_dropoff: boolean
|
||||
contact: Contact
|
||||
schedule: Schedule
|
||||
pickup_services: PickupServices
|
||||
payment_methods: string[]
|
||||
is_dark_store: boolean
|
||||
is_market_partner: boolean
|
||||
is_post_office: boolean
|
||||
is_yandex_branded: boolean
|
||||
dayoffs: any[]
|
||||
deactivation_date: string | null
|
||||
deactivation_date_predicted_debt: string | null
|
||||
}
|
||||
|
||||
export interface YandexPvzResponse extends PickupPoint {
|
||||
points: PickupPoint[]
|
||||
}
|
||||
23
shared/bsbp_create.ts
Normal file
23
shared/bsbp_create.ts
Normal file
@ -0,0 +1,23 @@
|
||||
export interface BsbpOrder {
|
||||
typeRid: string
|
||||
amount: number
|
||||
currency: string
|
||||
title?: string
|
||||
description?: string
|
||||
hppRedirectUrl: string
|
||||
}
|
||||
|
||||
export interface BsbpCreateRequest {
|
||||
order: BsbpOrder
|
||||
}
|
||||
|
||||
export interface BsbpCreateResponse {
|
||||
order: {
|
||||
id: number
|
||||
hppUrl: string
|
||||
password: string
|
||||
accessToken: string
|
||||
status: string
|
||||
cvv2AuthStatus: string
|
||||
}
|
||||
}
|
||||
160
shared/woo_orders_create.ts
Normal file
160
shared/woo_orders_create.ts
Normal file
@ -0,0 +1,160 @@
|
||||
// ------------------------------------
|
||||
// REQUEST: Create WooCommerce Order
|
||||
// ------------------------------------
|
||||
export interface WooOrderCreateBilling {
|
||||
first_name: string
|
||||
last_name: string
|
||||
address_1: string
|
||||
address_2: string
|
||||
city: string
|
||||
state: string
|
||||
postcode: string
|
||||
country: string
|
||||
email: string
|
||||
phone: string
|
||||
}
|
||||
|
||||
export interface WooOrderCreateShipping {
|
||||
first_name: string
|
||||
last_name: string
|
||||
address_1: string
|
||||
address_2: string
|
||||
city: string
|
||||
state: string
|
||||
postcode: string
|
||||
country: string
|
||||
}
|
||||
|
||||
export interface WooOrderCreateLineItem {
|
||||
product_id: number
|
||||
variation_id?: number
|
||||
quantity: number
|
||||
}
|
||||
|
||||
export interface WooOrderCreateShippingLine {
|
||||
method_id: string
|
||||
method_title: string
|
||||
total: string
|
||||
}
|
||||
|
||||
export interface WooOrderCreateRequest {
|
||||
payment_method: string
|
||||
payment_method_title: string
|
||||
set_paid: boolean
|
||||
billing: WooOrderCreateBilling
|
||||
shipping: WooOrderCreateShipping
|
||||
line_items: WooOrderCreateLineItem[]
|
||||
shipping_lines: WooOrderCreateShippingLine[]
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
// RESPONSE: WooCommerce Order
|
||||
// ------------------------------------
|
||||
export interface WooMetaData {
|
||||
id: number
|
||||
key: string
|
||||
value: any
|
||||
}
|
||||
|
||||
export interface WooTaxItem {
|
||||
id: number
|
||||
total: string
|
||||
subtotal: string
|
||||
}
|
||||
|
||||
export interface WooLineItem {
|
||||
id: number
|
||||
name: string
|
||||
product_id: number
|
||||
variation_id: number
|
||||
quantity: number
|
||||
tax_class: string
|
||||
subtotal: string
|
||||
subtotal_tax: string
|
||||
total: string
|
||||
total_tax: string
|
||||
taxes: WooTaxItem[]
|
||||
meta_data: WooMetaData[]
|
||||
sku: string
|
||||
price: number
|
||||
}
|
||||
|
||||
export interface WooTaxLine {
|
||||
id: number
|
||||
rate_code: string
|
||||
rate_id: number
|
||||
label: string
|
||||
compound: boolean
|
||||
tax_total: string
|
||||
shipping_tax_total: string
|
||||
meta_data: WooMetaData[]
|
||||
}
|
||||
|
||||
export interface WooShippingLine {
|
||||
id: number
|
||||
method_title: string
|
||||
method_id: string
|
||||
total: string
|
||||
total_tax: string
|
||||
taxes: WooTaxItem[]
|
||||
meta_data: WooMetaData[]
|
||||
}
|
||||
|
||||
export interface WooLink {
|
||||
href: string
|
||||
}
|
||||
|
||||
export interface WooOrderLinks {
|
||||
self: WooLink[]
|
||||
collection: WooLink[]
|
||||
}
|
||||
|
||||
export interface WooOrderCreateResponse {
|
||||
id: number
|
||||
parent_id: number
|
||||
number: string
|
||||
order_key: string
|
||||
created_via: string
|
||||
version: string
|
||||
status: string
|
||||
currency: string
|
||||
date_created: string
|
||||
date_created_gmt: string
|
||||
date_modified: string
|
||||
date_modified_gmt: string
|
||||
discount_total: string
|
||||
discount_tax: string
|
||||
shipping_total: string
|
||||
shipping_tax: string
|
||||
cart_tax: string
|
||||
total: string
|
||||
total_tax: string
|
||||
prices_include_tax: boolean
|
||||
customer_id: number
|
||||
customer_ip_address: string
|
||||
customer_user_agent: string
|
||||
customer_note: string
|
||||
|
||||
billing: WooOrderCreateBilling
|
||||
shipping: WooOrderCreateShipping
|
||||
|
||||
payment_method: string
|
||||
payment_method_title: string
|
||||
transaction_id: string
|
||||
date_paid: string | null
|
||||
date_paid_gmt: string | null
|
||||
date_completed: string | null
|
||||
date_completed_gmt: string | null
|
||||
cart_hash: string
|
||||
|
||||
meta_data: WooMetaData[]
|
||||
|
||||
line_items: WooLineItem[]
|
||||
tax_lines: WooTaxLine[]
|
||||
shipping_lines: WooShippingLine[]
|
||||
fee_lines: any[]
|
||||
coupon_lines: any[]
|
||||
refunds: any[]
|
||||
|
||||
_links: WooOrderLinks
|
||||
}
|
||||
12
shared/yandex_location_detect.ts
Normal file
12
shared/yandex_location_detect.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export interface YandexLocationVariantDetect {
|
||||
geo_id: number
|
||||
address: string
|
||||
}
|
||||
|
||||
export interface YandexLocationDetectResponse {
|
||||
variants: YandexLocationVariantDetect[]
|
||||
}
|
||||
|
||||
export interface YandexLocationDetectRequest {
|
||||
location: string
|
||||
}
|
||||
127
shared/yandex_pvz.ts
Normal file
127
shared/yandex_pvz.ts
Normal file
@ -0,0 +1,127 @@
|
||||
// -----------------------------
|
||||
// REQUEST
|
||||
// -----------------------------
|
||||
export type YandexPvzPaymentMethod = 'already_paid'
|
||||
|
||||
export interface YandexPvzCoordinateRange {
|
||||
from: number
|
||||
to: number
|
||||
}
|
||||
|
||||
export interface YandexPvzPickupServicesRequest {
|
||||
is_fitting_allowed: boolean
|
||||
is_partial_refuse_allowed: boolean
|
||||
is_paperless_pickup_allowed: boolean
|
||||
is_unboxing_allowed: boolean
|
||||
}
|
||||
|
||||
export interface YandexPvzRequest {
|
||||
pickup_point_ids?: string[]
|
||||
geo_id?: number
|
||||
longitude?: YandexPvzCoordinateRange
|
||||
latitude?: YandexPvzCoordinateRange
|
||||
type?: 'pickup_point'
|
||||
payment_method?: YandexPvzPaymentMethod
|
||||
available_for_dropoff?: boolean
|
||||
is_yandex_branded?: boolean
|
||||
is_not_branded_partner_station?: boolean
|
||||
is_post_office?: boolean
|
||||
payment_methods?: YandexPvzPaymentMethod[]
|
||||
pickup_services?: YandexPvzPickupServicesRequest
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// RESPONSE
|
||||
// -----------------------------
|
||||
export interface YandexPvzPosition {
|
||||
latitude: number
|
||||
longitude: number
|
||||
}
|
||||
|
||||
export interface YandexPvzAddress {
|
||||
geoId: string
|
||||
country: string
|
||||
region: string
|
||||
subRegion: string
|
||||
locality: string
|
||||
street: string
|
||||
house: string
|
||||
housing: string
|
||||
apartment: string
|
||||
building: string
|
||||
comment: string
|
||||
full_address: string
|
||||
postal_code: string
|
||||
}
|
||||
|
||||
export interface YandexPvzContact {
|
||||
first_name: string
|
||||
last_name: string
|
||||
patronymic: string
|
||||
phone: string
|
||||
email: string
|
||||
}
|
||||
|
||||
export interface YandexPvzTimeObject {
|
||||
hours: number
|
||||
minutes: number
|
||||
}
|
||||
|
||||
export interface YandexPvzScheduleRestriction {
|
||||
days: number[]
|
||||
time_from: YandexPvzTimeObject
|
||||
time_to: YandexPvzTimeObject
|
||||
}
|
||||
|
||||
export interface YandexPvzSchedule {
|
||||
time_zone: number
|
||||
restrictions: YandexPvzScheduleRestriction[]
|
||||
}
|
||||
|
||||
export interface YandexPvzPickupServices {
|
||||
is_fitting_allowed: boolean
|
||||
is_partial_refuse_allowed: boolean
|
||||
is_paperless_pickup_allowed: boolean
|
||||
is_unboxing_allowed: boolean
|
||||
}
|
||||
|
||||
export interface YandexPvzDayoff {
|
||||
date: string
|
||||
date_utc: string
|
||||
}
|
||||
|
||||
export interface YandexPvzDeactivation {
|
||||
deactivation_date_predicted_debt: boolean
|
||||
available_for_dropoff: boolean
|
||||
available_for_c2c_dropoff: boolean
|
||||
}
|
||||
|
||||
export interface YandexPvzPoint {
|
||||
ID: string
|
||||
operator_station_id: string
|
||||
name: string
|
||||
type: 'pickup_point'
|
||||
|
||||
position: YandexPvzPosition
|
||||
address: YandexPvzAddress
|
||||
instruction: string
|
||||
|
||||
payment_methods: YandexPvzPaymentMethod[]
|
||||
contact: YandexPvzContact
|
||||
schedule: YandexPvzSchedule
|
||||
|
||||
is_yandex_branded: boolean
|
||||
is_market_partner: boolean
|
||||
is_dark_store: boolean
|
||||
is_post_office: boolean
|
||||
|
||||
pickup_services: YandexPvzPickupServices
|
||||
|
||||
deactivation_date: YandexPvzDeactivation
|
||||
|
||||
dayoffs: YandexPvzDayoff[]
|
||||
}
|
||||
|
||||
export interface YandexPvzResponse {
|
||||
points: YandexPvzPoint[]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user