rikless / laravel-shop
此软件包设置为向Laravel提供商店或电子商务功能(例如购物车、订单、交易和项目),以便进行自定义构建。
Requires
- php: >=7.4
- illuminate/console: ^8.0
- illuminate/support: ^8.0
README
Laravel Shop 是将商店功能添加到 Laravel 8.9 的灵活方式。旨在成为手工艺人的电子商务解决方案。
Laravel 商店将购物车、订单和支付添加到您的新项目或现有项目;让您将任何模型转换为可购买的商品。
内容
作用域
当前版本包括
- 商店商品(将现有模型转换为可添加到购物车和订单的可购买商品)
- 购物车
- 订单
- 交易
- 支付网关支持
- PayPal
- 事件
即将推出
- 访客用户购物车
- 发货订单
- 优惠券
- 产品和变体解决方案
- 后端仪表板
- 前端模板
安装
使用 composer
composer require amsgames/laravel-shop
或添加
"rikless/laravel-shop": "0.2.*"
到您的 composer.json 中。然后运行 composer install
或 composer update
。
然后在您的 config/app.php
中添加
Amsgames\LaravelShop\LaravelShopProvider::class,
到 providers
数组。
然后添加
'Shop' => Amsgames\LaravelShop\LaravelShopFacade::class,
到 aliases
数组。
配置
在 config/auth.php
文件中设置配置值。此软件包将使用它们来引用用户表和模型。
发布此软件包的配置以进一步自定义表名、模型命名空间、货币和其他值。运行以下命令
php artisan vendor:publish
将在您的 app/config 目录中创建一个 shop.php
文件。
数据库设置
生成软件包迁移文件
php artisan laravel-shop:migration
以下命令将生成一个新的迁移文件,包含创建购物车和项目表的数据库命令。该文件将位于 database/migrations
。如有需要,添加额外的字段以满足您的软件需求。
该命令还将创建一个数据库种子来填充商店目录的状态和类型。
在数据库中创建模式
php artisan migrate
将种子添加到 database/seeds/DatabaseSeeder.php
class DatabaseSeeder extends Seeder { public function run() { Model::unguard(); $this->call('LaravelShopSeeder'); Model::reguard(); } }
运行种子(首先运行 composer dump-autoload
)
php artisan db:seed
模型
以下模型必须创建以使商店功能正常,这些模型可以根据您的需求进行定制。
项目
创建一个项目模型
php artisan make:model Item
这将创建模型文件 app/Item.php
,编辑它并使其看起来像(考虑您的应用程序命名空间)
<?php namespace App; use Amsgames\LaravelShop\Models\ShopItemModel; class Item extends ShopItemModel { }
Item
模型具有以下主要属性
id
— 项目 id。sku
— 库存单位,即您在商店中的唯一产品识别码。price
— 项目价格。tax
— 项目税。默认为 0。shipping
— 项目运输。默认为 0。currency
— 当前版本的软件包将使用 USD 作为默认值。quantity
— 项目数量。class
— 正在使用作为可购买商品的模型类引用。使用数组数据时为可选。reference_id
— 正在使用作为可购买商品的模型ID引用。使用数组数据时为可选。user_id
— 拥有者。displayPrice
— 适用于商店展示的定价值。例如,"$9.99" 而不是仅仅 "9.99"。displayTax
— 适用于商店展示的税值。例如,"$9.99" 而不是仅仅 "9.99"。displayShipping
— 适用于商店展示的运费值。例如,"$9.99" 而不是仅仅 "9.99"。displayName
— 基于模型的商品名称属性。shopUrl
— 基于模型的商品路由属性。wasPurchased
— 标志,表示商品是否被购买。这基于配置文件中设置的状态。created_at
— 商品记录在数据库中创建的时间。updated_at
— 商品最后更新时间。
业务定义:用作 购物车商品 或 订单商品 的商品。
购物车
创建购物车模型
php artisan make:model Cart
这将创建模型文件 app/Cart.php
,编辑它并使其看起来像(考虑您应用程序的命名空间)
<?php namespace App; use Amsgames\LaravelShop\Models\ShopCartModel; class Cart extends ShopCartModel { }
Item
模型具有以下主要属性
id
— 购物车ID。user_id
— 拥有者。items
— 购物车中的商品。count
— 购物车中的商品总数。totalPrice
— 购物车中所有商品的总价。totalTax
— 购物车中所有商品的总税,加上配置中设置的全球税。totalShipping
— 购物车中所有商品的运费总和。total
— 应收费用的总额,总计商品总价、总税和总运费。displayTotalPrice
— 总价值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。displayTotalTax
— 总税值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。displayTotalShipping
— 总运费值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。displayTotal
— 总金额值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。created_at
— 购物车记录在数据库中创建的时间。updated_at
— 购物车最后更新时间。
订单
创建订单模型
php artisan make:model Order
这将创建模型文件 app/Order.php
,编辑它并使其看起来像(考虑您应用程序的命名空间)
<?php namespace App; use Amsgames\LaravelShop\Models\ShopOrderModel; class Order extends ShopOrderModel { }
Order
模型有以下主要属性
id
— 订单ID或订单号。user_id
— 拥有者。items
— 订单中的商品。transactions
— 订单上的交易。statusCode
— 状态代码。count
— 订单中的商品总数。totalPrice
— 订单中所有商品的总价。totalTax
— 订单中所有商品的总税,加上配置中设置的全球税。totalShipping
— 订单中所有商品的运费总和。total
— 应收费用的总额,总计商品总价、总税和总运费。displayTotalPrice
— 总价值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。displayTotalTax
— 总税值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。displayTotalShipping
— 总运费值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。displayTotal
— 总金额值,适用于商店展示。例如,"$9.99" 而不是仅仅 "9.99"。created_at
— 订单记录在数据库中创建的时间。updated_at
— 订单最后更新时间。
交易
创建交易模型
php artisan make:model Transaction
这将创建模型文件 app/Transaction.php
,编辑它并使其看起来像(考虑您应用程序的命名空间)
<?php namespace App; use Amsgames\LaravelShop\Models\ShopTransactionModel; class Transaction extends ShopTransactionModel { }
Order
模型有以下主要属性
id
— 订单ID或订单号。order
— 订单中的商品。gateway
— 使用的网关。transaction_id
— 网关返回的交易ID。detail
— 网关返回的详细信息。token
— 网关回调的令牌。created_at
— 订单记录在数据库中创建的时间。updated_at
— 订单最后更新时间。
用户
在您的现有 User
模型中使用 ShopUserTrait
特性。通过添加 use Amsgames\LaravelShop\Traits\ShopUserTrait
和 use ShopUserTrait
,如下例所示
<?php use Amsgames\LaravelShop\Traits\ShopUserTrait; class User extends Model { use Authenticatable, CanResetPassword, ShopUserTrait; }
这将启用与 Cart
和商店所需的关联、方法和属性。
cart
— 用户的购物车。items
— 商品(订单或购物车中的商品)。orders
— 用户的订单。
现有模型转换
Laravel Shop 包允许您将任何现有的 Eloquent
模型转换为可售商品,可以在商店中使用而不牺牲任何现有功能。此功能将允许模型添加到购物车或订单中。这需要两个小步骤
在您的现有模型中使用 ShopItemTrait
。通过添加 use Amsgames\LaravelShop\Traits\ShopItemTrait
和 use ShopItemTrait
,如下例所示
<?php use Amsgames\LaravelShop\Traits\ShopItemTrait; class MyCustomProduct extends Model { use ShopItemTrait; // MY METHODS AND MODEL DEFINITIONS........ }
将 sku
(字符串)和 price
(小数,20,2)字段添加到您的模型表中。您还可以包括 name
(字符串)、tax
(小数,20,2)和 shipping
(小数,20,2),尽管这些是可选的。您可以通过创建一个新的迁移来完成此操作
php artisan make:migration alter_my_table
定义迁移,如下例所示
<?php class AlterMyTable extends Migration { public function up() { Schema::table('MyCustomProduct', function($table) { $table->string('sku')->after('id'); $table->decimal('price', 20, 2)->after('sku'); $table->index('sku'); $table->index('price'); }); } public function down() { // Restore type field Schema::table('MyCustomProduct', function($table) { $table->dropColumn('sku'); $table->dropColumn('price'); }); } }
运行迁移
php artisan migrate
商品名称
默认情况下,Laravel Shop 会查找 name
属性来定义商品的名称。如果您的现有模型有用于名称的不同属性,只需在模型中定义该属性即可
<?php use Amsgames\LaravelShop\Traits\ShopItemTrait; class MyCustomProduct extends Model { use ShopItemTrait; /** * Custom field name to define the item's name. * @var string */ protected $itemName = 'product_name'; // MY METHODS AND MODEL DEFINITIONS........ }
商品 URL
您可以通过设置类属性 itemRouteName
和 itemRouteParams
来定义商品的 URL 属性。在以下示例中,定义的 URL 用于显示产品的简介为 product/{slug}
,必须在模型中应用以下更改
<?php use Amsgames\LaravelShop\Traits\ShopItemTrait; class MyCustomProduct extends Model { use ShopItemTrait; /** * Name of the route to generate the item url. * * @var string */ protected $itemRouteName = 'product'; /** * Name of the attributes to be included in the route params. * * @var string */ protected $itemRouteParams = ['slug']; // MY METHODS AND MODEL DEFINITIONS........ }
自动加载导出
导出 composer 自动加载
composer dump-autoload
支付网关
可以在 shop.php
配置文件中的 gateways
数组中配置和添加已安装的支付网关,如下所示
'gateways' => [ 'paypal' => Amsgames\LaravelShopGatewayPaypal\GatewayPayPal::class, 'paypalExpress' => Amsgames\LaravelShopGatewayPaypal\GatewayPayPalExpress::class, ],
PayPal
Laravel Shop 默认支持 PayPal。您可以使用 PayPal 的 Direct Credit Card
或 PayPal Express
支付。
要配置 PayPal 以及了解如何使用网关,请访问 PayPal Gateway Package 页面。
Omnipay
安装 Omnipay Gateway 以启用其他支付服务,例如 2Checkout、Authorize.net、Stripe 等。
您可能需要了解 Omnipay 的工作方式。
用法
商店
需要考虑的商店方法
将价格或其他值格式化为配置中指定的价格格式
$formatted = Shop::format(9.99); // i.e. this will return $9.99 or the format set in the config file.
购买流程
使用 Laravel Shop,您可以按自己的方式自定义事物,尽管我们建议您将购买或结账流程标准化,如下(将解释如何使用以下商店方法)
- (步骤 1) - 用户查看他的购物车。
- (步骤 2) - 继续选择要使用的网关。
- (步骤 3) - 继续为所选网关提供所需信息。
- (步骤 4) - 在下订单之前检查结账购物车和预览购物车。
- (步骤 5) - 下订单。
支付网关
在调用任何商店方法之前,必须设置支付网关
// Select the gateway to use Shop::setGateway('paypal'); echo Shop::getGateway(); // echos: paypal
您还可以访问网关类对象
$gateway = Shop::gateway(); echo $gateway; // echos: [{"id":"paypal"}]
结账
一旦选择了支付网关,您可以像这样调用购物车结账
// Checkout current users' cart $success = Shop::checkout(); // Checkout q specific cart $success = Shop::checkout($cart);
这将调用支付网关中的 onCheckout
函数并执行验证。此方法将返回一个布尔标志,指示操作是否成功。
订单放置
一旦选择了支付网关并且用户已经结账,您可以像这样调用订单放置
// Places order based on current users' cart $order = Shop::placeOrder(); // Places order based on a specific cart $order = Shop::placeOrder($cart);
注意: placeOrder()
将创建订单,将购物车中的所有项目与订单相关联并清空购物车。Order
模型不包括添加或删除项的方法,任何对购物车的修改必须在下单之前完成。在设计您的结账流程时要意识到这一点。
这将调用支付网关中的 onCharge
函数并使用订单的总额向用户收费。placeOrder()
将返回一个 Order
模型,您可以使用它来验证状态并检索由网关生成的交易。
支付
支付由网关处理,此包默认包含 PayPal。
您可以使用 PayPal 的 Direct Credit Card
或 PayPal Express
支付。
要配置PayPal并了解如何使用其网关,请访问PayPal网关包页面。
异常
如果结账或下订单出现错误,您可以调用并查看相关的异常
// On checkout if (!Shop::checkout()) { $exception = Shop::exception(); echo $exception->getMessage(); // echos: error } // Placing order $order = Shop::placeOrder(); if ($order->hasFailed) { $exception = Shop::exception(); echo $exception->getMessage(); // echos: error }
关键异常存储在Laravel的日志中。
购物车
购物车在数据库中为每个用户创建,这意味着当用户注销或切换到不同设备时,他可以保存自己的购物车。
让我们先调用或创建当前用户的购物车
// From cart $cart = Cart::current(); // Once a cart has been created, it can be accessed from user $user->cart;
注意:Laravel Shop目前不支持访客。
获取其他用户的购物车
$userId = 1; $cart = Cart::findByUser($userId);
添加项目
让我们添加一个测试和现有模型MyCustomProduct
的一个项目
$cart = Cart::current()->add(MyCustomProduct::find(1));
默认情况下,添加方法将设置数量为1。
相反,让我们添加3个MyCustomProduct
;
$cart = Cart::current(); $cart->add(MyCustomProduct::find(1), 3);
购物车中每个sku只能创建一个项目。如果添加了相同sku
的项目,则只会保留一个项目,但其数量会增加
$product = MyCustomProduct::find(1); // Adds 1 $cart->add($product); // Adds 3 $cart->add($product, 3); // Adds 2 $cart->add($product, 2); echo $cart->count; // echos: 6 $second_product = MyCustomProduct::findBySKU('TEST'); // Adds 2 of product 'TEST' $cart->add($second_product, 2); // Count based on quantity echo $cart->count; // echos: 8 // Count based on products echo $cart->items->count(); // echos: 2
我们可以将项目的数量重置为给定值
// Add 3 $cart->add($product, 3); echo $cart->count; // echos: 3 // Reset quantity to 4 $cart->add($product, 4, $forceReset = true); echo $cart->count; // echos: 4
添加不存在的模型项目
您可以通过将它们作为数组插入来添加不存在的项目,每个数组必须包含sku
和price
键
// Adds unexistent item model PROD0001 $cart->add(['sku' => 'PROD0001', 'price' => 9.99]); // Add 4 items of SKU PROD0002 $cart->add(['sku' => 'PROD0002', 'price' => 29.99], 4);
移除项目
让我们从购物车中移除测试和现有模型MyCustomProduct
$product = MyCustomProduct::find(1); // Remove the product from cart $cart = Cart::current()->remove($product);
下面的示例将完全删除项目,但也可以只从购物车中删除一定数量的项目
// Removes only 2 from quantity // If the quantity is greater than 2, then 1 item will remain in cart $cart->remove($product, 2);
可以使用数组来删除不存在的模型项目
// Removes by sku $cart->remove(['sku' => 'PROD0001']);
清空购物车
$cart->clear();
这些方法可以串联使用
$cart->add($product, 5) ->add($product2) ->remove($product3) ->clear();
购物车方法
// Checks if cart has item with SKU "PROD0001" $success = $cart->hasItem('PROD0001');
下单
您可以直接从购物车下订单,而无需调用Shop
类,尽管这只会创建数据库中的订单记录,并不会处理支付。与使用Shop
时相同,订单完成后,购物车将被清空。
// This will create the order and set it to the status in configuration $order = $cart->placeOrder();
创建时也可以强制设置状态
$order = $cart->placeOrder('completed');
显示
以下是如何在blade模板中显示购物车的示例
购物车中的项目数量
<span>Items in cart: {{ $cart->count }}</span>
购物车中的项目
<table> @foreach ($cart->items as $item) { <tr> <td>{{ $item->sku }}</td> <td><a href="{{ $item->shopUrl }}">{{ $item->displayName }}</a></td> <td>{{ $item->price }}</td> <td>{{ $item->displayPrice }}</td> <td>{{ $item->tax }}</td> <td>{{ $item->quantity }}</td> <td>{{ $item->shipping }}</td> </tr> @endforeach </table>
购物车金额计算
<table> <tbody> <tr> <td>Subtotal:</td> <td>{{ $cart->displayTotalPrice }}</td> <td>{{ $cart->totalPrice }}</td> </tr> <tr> <td>Shipping:</td> <td>{{ $cart->displayTotalShipping }}</td> </tr> <tr> <td>Tax:</td> <td>{{ $cart->displayTotalTax }}</td> </tr> </tbody> <tfoot> <tr> <th>Total:</th> <th>{{ $cart->displayTotal }}</th> <th>{{ $cart->total }}</th> </tr> </tfoot> </table>
项目
插入购物车或订单的模型或数组将转换为SHOP项目,shop中使用模型Item
代替。
可以从SHOP项目检索模型对象
// Lets assume that the first Cart item is MyCustomProduct. $item = $cart->items[0]; // Check if item has model if ($item->hasObject) { $myproduct = $item->object; }
$item->object
是已加载的MyCustomProduct
模型,我们可以直接访问其属性和方法,例如
// Assuming MyCustomProduct has a types relationship. $item->object->types; // Assuming MyCustomProduct has myAttribute attribute. $item->object->myAttribute;
以下shop方法适用于模型Item
或使用ShopItemTrait
的现有模型
$item = Item::findBySKU('PROD0001'); $item = MyCustomProduct::findBySKU('PROD0002'); // Quering $item = Item::whereSKU('PROD0001')->where('price', '>', 0)->get();
订单
查找特定的订单号
$order = Order::find(1);
查找用户的订单
// Get orders from specific user ID. $orders = Order::findByUser($userId); // Get orders from specific user ID and status. $canceled_orders = Order::findByUser($userId, 'canceled');
执行交易
您可以直接从订单中放置交易,而无需调用Shop
类,尽管这只会创建数据库中的交易记录,并不会处理支付。
// This will create the order and set it to the status in configuration $transaction = $order->placeTransaction( $gateway = 'my_gateway', $transactionId = 55555, $detail = 'Custom transaction 55555' );
订单方法
$completed = $order->isCompleted // Checks if order is in a specific status. $success = $order->is('completed'); // Quering // Get orders from specific user ID. $orders = Order::whereUser($userId)->get(); // Get orders from specific user ID and status. $completed_orders = Order::whereUser($userId) ->whereStatus('completed') ->get();
订单状态码
开箱即用的状态码
in_creation
— 正在创建的订单状态。或使用$order->isInCreation
。pending
— 等待支付。或使用$order->isPending
。in_process
— 正在发货。正在修订中。或使用$order->isInProcess
。completed
— 当支付完成且项目已交付给客户时。或使用$order->isCompleted
。failed
— 当支付失败时。或使用$order->hasFailed
。canceled
— 当订单被用户取消时。或使用$order->isCanceled
。
您可以使用自己的自定义状态码。只需将它们手动添加到order_status
数据库表或创建一个自定义seeder,如下所示
class MyCustomStatusSeeder extends Seeder { public function run() { DB::table('order_status')->insert([ [ 'code' => 'my_status', 'name' => 'My Status', 'description' => 'Custom status used in my shop.', ], ]); } }
然后使用它
$myStatusCode = 'my_status'; if ($order->is($myStatusCode)) { echo 'My custom status work!'; }
事件
Laravel Shop遵循Laravel 5指南来触发事件,创建您的处理程序和监听器,就像您通常使用它们一样。
以下是事件参考
事件处理程序示例
如何使用处理程序中的事件的示例
<?php namespace App\Handlers\Events; use App\Order; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Amsgames\LaravelShop\Events\OrderCompleted; class NotifyPurchase implements ShouldQueue { use InteractsWithQueue; /** * Handle the event. * * @param OrderPurchased $event * @return void */ public function handle(OrderCompleted $event) { // The order ID echo $event->id; // Get order model object $order = Order::find($event->id); // My code here... } }
请记住在事件提供程序中注册您的句柄和监听器。
'Amsgames\LaravelShop\Events\OrderCompleted' => [ 'App\Handlers\Events\NotifyPurchase', ],
支付网关开发
Laravel Shop是为了定制而开发的。允许社区扩展其功能。
缺失的支付网关可以轻松地作为外部包开发,然后在配置文件中进行配置。
将此项目作为您的包或Laravel设置的必需依赖项,并简单地扩展Laravel Shop核心类,以下是一个PayPal示例
<?php namespace Vendor\Package; use Amsgames\LaravelShop\Core\PaymentGateway; use Amsgames\LaravelShop\Exceptions\CheckoutException; use Amsgames\LaravelShop\Exceptions\GatewayException; class GatewayPayPal extends PaymentGateway { /** * Called on cart checkout. * THIS METHOD IS OPTIONAL, DONE FOR GATEWAY VALIDATIONS BEFORE PLACING AN ORDER * * @param Order $order Order. */ public function onCheckout($cart) { throw new CheckoutException('Checkout failed.'); } /** * Called by shop to charge order's amount. * * @param Order $order Order. * * @return bool */ public function onCharge($order) { throw new GatewayException('Payment failed.'); return false; } }
网关至少需要onCharge
方法。您可以根据需要添加更多方法。
一旦创建,您可以将它添加到shop.php
配置文件中,例如
'gateways' => [ 'paypal' => Vendor\Package\GatewayPaypal::class, ],
使用方式如下
Shop::setGateway('paypal');
交易
为了正确生成交易,您必须在设置onCharge
时考虑以下3个属性
public function onCharge($order) { // The transaction id generated by the provider i.e. $this->transactionId = $paypal->transactionId; // Custom detail of 1024 chars. $this->detail = 'Paypal: success'; // Order status after method call. $this->statusCode = 'in_process'; return true; }
transactionId
—— 提供商的交易ID,有助于识别交易。detail
—— 交易的自定义描述。statusCode
—— 在执行onCharge后更新订单的订单状态代码。默认为'完成'。
回调
Laravel Shop支持需要回调的网关。为此,您需要向您的网关添加两个额外的函数
<?php namespace Vendor\Package; use Amsgames\LaravelShop\Core\PaymentGateway; use Amsgames\LaravelShop\Exceptions\CheckoutException; use Amsgames\LaravelShop\Exceptions\GatewayException; class GatewayWithCallbacks extends PaymentGateway { /** * Called by shop to charge order's amount. * * @param Order $order Order. * * @return bool */ public function onCharge($order) { // Set the order to pending. $this->statusCode = 'pending'; // Sets provider with the callback for successful transactions. $provider->setSuccessCallback( $this->callbackSuccess ); // Sets provider with the callback for failed transactions. $provider->setFailCallback( $this->callbackFail ); return true; } /** * Called on callback. * * @param Order $order Order. * @param mixed $data Request input from callback. * * @return bool */ public function onCallbackSuccess($order, $data = null) { $this->statusCode = 'completed'; $this->detail = 'successful callback'; $this->transactionId = $data->transactionId; // My code... } /** * Called on callback. * * @param Order $order Order. * @param mixed $data Request input from callback. * * @return bool */ public function onCallbackFail($order, $data = null) { $this->detail = 'failed callback'; // My code... } }
在上面的示例中,onCharge
不是创建完成的交易,而是创建一个挂起的交易,并指示提供者调用哪些URL以回调支付结果。
当提供者回调其响应时,Shop
会调用onCallbackSuccess
和onCallbackFail
方法,根据提供者使用的回调URL调用正确的函数。
onCallbackSuccess
方法将为结束的订单创建一个新的交易。
callbackSuccess
—— 供提供者使用的成功URL回调。callbackFail
—— 供提供者使用的失败URL回调。token
—— 验证令牌。
异常
Laravel Shop提供了一些异常,您可以使用它们来报告错误。
对于onCheckout
CheckoutException
GatewayException
StoreException
—— 此异常将在Laravel中记录,因此仅在致命错误时使用它。
对于onChange
、onCallbackSuccess
和onCallbackFail
GatewayException
StoreException
—— 此异常将在Laravel中记录,因此仅在致命错误时使用它。
注意:Laravel Shop不会捕获任何其他异常。如果抛出正常的Exception
或任何其他异常,它将像通常一样中断方法,这将影响您的结账流程,例如在从placeOrder()
获取订单时。
示例
您可以看到我们制作的PayPal网关作为示例。
-
GatewayPayPal - 处理信用卡,使用
onCheckout
和onCharge
。 -
GatewayPayPalExpress - 处理回调,使用
onCallbackSuccess
和onCharge
。
许可
Laravel Shop是免费软件,根据MIT许可协议分发。
其他信息
本包的架构和设计受到了Zizaco/entrust
包的启发,我们感谢他们的贡献者做出了出色的工作。