Menghasilkan tanda terima PDF setelah pesanan dibuat
Dalam contoh ini, kita melakukan pemesanan, membacanya kembali dengan data harga lengkap dan menyusun tanda terima yang dapat dicetak yang dapat dirender sebagai PDF di klien.
✅ Tujuan skenario:
- Melakukan pemesanan dan membacanya kembali dengan Orders.getOrderByMarkerAndId()
- Menyusun tanda terima dari produk pesanan, total dan metode pembayaran
- Merender tanda terima sebagai PDF yang dapat diunduh di klien
✅ Apa yang Anda butuhkan:
- PROJECT_URL dan APP_TOKEN yang valid untuk otentikasi dengan API OneEntry.
- Pengguna terdaftar
- Penyimpanan pesanan yang dikonfigurasi dengan penanda "orders"
📌 Penting:
- Merender PDF bukan bagian dari SDK OneEntry — gunakan pustaka sisi klien apa pun (jsPDF ditunjukkan di sini). SDK hanya menyediakan data pesanan.
- totalSum kembali sebagai string dan mata uang sering kali kosong — format dengan Number(totalSum).toFixed(2) dan jangan pernah mengkodekan simbol mata uang secara langsung.
- Contoh-contoh ini tidak mencakup penanganan kesalahan.
- Anda dapat mengelola kesalahan menggunakan blok try-catch atau dengan menggunakan konstruksi seperti await Promise.catch((error) => error).
📚 Lihat di dokumentasi:
📦 Referensi SDK:
Coba secara langsung
Jalankan metode ini secara interaktif di JS SDK sandbox — sambungkan Project URL dan App Token Anda pada kunjungan pertama, lalu buka:
- Menghasilkan tanda terima PDF setelah pesanan dibuat — Dalam contoh ini, kita melakukan pemesanan, membacanya kembali dengan data harga lengkap dan menyusun tanda terima yang dapat dicetak yang dapat dirender sebagai PDF di klien.
Skenario
1. Impor defineOneEntry dari SDK dan definisikan PROJECT_URL dan APP_TOKEN
Contoh:
import { defineOneEntry } from 'oneentry';
const PROJECT_URL = 'your-project-url';
const APP_TOKEN = 'your-app-token';
2. Membuat klien API dengan defineOneEntry()
Contoh:
const { AuthProvider, Orders } = defineOneEntry(PROJECT_URL, {
token: APP_TOKEN,
});
3. Otorisasi pengguna dengan AuthProvider.auth()
Contoh:
const authData = [
{ marker: 'email_reg', value: 'your-email' },
{ marker: 'password_reg', value: 'your-password' },
];
const user = await AuthProvider.auth('email', { authData });
console.log(user);
Hasil:
{
"userIdentifier": "kvasssukr.net@gmail.com",
"authProviderIdentifier": "email",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR...pZCI6MTYsImF1dGhQ"
"refreshToken": "1745494429101-...-2834edf8"
}
4. Lakukan pemesanan dengan Orders.createOrder()
Data:
{
"formIdentifier": "order",
"paymentAccountIdentifier": "cash",
"formData": {
"en_US": [
{
"type": "string",
"marker": "name",
"value": "Christina Thomas"
}
]
},
"products": [
{
"productId": 15,
"quantity": 1
}
]
}
Contoh:
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);
}
Hasil:
{
"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. Bacalah pesanan yang telah dibuat kembali dengan Orders.getOrderByMarkerAndId()
Contoh:
// 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);
}
Hasil:
{
"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. Susun tanda terima dari data pesanan
Contoh:
// 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);
Hasil:
{
"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. Render tanda terima sebagai PDF di klien (misalnya dengan jsPDF)
Contoh:
/*
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`);
*/
Contoh akhir
// 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`);
*/