bored-programmers/laravel-wolt

Wolt 是一个 Laravel 包,允许您将您的餐厅与 Wolt 平台集成。它提供了一个简单易用的 API,用于同步您的菜单和管理订单。

v1.1.6 2024-08-17 15:33 UTC

This package is auto-updated.

Last update: 2024-09-17 15:36:28 UTC


README

Wolt Logo

Latest Stable Version Total Downloads License

Wolt 是一个 Laravel 包,允许您将您的餐厅与 Wolt 平台集成。它提供了一个简单易用的 API,用于同步您的菜单和管理订单。

目录

要求

  • PHP 8.1 或更高版本
  • Laravel 10.0 或更高版本

安装

要安装 Wolt,您需要运行以下命令

composer require bored-programmers/laravel-wolt

发布配置文件并设置环境变量。

php artisan vendor:publish --tag=wolt-config

更新您的 .env 文件,包括以下变量

WOLT_MENU_API_USERNAME=your_menu_api_username
WOLT_MENU_API_PASSWORD=your_menu_api_password
WOLT_ORDER_API_KEY=your_order_api_key
WOLT_VENUE_ID=your_venue_id
WOLT_IS_SANDBOX=true/false

使用

同步菜单

要同步您的菜单与 Wolt,请使用 WoltService::syncMenu 方法。
以下是一个如何使用 DTO 创建菜单并与 Wolt 同步的示例。

use BoredProgrammers\Wolt\DTO\MenuData;
use BoredProgrammers\Wolt\DTO\CategoryData;
use BoredProgrammers\Wolt\DTO\SubcategoryData;
use BoredProgrammers\Wolt\DTO\ItemData;
use BoredProgrammers\Wolt\DTO\TranslationData;
use BoredProgrammers\Wolt\DTO\CaffeineContentData;
use BoredProgrammers\Wolt\DTO\WeeklyAvailabilityData;
use BoredProgrammers\Wolt\DTO\WeeklyVisibilityData;
use BoredProgrammers\Wolt\DTO\OptionData;
use BoredProgrammers\Wolt\DTO\SelectionRangeData;
use BoredProgrammers\Wolt\DTO\OptionValueData;
use BoredProgrammers\Wolt\DTO\SubOptionValueData;
use BoredProgrammers\Wolt\DTO\ProductInformationData;
use BoredProgrammers\Wolt\DTO\NutritionInformationData;
use BoredProgrammers\Wolt\DTO\NutritionValuesData;
use BoredProgrammers\Wolt\DTO\NutrientData;
use Spatie\LaravelData\DataCollection;

// Example Translations for Category
$categoryNameTranslation = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Beverages']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Boissons'])
]);

// Example Translations for Subcategory
$subCategoryNameTranslation = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Hot Drinks']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Boissons Chaudes'])
]);

// Example Translations for Item
$itemNameTranslation = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Espresso']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Espresso'])
]);

$itemDescriptionTranslation = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Rich and bold espresso coffee']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Café espresso riche et audacieux'])
]);

// Example Translations for Options
$optionNameTranslation = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Milk Type']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Type de Lait'])
]);

$optionValueNameTranslation1 = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Whole Milk']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Lait entier'])
]);

$optionValueNameTranslation2 = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Soy Milk']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Lait de soja'])
]);

// Example Sub-option Value
$subOptionValueNameTranslation = new DataCollection([
    TranslationData::from(['lang' => 'en', 'value' => 'Vanilla Syrup']),
    TranslationData::from(['lang' => 'fr', 'value' => 'Sirop de vanille'])
]);

// Example Nutrition Information
$nutritionInformation = NutritionInformationData::from([
    'serving_size' => 'per_100_ml',
    'nutrition_values' => NutritionValuesData::from([
        'energy_kcal' => NutrientData::from(['unit' => 'kcal', 'value' => 5]),
        'energy_kj' => NutrientData::from(['unit' => 'kj', 'value' => 20]),
        'fats' => NutrientData::from(['unit' => 'g', 'value' => 0.1]),
        'saturated_fats' => NutrientData::from(['unit' => 'g', 'value' => 0.05]),
        'mono_unsaturated_fats' => NutrientData::from(['unit' => 'g', 'value' => 0.01]),
        'poly_unsaturated_fats' => NutrientData::from(['unit' => 'g', 'value' => 0.01]),
        'carbohydrate' => NutrientData::from(['unit' => 'g', 'value' => 0.5]),
        'sugar' => NutrientData::from(['unit' => 'g', 'value' => 0.1]),
        'starch' => NutrientData::from(['unit' => 'g', 'value' => 0.2]),
        'polyols' => NutrientData::from(['unit' => 'g', 'value' => 0.0]),
        'protein' => NutrientData::from(['unit' => 'g', 'value' => 0.2]),
        'salt' => NutrientData::from(['unit' => 'g', 'value' => 0.01]),
        'sodium' => NutrientData::from(['unit' => 'mg', 'value' => 5]),
        'fibres' => NutrientData::from(['unit' => 'g', 'value' => 0.1]),
        'vitamin_c' => NutrientData::from(['unit' => 'mg', 'value' => 0.0]),
        'potassium' => NutrientData::from(['unit' => 'mg', 'value' => 80]),
        'calcium' => NutrientData::from(['unit' => 'mg', 'value' => 10]),
        'magnesium' => NutrientData::from(['unit' => 'mg', 'value' => 2]),
        'chloride' => NutrientData::from(['unit' => 'mg', 'value' => 5]),
        'fluoride' => NutrientData::from(['unit' => 'mg', 'value' => 0.0])
    ])
]);

// Example Product Information
$productInformation = ProductInformationData::from([
    'ingredients' => new DataCollection([
        TranslationData::from(['lang' => 'en', 'value' => 'Water, Coffee Beans']),
        TranslationData::from(['lang' => 'fr', 'value' => 'Eau, Grains de café'])
    ]),
    'additives' => new DataCollection([
        TranslationData::from(['lang' => 'en', 'value' => 'None']),
        TranslationData::from(['lang' => 'fr', 'value' => 'Aucun'])
    ]),
    'nutrition_facts' => new DataCollection([
        TranslationData::from(['lang' => 'en', 'value' => 'Low calories']),
        TranslationData::from(['lang' => 'fr', 'value' => 'Faible en calories'])
    ]),
    'nutrition_information' => $nutritionInformation,
    'allergens' => new DataCollection([
        TranslationData::from(['lang' => 'en', 'value' => 'None']),
        TranslationData::from(['lang' => 'fr', 'value' => 'Aucun'])
    ]),
    'producer_information' => new DataCollection([
        TranslationData::from(['lang' => 'en', 'value' => 'Local Roastery']),
        TranslationData::from(['lang' => 'fr', 'value' => 'Torréfacteur local'])
    ])
]);

// Example Option with Sub-option Values
$optionValue1 = OptionValueData::from([
    'name' => $optionValueNameTranslation1,
    'selection_range' => SelectionRangeData::from(['min' => 0, 'max' => 1]),
    'price' => 0.50,
    'enabled' => true,
    'default' => true,
    'external_data' => 'option-value-1',
    'sub_option_values' => new DataCollection([
        SubOptionValueData::from([
            'name' => $subOptionValueNameTranslation,
            'selection_range' => SelectionRangeData::from(['min' => 0, 'max' => 1]),
            'price' => 0.20,
            'enabled' => true,
            'default' => false,
            'external_data' => 'sub-option-value-1'
        ])
    ])
]);

$optionValue2 = OptionValueData::from([
    'name' => $optionValueNameTranslation2,
    'selection_range' => SelectionRangeData::from(['min' => 0, 'max' => 1]),
    'price' => 0.60,
    'enabled' => true,
    'default' => false,
    'external_data' => 'option-value-2',
    'sub_option_values' => null
]);

$option = OptionData::from([
    'name' => $optionNameTranslation,
    'type' => 'SingleChoice',
    'selection_range' => SelectionRangeData::from(['min' => 1, 'max' => 1]),
    'external_data' => 'option-1',
    'values' => new DataCollection([$optionValue1, $optionValue2])
]);

// Example Item
$item = ItemData::from([
    'name' => $itemNameTranslation,
    'description' => $itemDescriptionTranslation,
    'image_url' => 'https://example.com/espresso.jpg',
    'price' => 2.99,
    'sales_tax_percentage' => 0.07,
    'alcohol_percentage' => null,
    'caffeine_content' => CaffeineContentData::from(['serving_size' => 'per_100_ml', 'value' => 212.0]),
    'weekly_availability' => new DataCollection([
        WeeklyAvailabilityData::from([
            'opening_day' => 'MONDAY',
            'opening_time' => '08:00',
            'closing_day' => 'MONDAY',
            'closing_time' => '20:00'
        ])
    ]),
    'weekly_visibility' => new DataCollection([
        WeeklyVisibilityData::from([
            'opening_day' => 'MONDAY',
            'opening_time' => '08:00',
            'closing_day' => 'MONDAY',
            'closing_time' => '20:00'
        ])
    ]),
    'enabled' => true,
    'delivery_methods' => ['takeaway', 'homedelivery'],
    'options' => new DataCollection([$option]),
    'external_data' => 'item-espresso-001',
    'product_information' => $productInformation
]);

// Example Subcategory
$subcategory = SubcategoryData::from([
    'name' => $subCategoryNameTranslation,
    'description' => null,
    'items' => new DataCollection([$item])
]);

// Example Category
$category = CategoryData::from([
    'name' => $categoryNameTranslation,
    'description' => null,
    'subcategories' => new DataCollection([$subcategory])
]);

// Example Menu
$menu = MenuData::from([
    'currency' => 'USD',
    'primary_language' => 'en',
    'categories' => new DataCollection([$category])
]);

$response = WoltService::syncMenu($menuData);

获取订单

要检索订单,请使用 WoltService::getOrder 方法。

您将从 Wolt 调用的 webhook 中获取订单 ID。
更多关于此的信息 > Wolt Webhook 文档

我建议使用 spatie/laravel-webhook-client 包来处理 webhook。

use BoredProgrammers\Wolt\WoltService;

$orderId = 'your_wolt_order_id';
$response = WoltService::getOrder($orderId);

接受订单

要接受订单,请使用 WoltService::acceptOrder 方法。

use BoredProgrammers\Wolt\WoltService;

$orderId = 'your_wolt_order_id';
$response = WoltService::acceptOrder($orderId);

拒绝订单

要拒绝订单,请使用 WoltService::rejectOrder 方法。

use BoredProgrammers\Wolt\WoltService;

$orderId = 'your_wolt_order_id';
$response = WoltService::rejectOrder($orderId);

标记订单为准备就绪

要标记订单为准备就绪,请使用 WoltService::markReadyOrder 方法。

use BoredProgrammers\Wolt\WoltService;

$orderId = 'your_wolt_order_id';
$response = WoltService::markReadyOrder($orderId);

标记订单为已送达

要标记订单为已送达,请使用 WoltService::markDeliveredOrder 方法。

use BoredProgrammers\Wolt\WoltService;

$orderId = 'your_wolt_order_id';
$response = WoltService::markDeliveredOrder($orderId);

确认预订

要确认预订,请使用 WoltService::confirmPreorder 方法。

use BoredProgrammers\Wolt\WoltService;

$orderId = 'your_wolt_order_id';
$response = WoltService::confirmPreorder($orderId);

贡献指南

我们欢迎为 Wolt 做出贡献。如果您想做出贡献,请 fork 仓库,进行更改,并提交 pull request。我们对贡献有一些要求

  • 遵循 PSR-2 编码标准。
  • 仅使用 pull request 进行贡献。

变更日志

有关更改的详细历史记录,请参阅 GitHub 上的 发行版

许可

本项目采用 MIT 许可证

联系方式

如有任何问题或疑虑,请随时在 GitHub 上创建 讨论

鸣谢

Matěj ČernýBored Programmers 创建。

致谢

我们感谢所有帮助使 Wolt 成为更好的包的贡献者。