إنشاء إيصال PDF بعد تقديم الطلب
في هذا المثال، نقوم بتقديم طلب، نقرأه مرة أخرى مع بيانات التسعير الكاملة ونقوم بتجميع إيصال قابل للطباعة يمكن عرضه كملف PDF على العميل.
✅ هدف السيناريو:
- تقديم طلب وقراءته مرة أخرى باستخدام Orders.getOrderByMarkerAndId()
- تجميع إيصال من منتجات الطلب، والمجموعات وطريقة الدفع
- عرض الإيصال كملف PDF قابل للتنزيل على العميل
✅ ما تحتاجه:
- PROJECT_URL و APP_TOKEN صالحين للمصادقة مع واجهة برمجة التطبيقات OneEntry.
- مستخدم مسجل
- تخزين الطلبات المكون مع علامة "orders"
📌 مهم:
- عرض PDF ليس جزءًا من SDK الخاص بـ OneEntry — استخدم أي مكتبة على جانب العميل (jsPDF موضحة هنا). يوفر SDK فقط بيانات الطلب.
- totalSum يعود كسلسلة وغالبًا ما تكون العملة فارغة — قم بتنسيقها باستخدام Number(totalSum).toFixed(2) ولا تقم بتشفير رمز العملة.
- هذه الأمثلة لا تتضمن معالجة الأخطاء.
- يمكنك إدارة الأخطاء باستخدام كتلة try-catch أو من خلال استخدام بناء مثل await Promise.catch((error) => error).
📚 انظر في الوثائق:
📦 مرجع SDK:
جربها مباشرة
قم بتشغيل هذه الطريقة بشكل تفاعلي في JS SDK sandbox — قم بتوصيل Project URL و App Token عند الزيارة الأولى، ثم افتح:
- إنشاء إيصال PDF بعد تقديم الطلب — في هذا المثال، نقوم بتقديم طلب، نقرأه مرة أخرى مع بيانات التسعير الكاملة ونقوم بتجميع إيصال قابل للطباعة يمكن عرضه كملف PDF على العميل.
السيناريو
1. استيراد defineOneEntry من SDK وتعريف PROJECT_URL و APP_TOKEN
مثال:
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
2. إنشاء عميل API باستخدام defineOneEntry()
مثال:
const { AuthProvider, Orders } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
3. مصادقة المستخدم باستخدام AuthProvider.auth()
مثال:
const authData = [
{ marker: 'email_reg', value: 'your-email' },
{ marker: 'password_reg', value: 'your-password' },
];
const user = await AuthProvider.auth('email', { authData });
console.log(user);
النتيجة:
{
"userIdentifier": "kvasssukr.net@gmail.com",
"authProviderIdentifier": "email",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR...pZCI6MTYsImF1dGhQ"
"refreshToken": "1745494429101-...-2834edf8"
}
4. تقديم الطلب باستخدام Orders.createOrder()
البيانات:
{
"formIdentifier": "order",
"paymentAccountIdentifier": "cash",
"formData": {
"en_US": [
{
"type": "string",
"marker": "name",
"value": "Christina Thomas"
}
]
},
"products": [
{
"productId": 15,
"quantity": 1
}
]
}
مثال:
const body = {
formIdentifier: 'order',
paymentAccountIdentifier: 'cash',
formData: [{ type: 'string', marker: 'name', value: 'Christina Thomas' }],
products: [{ productId: 15, quantity: 1 }],
};
const created = await Orders.createOrder('orders', body as any);
if ('statusCode' in created) {
throw new Error(created.message);
}
النتيجة:
{
"id": 127,
"formIdentifier": "order",
"paymentAccountIdentifier": "cash",
"formData": [
{
"type": "string",
"marker": "name",
"value": "Christina Thomas"
}
],
"products": [
{
"productId": 15,
"quantity": 1
}
],
"currency": "USD",
"totalSum": 400,
"bonusApplied": 0,
"totalDue": 400,
"discountConfig": {
"orderDiscounts": [],
"productDiscounts": [],
"coupon": null,
"settings": {
"allowStacking": false,
"maxDiscountValue": null,
"allowGiftStacking": false,
"maxBonusPaymentPercent": null,
"minBonusAmount": null,
"minOrderAmountForBonus": null,
"giftRefundPolicy": "KEEP_GIFT"
},
"additionalDiscountsMarkers": [],
"totalRaw": 400,
"totalSumWithDiscount": 400,
"excludedGiftProductIds": [],
"bonus": {
"availableBalance": 0,
"maxBonusDiscount": 0,
"minBonusAmount": null,
"minOrderAmountForBonus": null,
"bonusApplied": 0
},
"bonusApplied": 0,
"totalDue": 400
},
"statusIdentifier": "upcoming",
"statusLocalizeInfos": {
"title": "Upcoming"
},
"createdDate": "2026-06-06T12:04:52.459Z"
}
5. قراءة الطلب المقدم مرة أخرى باستخدام Orders.getOrderByMarkerAndId()
مثال:
// This returns the full order: products with titles/prices, totalSum, currency,
// payment method and status — everything the receipt needs.
const order = await Orders.getOrderByMarkerAndId('orders', created.id);
if ('statusCode' in order) {
throw new Error(order.message);
}
النتيجة:
{
"id": 127,
"storageId": 1,
"createdDate": "2026-06-06T12:04:52.459Z",
"statusIdentifier": "upcoming",
"statusLocalizeInfos": {
"title": "Upcoming"
},
"formIdentifier": "order",
"formData": [
{
"type": "string",
"marker": "name",
"value": "Christina Thomas"
}
],
"attributeSetIdentifier": "order",
"paymentStrategy": "once",
"totalSum": "400",
"totalSumRaw": "400",
"currency": "USD",
"paymentAccountIdentifier": "cash",
"paymentAccountLocalizeInfos": {
"title": "Cash"
},
"products": [
{
"id": 15,
"title": "Orange ball",
"sku": null,
"previewImage": "[]",
"price": 400,
"quantity": 1,
"isGift": false
}
],
"paymentUrl": null,
"discountConfig": {
"orderDiscounts": [],
"productDiscounts": [],
"coupon": null,
"settings": {
"allowStacking": false,
"maxDiscountValue": null,
"allowGiftStacking": false,
"maxBonusPaymentPercent": null,
"minBonusAmount": null,
"minOrderAmountForBonus": null,
"giftRefundPolicy": "KEEP_GIFT"
},
"additionalDiscountsMarkers": [],
"totalRaw": 400,
"totalSumWithDiscount": 400,
"excludedGiftProductIds": [],
"bonus": {
"availableBalance": 0,
"maxBonusDiscount": 0,
"minBonusAmount": null,
"minOrderAmountForBonus": null,
"bonusApplied": 0
},
"bonusApplied": 0,
"totalDue": 400
},
"isPartial": false,
"isCompleted": null,
"split": {
"completed": false,
"partial": false,
"stages": [
{
"marker": "default",
"sessionId": null,
"productId": 15,
"title": "Default",
"value": 400,
"status": "planned"
}
]
}
}
6. تجميع الإيصال من بيانات الطلب
مثال:
// currency is frequently an empty string — fall back to '' instead of hardcoding '$'.
const currency = order.currency || '';
// Order status is only a marker; its title is project-specific. Prefer the
// localized title from the API, then a client map, then the raw marker.
const STATUS_LABELS: Record<string, string> = {
inProgress: 'In progress',
completed: 'Completed',
};
const receipt = {
orderId: order.id,
// createdDate is an ISO string returned by the API.
date: new Date(order.createdDate).toLocaleString(),
status:
order.statusLocalizeInfos?.title ??
STATUS_LABELS[order.statusIdentifier ?? ''] ??
order.statusIdentifier,
// paymentAccountLocalizeInfos.title is the human label; fall back to the marker.
payment: order.paymentAccountLocalizeInfos?.title || order.paymentAccountIdentifier,
items: order.products.map((p) => ({
title: p.title,
quantity: p.quantity,
price: `${currency}${p.price.toFixed(2)}`,
lineTotal: `${currency}${(p.price * p.quantity).toFixed(2)}`,
})),
// totalSum is a string ("300.00") — convert before formatting.
total: `${currency}${Number(order.totalSum).toFixed(2)}`,
};
console.log(receipt);
النتيجة:
{
"orderId": 127,
"date": "06.06.2026, 15:04:52",
"status": "Upcoming",
"payment": "Cash",
"items": [
{
"title": "Orange ball",
"quantity": 1,
"price": "USD400.00",
"lineTotal": "USD400.00"
}
],
"total": "USD400.00"
}
7. عرض الإيصال كملف PDF على العميل (على سبيل المثال باستخدام jsPDF)
مثال:
/*
import { jsPDF } from 'jspdf';
const doc = new jsPDF();
doc.setFontSize(16);
doc.text(`Receipt #${receipt.orderId}`, 14, 20);
doc.setFontSize(11);
doc.text(`Date: ${receipt.date}`, 14, 30);
doc.text(`Status: ${receipt.status}`, 14, 37);
doc.text(`Payment: ${receipt.payment}`, 14, 44);
let y = 58;
receipt.items.forEach((item) => {
doc.text(`${item.quantity} × ${item.title}`, 14, y);
doc.text(item.lineTotal, 196, y, { align: 'right' });
y += 7;
});
doc.setFontSize(13);
doc.text(`Total: ${receipt.total}`, 196, y + 8, { align: 'right' });
doc.save(`receipt-${receipt.orderId}.pdf`);
*/
المثال النهائي
// 1. Import defineOneEntry from SDK and define PROJECT_URL and APP_TOKEN
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
// 2. Creating an API client with [defineOneEntry()](/docs/index/#Installation)
const { AuthProvider, Orders } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
// 3. User authorization with [AuthProvider.auth()](/docs/auth-provider/auth)
const authData = [
{ marker: 'email_reg', value: 'your-email' },
{ marker: 'password_reg', value: 'your-password' },
];
const user = await AuthProvider.auth('email', { authData });
console.log(user);
// 4. Place the order with [Orders.createOrder()](/docs/orders/createOrder)
const body = {
formIdentifier: 'order',
paymentAccountIdentifier: 'cash',
formData: [{ type: 'string', marker: 'name', value: 'Christina Thomas' }],
products: [{ productId: 15, quantity: 1 }],
};
const created = await Orders.createOrder('orders', body as any);
if ('statusCode' in created) {
throw new Error(created.message);
}
// 5. Read the placed order back with [Orders.getOrderByMarkerAndId()](/docs/orders/getOrderByMarkerAndId)
// This returns the full order: products with titles/prices, totalSum, currency,
// payment method and status — everything the receipt needs.
const order = await Orders.getOrderByMarkerAndId('orders', created.id);
if ('statusCode' in order) {
throw new Error(order.message);
}
// 6. Assemble the receipt from the order data
// currency is frequently an empty string — fall back to '' instead of hardcoding '$'.
const currency = order.currency || '';
// Order status is only a marker; its title is project-specific. Prefer the
// localized title from the API, then a client map, then the raw marker.
const STATUS_LABELS: Record<string, string> = {
inProgress: 'In progress',
completed: 'Completed',
};
const receipt = {
orderId: order.id,
// createdDate is an ISO string returned by the API.
date: new Date(order.createdDate).toLocaleString(),
status:
order.statusLocalizeInfos?.title ??
STATUS_LABELS[order.statusIdentifier ?? ''] ??
order.statusIdentifier,
// paymentAccountLocalizeInfos.title is the human label; fall back to the marker.
payment: order.paymentAccountLocalizeInfos?.title || order.paymentAccountIdentifier,
items: order.products.map((p) => ({
title: p.title,
quantity: p.quantity,
price: `${currency}${p.price.toFixed(2)}`,
lineTotal: `${currency}${(p.price * p.quantity).toFixed(2)}`,
})),
// totalSum is a string ("300.00") — convert before formatting.
total: `${currency}${Number(order.totalSum).toFixed(2)}`,
};
console.log(receipt);
// 7. Render the receipt as a PDF on the client (e.g. with jsPDF)
/*
import { jsPDF } from 'jspdf';
const doc = new jsPDF();
doc.setFontSize(16);
doc.text(`Receipt #${receipt.orderId}`, 14, 20);
doc.setFontSize(11);
doc.text(`Date: ${receipt.date}`, 14, 30);
doc.text(`Status: ${receipt.status}`, 14, 37);
doc.text(`Payment: ${receipt.payment}`, 14, 44);
let y = 58;
receipt.items.forEach((item) => {
doc.text(`${item.quantity} × ${item.title}`, 14, y);
doc.text(item.lineTotal, 196, y, { align: 'right' });
y += 7;
});
doc.setFontSize(13);
doc.text(`Total: ${receipt.total}`, 196, y + 8, { align: 'right' });
doc.save(`receipt-${receipt.orderId}.pdf`);
*/