restapi-laravel maintained by biteslote
biteslote Laravel Connector
Laravel integration for the biteslote POS connector API. It solves the core problem of any storefront ↔ POS link: your website's product IDs and names never match the POS menu-item IDs. Orders are translated through a mapping table before they reach the POS, so the right items always hit the kitchen.
Built on top of biteslote/restapi-sdk.
Website order ──> ProductMapper (biteslote_product_map) ──> POS /v1/orders
(local id 482) local 482 → pos_item 1071 { items:[{id:1071,...}] }
What you get
biteslote_product_map— the authoritative local-product → POS-item link.biteslote_pos_items— a synced snapshot of the POS catalog for building a mapping UI and matching by SKU.ProductMapper— translates a cart to POS line items, or throwsUnmappedProductsExceptionlisting exactly which products aren't mapped.OrderForwarder— maps + forwards a cart to the POS, idempotently.CatalogSync+php artisan biteslote:sync-catalog— pull the catalog and auto-map by SKU.- Webhook receiver — verified inbound POS webhooks re-dispatched as the
PosWebhookReceivedevent so you can sync status back to your order.
Install
composer require biteslote/restapi-laravel
php artisan vendor:publish --tag=biteslote-connector-config
php artisan migrate
Credentials live in the SDK config (config/biteslote-restapi.php):
BITESLOTE_API_URL=https://shop.example.com/api/application-integration/v1
BITESLOTE_API_KEY=rk_live_xxxxxxxx
# this package
BITESLOTE_BRANCH_ID=12 # optional; the key usually already scopes a branch
BITESLOTE_ORDER_TYPE=delivery
BITESLOTE_WEBHOOK_SECRET=whsec_... # the endpoint secret you set on the POS
1. Map your products
Sync the POS catalog and let SKU matches link themselves:
php artisan biteslote:sync-catalog
Seed your storefront products (id + sku) into biteslote_product_map and run the
command — anything with a matching SKU is linked automatically. Map the rest in
your own admin screen:
use Biteslote\Connector\Models\ProductMap;
ProductMap::link($localProduct->id, $posItemId, $branchId, [
'local_sku' => $localProduct->sku,
'pos_name' => $posItemName,
]);
2. Forward an order
use Biteslote\Connector\Services\OrderForwarder;
use Biteslote\Connector\Exceptions\UnmappedProductsException;
try {
$posOrder = app(OrderForwarder::class)->forward([
'reference' => $order->id, // used as the idempotency key
'order_type' => 'delivery',
'note' => $order->notes,
'items' => $order->lines->map(fn ($l) => [
'product_id' => $l->product_id, // YOUR id — translated for you
'quantity' => $l->qty,
'note' => $l->note,
])->all(),
'customer' => [
'name' => $order->customer_name,
'phone' => $order->customer_phone,
'email' => $order->customer_email,
],
]);
// $posOrder['id'] is the POS order id — store it on your order.
} catch (UnmappedProductsException $e) {
// $e->localProductIds — block checkout / alert an admin
}
Retrying with the same reference returns the same POS order (idempotent), so a
double-submit never creates two orders.
3. Sync status back
Register the webhook endpoint on the POS (API & Integrations → Webhooks) pointing
to https://your-site.com/biteslote/webhook with events order.created,
order.status_changed, then listen:
use Biteslote\Connector\Events\PosWebhookReceived;
Event::listen(function (PosWebhookReceived $e) {
if ($e->type === 'order.status_changed') {
Order::where('pos_order_id', $e->orderId())->update(['status' => $e->status()]);
}
});
Why a mapping table (not name matching)
- Merchant can rename / re-ID products on either side without breaking orders.
- Unmapped lines fail loudly with the offending IDs — never a silent wrong item.
- Per-product, so Woo + Shopify + this Laravel site can each keep their own map.