shipx.tsNowy plik, 19 linii
1const API = process.env.SHIPX_URL ?? 'https://sandbox-api-shipx-pl.easypack24.net';2const TOKEN = process.env.SHIPX_TOKEN ?? '';3const ORG = process.env.SHIPX_ORG ?? '';4 5export async function shipx<T>(method: string, path: string, body?: unknown): Promise<T> {6 const response = await fetch(`${API}${path}`, {7 method,8 headers: {9 Authorization: `Bearer ${TOKEN}`,10 'Content-Type': 'application/json',11 'X-User-Agent': 'sklep-example',12 },13 body: body === undefined ? undefined : JSON.stringify(body),14 });15 if (!response.ok) {16 throw new Error(`ShipX ${method} ${path}: ${response.status} ${await response.text()}`);17 }18 return response.json() as Promise<T>;19}
shipx.tsZmiana w pliku: 4 linie
1interface Organization { id: number; name: string; services: string[] }2 3const org = await shipx<Organization>('GET', `/v1/organizations/${ORG}`);4console.log(org.name, org.services);5
shipx.tsZmiana w pliku: 11 linii
1interface Shipment { id: number; status: string; tracking_number: string | null }2 3export const lockerShipment = (order: { email: string; phone: string; point: string; ref: string }) =>4 shipx<Shipment>('POST', `/v1/organizations/${ORG}/shipments`, {5 receiver: { email: order.email, phone: order.phone },6 parcels: { template: 'small' },7 custom_attributes: { target_point: order.point, sending_method: 'parcel_locker' },8 service: 'inpost_locker_standard',9 reference: order.ref,10 });11 12const created = await lockerShipment({13 email: 'klient@example.com', phone: '888000000', point: 'KRA010', ref: 'zamowienie-1042',14});15
shipx.tsZmiana w pliku: 17 linii
1export const courierShipment = (order: CourierOrder) =>2 shipx<Shipment>('POST', `/v1/organizations/${ORG}/shipments`, {3 receiver: {4 first_name: order.firstName,5 last_name: order.lastName,6 email: order.email,7 phone: order.phone,8 address: {9 street: order.street,10 building_number: order.building,11 city: order.city,12 post_code: order.postCode,13 country_code: 'PL',14 },15 },16 parcels: [{17 dimensions: { length: '300', width: '200', height: '100', unit: 'mm' },18 weight: { amount: '2', unit: 'kg' },19 }],20 service: 'inpost_courier_standard',21 reference: order.ref,22 });
shipx.tsZmiana w pliku: 6 linii
1export async function waitForConfirmed(id: number): Promise<Shipment> {2 for (let attempt = 0; attempt < 30; attempt++) {3 const shipment = await shipx<Shipment>('GET', `/v1/shipments/${id}`);4 if (shipment.status === 'confirmed' || shipment.tracking_number) return shipment;5 await new Promise(resolve => setTimeout(resolve, 2000));6 }7 throw new Error(`Przesyłka ${id} nie została opłacona`);8}
shipx.tsZmiana w pliku: 8 linii
1import { writeFile } from 'node:fs/promises';2 3export async function label(id: number): Promise<Buffer> {4 const response = await fetch(`${API}/v1/shipments/${id}/label?format=pdf&type=A6`, {5 headers: { Authorization: `Bearer ${TOKEN}` },6 });7 if (!response.ok) throw new Error(`Etykieta ${id}: ${response.status} ${await response.text()}`);8 return Buffer.from(await response.arrayBuffer());9}10 11const confirmed = await waitForConfirmed(created.id);12await writeFile(`etykieta-${confirmed.tracking_number}.pdf`, await label(confirmed.id));
webhook.tsNowy plik, 15 linii
1import express from 'express';2 3const app = express();4 56app.get('/inpost/webhook', (_req, res) => res.sendStatus(200));7 8app.post('/inpost/webhook', express.json(), async (req, res) => {9 res.sendStatus(200); 10 const { event, payload } = req.body as { event: string; payload: { shipment_id: number } };11 if (event !== 'shipment_status_changed' && event !== 'shipment_confirmed') return;12 13 const shipment = await shipx<Shipment>('GET', `/v1/shipments/${payload.shipment_id}`);14 await saveShipmentStatus(shipment.id, shipment.status, shipment.tracking_number);15});
statusy.tsNowy plik, 5 linii
1const response = await fetch(`${API}/v1/statuses?lang=pl_PL`); 2const { items } = await response.json() as { items: { name: string; title: string; description: string }[] };3const titles = new Map(items.map(status => [status.name, status.title]));4 5titles.get('ready_to_pickup');