Giter VIP home page Giter VIP logo

laravel-shop's Introduction

ITwrx fork of LARAVEL SHOP (minor changes for Laravel 5.2 Compatibility)

Latest Stable Version Total Downloads Latest Unstable Version License

Laravel Shop is flexible way to add shop functionality to Laravel 5.2. Aimed to be the e-commerce solution for artisans.

Laravel shop adds shopping cart, orders and payments to your new or existing project; letting you transform any model into a shoppable item.

Supports

PayPal Omnipay

Contents

Scope

Current version includes:

  • Shop Items (transforms existing models into shoppable items that can be added to cart and orders)
  • Cart
  • Orders
  • Transactions
  • Payment gateways support
  • PayPal
  • Events

On the horizon:

  • Guest user cart
  • Shipping orders
  • Coupons
  • Product and variations solution
  • Backend dashboard
  • Frontend templates

Installation

With composer

composer require amsgames/laravel-shop

Or add

"amsgames/laravel-shop": "0.2.*"

to your composer.json. Then run composer install or composer update.

Then in your config/app.php add

Amsgames\LaravelShop\LaravelShopProvider::class,

in the providers array.

Then add

'Shop'      => Amsgames\LaravelShop\LaravelShopFacade::class,

in the aliases array.

Configuration

Set the configuration values in the config/auth.php file. This package will use them to refer to the user table and model.

Publish the configuration for this package to further customize table names, model namespaces, currencies and other values. Run the following command:

php artisan vendor:publish

A shop.php file will be created in your app/config directory.

Database Setup

Generate package migration file:

php artisan laravel-shop:migration

The command below will generate a new migration file with database commands to create the cart and item tables. The file will be located in database/migrations. Add additional fields if needed to fill your software needs.

The command will also create a database seeder to fill shop catalog of status and types.

Create schema in database:

php artisan migrate

Add the seeder to database/seeds/DatabaseSeeder.php:

class DatabaseSeeder extends Seeder
{

  public function run()
  {
    Model::unguard();

    $this->call('LaravelShopSeeder');

    Model::reguard();
  }

}

Run seeder (do composer dump-autoload first):

php artisan db:seed

Models

The following models must be created for the shop to function, these models can be customizable to fir your needs.

Item

Create a Item model:

php artisan make:model Item

This will create the model file app/Item.php, edit it and make it look like (take in consideration your app's namespace):

<?php

namespace App;

use Amsgames\LaravelShop\Models\ShopItemModel;

class Item extends ShopItemModel
{
}

The Item model has the following main attributes:

  • id — Item id.
  • sku — Stock Keeping Unit, aka your unique product identification within your store.
  • price — Item price.
  • tax — Item tax. Defaulted to 0.
  • shipping — Item shipping. Defaulted to 0.
  • currency — Current version of package will use USD as default.
  • quantity — Item quantity.
  • class — Class reference of the model being used as shoppable item. Optional when using array data.
  • reference_id — Id reference of the model being used as shoppable item. Optional when using array data.
  • user_id — Owner.
  • displayPrice — Price value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTax — Tax value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayShipping — Tax value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayName — Based on the model's item name property.
  • shopUrl — Based on the model's item route property.
  • wasPurchased — Flag that indicates if item was purchased. This base on the status set in config file.
  • created_at — When the item record was created in the database.
  • updated_at — Last time when the item was updated.

Business definition: Item used as a cart item or an order item.

Cart

Create a Cart model:

php artisan make:model Cart

This will create the model file app/Cart.php, edit it and make it look like (take in consideration your app's namespace):

<?php

namespace App;

use Amsgames\LaravelShop\Models\ShopCartModel;

class Cart extends ShopCartModel 
{
}

The Item model has the following main attributes:

  • id — Cart id.
  • user_id — Owner.
  • items — Items in cart.
  • count — Total amount of items in cart.
  • totalPrice — Total price from all items in cart.
  • totalTax — Total tax from all items in cart, plus global tax set in config.
  • totalShipping — Total shipping from all items in cart.
  • total — Total amount to be charged, sums total price, total tax and total shipping.
  • displayTotalPrice — Total price value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTotalTax — Total tax value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTotalShipping — Total shipping value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTotal — Total amount value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • created_at — When the cart record was created in the database.
  • updated_at — Last time when the cart was updated.

Order

Create a Order model:

php artisan make:model Order

This will create the model file app/Order.php, edit it and make it look like (take in consideration your app's namespace):

<?php

namespace App;

use Amsgames\LaravelShop\Models\ShopOrderModel;

class Order extends ShopOrderModel 
{
}

The Order model has the following main attributes:

  • id — Order id or order number.
  • user_id — Owner.
  • items — Items in order.
  • transactions — Transactions made on order.
  • statusCode — Status code.
  • count — Total amount of items in order.
  • totalPrice — Total price from all items in order.
  • totalTax — Total tax from all items in order, plus global tax set in config.
  • totalShipping — Total shipping from all items in order.
  • total — Total amount to be charged, sums total price, total tax and total shipping.
  • displayTotalPrice — Total price value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTotalTax — Total tax value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTotalShipping — Total shipping value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • displayTotal — Total amount value formatted for shop display. i.e. "$9.99" instead of just "9.99".
  • created_at — When the order record was created in the database.
  • updated_at — Last time when the order was updated.

Transaction

Create a Transaction model:

php artisan make:model Transaction

This will create the model file app/Transaction.php, edit it and make it look like (take in consideration your app's namespace):

<?php

namespace App;

use Amsgames\LaravelShop\Models\ShopTransactionModel;

class Transaction extends ShopTransactionModel 
{
}

The Order model has the following main attributes:

  • id — Order id or order number.
  • order — Items in order.
  • gateway — Gateway used.
  • transaction_id — Transaction id returned by gateway.
  • detail — Detail returned by gateway.
  • token — Token for gateway callbacks.
  • created_at — When the order record was created in the database.
  • updated_at — Last time when the order was updated.

User

Use the ShopUserTrait trait in your existing User model. By adding use Amsgames\LaravelShop\Traits\ShopUserTrait and use ShopUserTrait like in the following example:

<?php

use Amsgames\LaravelShop\Traits\ShopUserTrait;

class User extends Model {

	use Authenticatable, CanResetPassword, ShopUserTrait;

}

This will enable the relation with Cart and shop needed methods and attributes.

  • cart — User's cart.
  • items — Items (either order or cart).
  • orders — User's orders.

Existing Model Conversion

Laravel Shop package lets you convert any existing Eloquent model to a shoppable item that can be used within the shop without sacrificing any existing functionality. This feature will let the model be added to carts or orders. The will require two small steps:

Use the ShopItemTrait in your existing model. By adding use Amsgames\LaravelShop\Traits\ShopItemTrait and use ShopItemTrait like in the following example:

<?php

use Amsgames\LaravelShop\Traits\ShopItemTrait;

class MyCustomProduct extends Model {

	use ShopItemTrait;

	// MY METHODS AND MODEL DEFINITIONS........

}

Add sku (string) and price (decimal, 20, 2) fields to your model's table. You can also include name (string), tax (decimal, 20, 2) and shipping (decimal, 20, 2), although these are optional. You can do this by creating a new migration:

php artisan make:migration alter_my_table

Define migration to look like the following example:

<?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');
		});
	}

}

Run the migration:

php artisan migrate
Item name

By default, Laravel Shop will look for the name attribute to define the item's name. If your exisintg model has a different attribute assigned for the name, simply define it in a property within your model:

<?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........

}
Item url

You can define the URL attribute of the item by setting itemRouteName and itemRouteParams class properties. In the following example the url defined to show the product's profile is product/{slug}, the following changes must be applied to the model:

<?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........

}

Dump Autoload

Dump composer autoload

composer dump-autoload

Payment Gateways

Installed payment gateways can be configured and added in the gateways array in the shop.php config file, like:

'gateways' => [
    'paypal'            =>  Amsgames\LaravelShopGatewayPaypal\GatewayPayPal::class,
    'paypalExpress'     =>  Amsgames\LaravelShopGatewayPaypal\GatewayPayPalExpress::class,
],

PayPal

Laravel Shop comes with PayPal support out of the box. You can use PayPal's Direct Credit Card or PayPal Express payments.

To configure PayPal and know how to use the gateways, please visit the PayPal Gateway Package page.

Omnipay

Install Omnipay Gateway to enable other payment services like 2Checkout, Authorize.net, Stripe and to name a few.

You might need to get some extra understanding about how Omnipay works.

Usage

Shop

Shop methods to consider:

Format prices or other values to the price format specified in config:

$formatted = Shop::format(9.99);
// i.e. this will return $9.99 or the format set in the config file.

Purchase Flow

With Laravel Shop you can customize things to work your way, although we recommend standarize your purchase or checkout flow as following (will explain how to use the shop methods below):

Purchase Flow

  • (Step 1) - User views his cart.
  • (Step 2) - Continues into selecting the gateway to use.
  • (Step 3) - Continues into feeding the gateway selected with required information.
  • (Step 4) - Checkouts cart and reviews cart before placing order.
  • (Step 5) - Places order.

Payment Gateway

Before any shop method is called, a payment gateway must be set:

// Select the gateway to use
Shop::setGateway('paypal');

echo Shop::getGateway(); // echos: paypal

You can access the gateway class object as well:

$gateway = Shop::gateway();

echo $gateway; // echos: [{"id":"paypal"}] 

Checkout

Once a payment gateway has been selected, you can call cart to checkout like this:

// Checkout current users' cart
$success = Shop::checkout();

// Checkout q specific cart
$success = Shop::checkout($cart);

This will call the onCheckout function in the payment gateway and perform validations. This method will return a bool flag indication if operation was successful.

Order Placement

Once a payment gateway has been selected and user has checkout, you can call order placement like:

// Places order based on current users' cart
$order = Shop::placeOrder();

// Places order based on a specific cart
$order = Shop::placeOrder($cart);

NOTE: placeOrder() will create an order, relate all the items in cart to the order and empty the cart. The Order model doen't include methods to add or remove items, any modification to the cart must be done before the order is placed. Be aware of this when designing your checkout flow.

This will call the onCharge function in the payment gateway and charge the user with the orders' total amount. placeOrder() will return an Order model with which you can verify the status and retrieve the transactions generated by the gateway.

Payments

Payments are handled gateways, this package comes with PayPal out of the box.

You can use PayPal's Direct Credit Card or PayPal Express payments.

To configure PayPal and know how to use its gateways, please visit the PayPal Gateway Package page.

Exceptions

If checkout or placeOrder had errores, you can call and see the exception related:

// 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
}

Critical exceptions are stored in laravel's log.

Shopping Cart

Carts are created per user in the database, this means that a user can have his cart saved when logged out and when he switches to a different device.

Let's start by calling or creating the current user's cart:

// From cart
$cart = Cart::current();
// Once a cart has been created, it can be accessed from user
$user->cart;

Note: Laravel Shop doen not support guest at the moment.

Get the cart of another user:

$userId = 1;

$cart = Cart::findByUser($userId);

Adding Items

Lest add one item of our test and existing model MyCustomProduct:

$cart = Cart::current()->add(MyCustomProduct::find(1));

By default the add method will set a quantity of 1.

Instead lets add 3 MyCustomProduct;

$cart = Cart::current();

$cart->add(MyCustomProduct::find(1), 3);

Only one item will be created per sku in the cart. If an item of the same sku is added, just on item will remain but its quantity will increase:

$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

We can reset the quantity of an item to a given value:

// 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

Adding Unexistent Model Items

You can add unexistent items by inserting them as arrays, each array must contain sku and price keys:

// 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);

Removing Items

Lest remove our test and existing model MyCustomProduct from cart:

$product = MyCustomProduct::find(1);

// Remove the product from cart
$cart = Cart::current()->remove($product);

The example below will remove the item completly, but it is possible to only remove a certain quantity from the cart:

// Removes only 2 from quantity
// If the quantity is greater than 2, then 1 item will remain in cart
$cart->remove($product, 2);

Arrays can be used to remove unexistent model items:

// Removes by sku
$cart->remove(['sku' => 'PROD0001']);

To empty cart:

$cart->clear();

These methods can be chained:

$cart->add($product, 5)
    ->add($product2)
    ->remove($product3)
    ->clear();

Cart Methods

// Checks if cart has item with SKU "PROD0001"
$success = $cart->hasItem('PROD0001');

Placing Order

You can place an order directly from the cart without calling the Shop class, although this will only create the order record in the database and no payments will be processed. Same ad when using Shop, the cart will be empty after the order is placed.

// This will create the order and set it to the status in configuration
$order = $cart->placeOrder();

Status can be forced in creation as well:

$order = $cart->placeOrder('completed');

Displaying

Hew is an example of how to display the cart in a blade template:

Items count in cart:

<span>Items in cart: {{ $cart->count }}</span>

Items in cart:

<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>

Cart amount calculations:

<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>

Item

Models or arrays inserted in a cart or order are converted into SHOP ITEMS, model Item is used instead within the shop.

Model objects can be retrieved from a SHOP ITEM:

// 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 is MyCustomProduct model already loaded, we can access its properties and methods directly, like:

// Assuming MyCustomProduct has a types relationship.
$item->object->types;

// Assuming MyCustomProduct has myAttribute attribute.
$item->object->myAttribute;

The following shop methods apply to model Item or exiting models that uses ShopItemTrait:

$item = Item::findBySKU('PROD0001');

$item = MyCustomProduct::findBySKU('PROD0002');

// Quering
$item = Item::whereSKU('PROD0001')->where('price', '>', 0)->get();

Order

Find a specific order number:

$order = Order::find(1);

Find orders form user:

// Get orders from specific user ID.
$orders = Order::findByUser($userId);
// Get orders from specific user ID and status.
$canceled_orders = Order::findByUser($userId, 'canceled');

Placing Transactions

You can place a transaction directly from the order without calling the Shop class, although this will only create the transaction record in the database and no payments will be processed.

// 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'
);

Order Methods

$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();

Order Status Codes

Status codes out of the box:

  • in_creation — Order status in creation. Or use $order->isInCreation.
  • pending — Pending for payment. Or use $order->isPending.
  • in_process — In process of shipping. In process of revision. Or use $order->isInProcess.
  • completed — When payment has been made and items were delivered to client. Or use $order->isCompleted.
  • failed — When payment failed. Or use $order->hasFailed.
  • canceled — When an order has been canceled by the user. Or use $order->isCanceled.

You can use your own custom status codes. Simply add them manually to the order_status database table or create a custom seeder like this:

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.',
		    ],
		]);

  }
}

Then use it like:

$myStatusCode = 'my_status';

if ($order->is($myStatusCode)) {
	echo 'My custom status work!';
}

Events

Laravel Shop follows Laravel 5 guidelines to fire events, create your handlers and listeners like you would normally do to use them.

Event Description Data passed
Cart checkout Event fired after a shop has checkout a cart. id - Cart Id success - Checkout result (boolean)
Order placed Event fired when an order has been placed. id - Order Id
Order completed Event fired when an order has been completed. id - Order Id
Order status changed Event fired when an order's status has been changed. id - Order Id statusCode - New status previousStatusCode - Prev status

Here are the events references:

Event Reference
Cart checkout Amsgames\LaravelShop\Events\CartCheckout
Order placed Amsgames\LaravelShop\Events\OrderPlaced
Order completed Amsgames\LaravelShop\Events\OrderCompleted
Order status changed Amsgames\LaravelShop\Events\OrderStatusChanged

Event Handler Example

An example of how to use an event in a handler:

<?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...
    }
}

Remember to register your handles and listeners at the Event Provider:

        'Amsgames\LaravelShop\Events\OrderCompleted' => [
            'App\Handlers\Events\NotifyPurchase',
        ],

Payment Gateway Development

Laravel Shop has been developed for customization in mind. Allowing the community to expand its capabilities.

Missing payment gateways can be easily developed as external packages and then be configured in the config file.

Make this proyect a required dependency of your package or laravel's setup and simply extend from Laravel Shop core class, here a PayPal example:

<?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;
    }
}

The gateway will require onCharge method as minimun. You can add more depending your needs.

Once created, you can add it to the shop.php config file, like:

'gateways' => [
    'paypal'              =>  Vendor\Package\GatewayPaypal::class,
],

And use it like:

Shop::setGateway('paypal');

Transaction

To properly generate the transaction there are 3 properties you must consider on setting during onCharge:

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 — Provider's transaction ID, will help identify a transaction.
  • detail — Custom description for the transaction.
  • statusCode — Order status code with which to update the order after onCharge has executed. By default is 'completed'.

Callbacks

Laravel Shop supports gateways that require callbacks. For this, you will need to add 2 additional functions to your gateway:

<?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...
    }
}

In the example above, onCharge instead of creating a completed transaction, it is creating a pending transaction and indicating the provider to which urls to call back with the payment results.

The methods onCallbackSuccess and onCallbackFail are called by Shop when the provider calls back with its reponse, the proper function will be called depending on the callback url used by the provider.

The method onCallbackSuccess will create a new transaction for the order it ends.

  • callbackSuccess — Successful url callback to be used by the provider.
  • callbackFail — i.e. Failure url callback to be used by the provider.
  • token — i.e. Validation token.

Exceptions

Laravel Shop provides several exceptions you can use to report errors.

For onCheckout:

  • CheckoutException
  • GatewayException
  • StoreException — This exception will be logged in laravel, so use it only for fatal errores.

For onChange, onCallbackSuccess and onCallbackFail:

  • GatewayException
  • StoreException — This exception will be logged in laravel, so use it only for fatal errores.

NOTE: Laravel Shop will not catch any other exception. If a normal Exception or any other exceptions is thrown, it will break the method as it normally would, this will affect your checkout flow like in example when you want to get the order from placeOrder().

Examples

You can see the PayPal gateways we made as examples.

License

Laravel Shop is free software distributed under the terms of the MIT license.

Additional Information

This package's architecture and design was inpired by the Zizaco/entrust package, we'll like to thank their contributors for their awesome woek.

Change Log

laravel-shop's People

Contributors

amostajo avatar amsgames avatar brunopincaro avatar edderrd avatar itwrx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-shop's Issues

ERROR: PayPal Express Checkout not working.

I just tried to make a test-payment using paypalExpress.. Doesn´t work.

Controller Method:

public function checkout() {
        $cart = Cart::current();

        Shop::setGateway('paypalExpress');
        Shop::checkout();
        $order = Shop::placeOrder($cart);
        if ($order->isPending) {
            $approvalUrl = Shop::gateway()->getApprovalUrl();
            return redirect($approvalUrl);
        }
    }

Error:

in GatewayPayPalExpress.php line 131
at HandleExceptions->handleError('8', 'Trying to get property of non-object', '/home/vagrant/Code/Laravel/cookinio/vendor/amsgames/laravel-shop-gateway-paypal/src/GatewayPayPalExpress.php', '131', array('order' => object(Order), 'payer' => object(Payer), 'list' => object(ItemList), 'details' => object(Details), 'amount' => object(Amount), 'transaction' => object(Transaction), 'redirectUrls' => object(RedirectUrls), 'payment' => object(Payment), 'e' => object(PayPalConnectionException), 'response' => null)) in GatewayPayPalExpress.php line 131
at GatewayPayPalExpress->onCharge(object(Order)) in LaravelShop.php line 161

How to fix this? :/

BadMethodCallException

Hello!

When I try to add something to my cart, I got a BadMethodCallException:

cart

# Cart Test
$cart = Cart::findByUser(1);
$product = Product::findBySKU('CA1524585BR');
 $cart->add($product); // this one will not work too: ['sku' => 'PROD0001', 'price' => 9.99]

dd($cart);

$cart and $product are working. When I try to add a product to the cart, I got the BadMethodCallException.

I don't know why it happens. Can you help me? Thank you!

Edit:

/**
     * Retrieves item from cart;
     *
     * @param string $sku SKU of item.
     *
     * @return mixed
     */
    private function getItem($sku)
    {
        $className  = Config::get('shop.item');
        $item       = new $className();
        return $item->where('sku', $sku)
            ->where('cart_id', $this->attributes['id'])
            ->first();
    }

I did a rewrite in the add method and it calls:

$this->getItem(is_array($item) ? $item['sku'] : $item->sku);

the getItem method is private and I cannot access it. But now it is fixed :D

orders table colume definition?

Why README.md, for fields and /src/views/generators/migration.blade.php orders table definition is inconsistent? The former field more

look:

/src/views/generators/migration.blade.php:

Schema::create('orders', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id')->unsigned();
            $table->string('statusCode', 32) -> comment('订单状态码');
            $table->timestamps();
            $table->foreign('user_id')
                ->references('id')
                ->on('users')
                ->onUpdate('cascade')
                ->onDelete('cascade');
            $table->foreign('statusCode')
                ->references('code')
                ->on('order_status')
                ->onUpdate('cascade');
            $table->index(['user_id', 'statusCode']);
            $table->index(['id', 'user_id', 'statusCode']);
        });

README.md

The Order model has the following main attributes:

id — Order id or order number.
user_id — Owner.
items — Items in order.
transactions — Transactions made on order.
statusCode — Status code.
count — Total amount of items in order.
totalPrice — Total price from all items in order.
totalTax — Total tax from all items in order, plus global tax set in config.
totalShipping — Total shipping from all items in order.
total — Total amount to be charged, sums total price, total tax and total shipping.
displayTotalPrice — Total price value formatted for shop display. i.e. "$9.99" instead of just "9.99".
displayTotalTax — Total tax value formatted for shop display. i.e. "$9.99" instead of just "9.99".
displayTotalShipping — Total shipping value formatted for shop display. i.e. "$9.99" instead of just "9.99".
displayTotal — Total amount value formatted for shop display. i.e. "$9.99" instead of just "9.99".
created_at — When the order record was created in the database.
updated_at — Last time when the order was updated.

[Symfony\Component\Debug\Exception\FatalThrowableError]

After i have installed package with Laravel 5.2 , i am getting following error on
php artisan vendor:publish

[Symfony\Component\Debug\Exception\FatalThrowableError]
Fatal error: Call to undefined method Illuminate\Foundation\Application::bindShared()

Can items.user_id be null?

Will it break any existing functionality if items.user_id is nullable? I have products in my system that will not be owned by a specific user and I'm wondering if making this column null will break things.

Custom cart table name is not working correctly

Hi,

I defined a custom cart table name inside the config file as stated in the docs. I discovered some problems with the foreign key names though.
First the migration generator script does not adopt the correct foreign key names:

e.g. if you have a custom_carts table defined, the foreign key to a custom cart should be custom_cart_id instead it is cart_id (I guess?)

If you forget to change them you'll get an SQL exception in the runCalculations method of the ShopCalculationsTrait in Line 170, since the foreign key is generated from the table name following "_id". BTW I don't understand why order_id is hardcoded here? is this somewhere mentioned in the docs?

If you change the foreign key names accordingly, it is not possible to add products to the cart. The problem here is that the foreign key name referencing the cart table is hardcoded (in Line 86 of the ShopCartTrait) and is not following the pattern table_name_id as the ShopCalculationsTrait does.

I think this is an easy fix by changing ShopCartTrait, But I just wanted to hear your thoughts on this first.

Items are not being saved to Paypal Payments

{
    "id": "PAY-3A447653UM024043KKZPSIYQ",
    "intent": "sale",
    "state": "approved",
    "cart": "6AB7558060412360N",
    "payer": {
        "payment_method": "paypal",
        "status": "VERIFIED",
        "payer_info": {
            "email": "[email protected]",
            "first_name": "Ozan",
            "last_name": "Kurt",
            "payer_id": "JVQLKAALL86WE",
            "shipping_address": {
                "recipient_name": "Ozan Kurt",
                "line1": "Istinye Mahallesi",
                "line2": "\u00c3\u009c Sehitler Sokak No.2",
                "city": "Istanbul",
                "state": "",
                "postal_code": "34460",
                "country_code": "TR"
            },
            "phone": "2168127247",
            "country_code": "TR"
        }
    },
    "transactions": [
        {
            "amount": {
                "total": "118.00",
                "currency": "TRY",
                "details": {
                    "subtotal": "118.00"
                }
            },
            "description": "Cadde Home payment, Order #30",
            "invoice_number": "30",
            "item_list": {
                "items": [],
                "shipping_address": {
                    "recipient_name": "Ozan Kurt",
                    "line1": "Istinye Mahallesi",
                    "line2": "\u00c3\u009c Sehitler Sokak No.2",
                    "city": "Istanbul",
                    "state": "",
                    "postal_code": "34460",
                    "country_code": "TR"
                }
            },
            "related_resources": [
                {
                    "sale": {
                        "id": "4AH02058U6199543D",
                        "state": "pending",
                        "amount": {
                            "total": "118.00",
                            "currency": "TRY",
                            "details": {
                                "subtotal": "118.00"
                            }
                        },
                        "payment_mode": "INSTANT_TRANSFER",
                        "reason_code": "PAYMENT_REVIEW",
                        "protection_eligibility": "INELIGIBLE",
                        "transaction_fee": {
                            "value": "4.46",
                            "currency": "TRY"
                        },
                        "parent_payment": "PAY-3A447653UM024043KKZPSIYQ",
                        "create_time": "2015-12-02T17:16:37Z",
                        "update_time": "2015-12-02T17:16:37Z",
                        "links": [
                            {
                                "href": "https://api.sandbox.paypal.com/v1/payments/sale/4AH02058U6199543D",
                                "rel": "self",
                                "method": "GET"
                            },
                            {
                                "href": "https://api.sandbox.paypal.com/v1/payments/sale/4AH02058U6199543D/refund",
                                "rel": "refund",
                                "method": "POST"
                            },
                            {
                                "href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-3A447653UM024043KKZPSIYQ",
                                "rel": "parent_payment",
                                "method": "GET"
                            }
                        ]
                    }
                }
            ]
        }
    ],
    "create_time": "2015-12-02T17:16:37Z",
    "links": [
        {
            "href": "https://api.sandbox.paypal.com/v1/payments/payment/PAY-3A447653UM024043KKZPSIYQ",
            "rel": "self",
            "method": "GET"
        }
    ]
}

See: transactions.item_list.items is empty

Why can be this?

I need some help to understand this package

Hello and thank you for this great package!

I need help :)

I was reading the documentation and I'm not understanding the Item model.

First, I don't have a model to use as a shoppable item. So, should I use the model Item as a product model? In my case I'm using the model Item as Product(I changed in the config file).
Or, I need to create a new model to be my products model?

And, I didn't understand this attributes:

class — Class reference of the model being used as shoppable item. Optional when using array data.
reference_id — Id reference of the model being used as shoppable item. Optional when using array data.

I'll use them only if I create my own model for products?

Sorry if I'm making some dumb questions but I can't continue without know this.

Thank you!

Extend

I don't find a way to extend your 'placeOrder' method in my models or anywhere

subscription/recurring payment item

hi,
is there a way to create a product/item to use with laravel-shop that uses s subscription or recurring payment instead of one time payment?

thanks in advance.

Examples Anyone?

I am having some trouble integrating the package into my existing models.

Do any of you have some working examples of the shopcontroller and views cart and checkout I can view?

I would appreciate it!

5.2 Completely stops my site

here is the error code:

PHP Fatal error: Uncaught ReflectionException: Class log does not exist in /vendor/laravel/framework/src/Illuminate/Container/Container.php:738
Stack trace:
#0 /vendor/laravel/framework/src/Illuminate/Container/Container.php(738): ReflectionClass->__construct('log')
#1 /vendor/laravel/framework/src/Illuminate/Container/Container.php(633): Illuminate\Container\Container->build('log', Array)
#2 /vendor/laravel/framework/src/Illuminate/Foundation/Application.php(674): Illuminate\Container\Container->make('log', Array)
#3 /vendor/laravel/framework/src/Illuminate/Container/Container.php(853): Illuminate\Foundation\Application->make('log')
#4 /vendor/laravel/framework/src/Illuminate/Container/Container.php(808): Illuminate\Container\Container->resolveClass(Object(ReflectionParameter))
#5 /vendor/laravel/framework/src/Illumina in /vendor/laravel/framework/src/Illuminate/Container/Container.php on line 738

Ability to list users their old transactions [enhancement][help wanted][question]

        $apiContext = new ApiContext(new OAuthTokenCredential(
            config('services.paypal.client_id'),
            config('services.paypal.secret')
        ));

        if (!config('services.paypal.sandbox'))
            $apiContext->setConfig(['mode' => 'live']);

        $transactions = collect();

        foreach (auth()->user()->orders as $order) {
            $transactions = $transactions->merge($order->transactions()->where('detail', 'Success')->get());
        }

        foreach ($transactions as $transaction) {
            $payments[] = Payment::get($transaction->transaction_id, $apiContext)->toArray();
        }

This following code allows me to get all the payments done by the user but somehow their items are always empty. Do you have any idea about why this is happening?

How to use this?

Sorry this isn't an issue but either the documentation isn't great or i'm completely confused.

Does this package allow multiple items to be stored into the database or do we have to create a model for each item?

Like:

T-shirt
Pants

Are they a model each or are they stored in a 'items' database?

config not properly implemented

I have changes table name and now code is breaking....

Column not found: 1054 Unknown column 'shop_items.shop_carts_id' in 'on clause' (SQL: select sum(shop_items.quantity) as itemCount, sum(shop_items.price * shop_items.quantity) as totalPrice, sum(shop_items.tax * shop_items.quantity) as totalTax, sum(shop_items.shipping * shop_items.quantity) as totalShipping from shop_carts inner join shop_items on shop_items.shop_carts_id = shop_carts.id where shop_carts.id = 1 limit 1

typo in composer.json?

i get errors during update having to do with the src/commands folder not being accessible. I'm guessing that's because it's src/Commands locally but src/commands in laravel-shop's composer.json.

thanks

[Unclear] Custom Omnipay gateway

Hey guys,

First of all awesome package! Thanks a lot! I'm sorry to ask this here but i can't figuur out if it's possible to add Omnipay gateways directly into the gateway array of laravel-shop like so:

'gateways' => [
    'paypal'            =>  Amsgames\LaravelShopGatewayPaypal\GatewayPayPal::class,
    'paypalExpress'     =>  Amsgames\LaravelShopGatewayPaypal\GatewayPayPalExpress::class,
    'someOmnipayGateway' => Vendor\Package\SomeOmnipayPackage::class,
],

Your documentation only states: Install Omnipay Gateway to enable other payment services but i can't find any thing in the source code that would handle a custom omnipay gateway.

Am i correct in assuming that a gateway class is needed that extents Amsgames\LaravelShop\Core\PaymentGateway and defines the required functions using the custom gateway omnipay package?

Thanks,

Raoul

Generate package migration file laravel 5.2

i am new and I am following in the footsteps of laravel 5.1 to 5.2
php artisan laravel-shop:migration

after giving yes

creating migration...
Symfony\Component\Debug\Exception\FatalErrorException
Class name must be a valid object or a string

Problems with $cart->add(..); in L5.2

I get Call to undefined method Illuminate\Database\Query\Builder::add()when i´m trying to add an item to the cart..

All models are set up properly.

problem with item name and item url

first of all, let me say, this project looks like it is the exact feature set i was hoping for, especially the good common sense, model conversion feature. so thanks a lot!

I'm using laravel 5.1
i converted an existing model to use with laravel-shop.
i can add it to the cart and view the cart but

<a href="{{ $item->shopUrl }}">{{ $item->displayName }}</a> 

only outputs

<a href="#"></a>

however, i notice that everything that comes directly from the items table is output sucessfully. the top of the converted model in question is:

 namespace App\Models;

use Amsgames\LaravelShop\Traits\ShopItemTrait;
use Illuminate\Database\Eloquent\Model;

class Paso extends Model {

    use ShopItemTrait;

    /**
     * Name of the route to generate the item url.
     *
     * @var string
     */
    protected $itemRouteName = 'paso_finos';

    /**
     * Name of the attributes to be included in the route params.
     *
     * @var string
     */
    protected $itemRouteParams = ['slug'];

the name attribute in my model's table is "name" and i also tried

protected $itemName = 'product_name';

in my model to no avail.

I can also add the cart to an order but it looks like paypal chokes on the lack of item name, so i'm hoping this fixes that too.

Any ideas?

Thanks in advance

Negative values

The shop able me to insert negative values as order total.

Can you suggest me with method to edit values before insert order total and modify the order total.

Thanks

Session::get retrieves wrong index for gatewayKey

I'm amused with your code here and thank you some much for your precious effort. That has teached me a lot. I have some questions about some minor issues with kind regards.

The gateway system pushes gatewayKey to the tail of an session key (as an array). However if, you attempt to pay with multiple gateway and unsuccessfull payment, wrong index returns since getGateway method returns the the first index of the array.

What would you prefer us to use instead? Session::put? Perhaps some users might be interested to store the data of attempted unsuccessful gateways.

Would you prefer pushing data to the head of array

As an example;

First try:
-Payu
Second try:
-Payu
-Payu(no limit)
Third try:
-bank-transfer
-Payu(no limit)
-Payu(no limit)

php artisan laravel-shop:migration showing error

when i run the php artisan laravel-shop:migration command it is showing me error.
object or a string in C:\xampp\htdocs\iqenterprise.in\vendor\amsgames\laravel-shop\src\Commands\MigrationCommand.php on line 132 In MigrationCommand.php line 132: Class name must be a valid object or a string

Column not found 'items.carts_id'

Hi,

I have this problem when I use {!! $cart->count !!}. Why?

This is the error:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'items.carts_id' in 'on clause' (SQL: select sum(items.quantity) as itemCount, sum(items.price * items.quantity) as totalPrice, sum(items.tax * items.quantity) as totalTax, sum(items.shipping * items.quantity) as totalShipping from carts inner join items on items.carts_id = carts.id where carts.id = 8 limit 1) (View: /var/www/theshop/modules/Shopping/Resources/views/cart/cart.blade.php)

Thanks!

Use "reference_id" colum (item table) to keep an array data

Hello

I am dealing with you great package, I want to propose to keep more data in the item table when you don't use a class. At this moment you can keep the sku, price and a id key of a certain class. But if you need to keep an array of ids for example (in my case, array of ids of two classes) you need to modifiy the table, I would to reuse the reference_id column that is null when you create a item without associated class, like this:

        $item_data = array();
        $item_data["myclass1"] = $oferta_tipo_id;
        $item_data["myclass2"] = $oferta_fecha_id;
        $item_data["sku"] = "...";
        $item_data["price"] = 100;
        $carro->add($item_data);

The idea is to retrieve this array when you read the items in the future:

foreach($items as $item)
    $item->getObjectAttribute

I can prepare a PR in this way if the owner wants.

laravel 5.2 incompatability

Not to rush you on updating for laravel 5.2 but i thought i'd post this for your reference.

FatalErrorException in LaravelShopProvider.php line 91: Call to undefined method Illuminate\Foundation\Application::bindShared()

Thanks

Where to call Shop::setGateway('paypal')

Hi I'm new to Laravel, I'm able to create a site just add product to cart, remove product from cart. Now I want to make it can purchase, and I have no idea where to call Shop::setGateway('paypal'). Anyone can explain it to me or give me an example, thanks for help.
p/s: sorry for my bad english.

using with Sentry

I know this package isn't suppor for guest users at the moment. i start a project with Sentry but it cant handle together. When i use Auth class i see there is no problem. Am i missing something ?
Do you have any idea how can i adapt laravel-shop with Sentry

Example ShopController with Cart & Checkout

Could you please add a dummy or example shopcontroller with cart and checkout method examples. It would speed up the process of figuring out this package.

Maybe example cart.blade.php and checkout.blade.php if you have one you have created handy.

So far I think you package rocks.

thanks

How can I include a new field for transactions table?

Hello!

Some tables have a user id as a owner of that data. In my case, I also need to know another owner(in this case, an event).

I have some events created and I want to sell products for each one. So, for each one, I need to know what I sold and so on. How can I add a new field for transactions table and populate this field.

I know that I need to change the migration file but I don't know the best way to make this field be a part of a insert when a method of this package is executed.

Can you help me? Thank you!

EDIT 1

I just found this code in Amsgames\LaravelShop\Traits\ShopOrderTrait.

/**
     * Creates the order's transaction.
     *
     * @param string $gateway       Gateway.
     * @param mixed  $transactionId Transaction ID.
     * @param string $detail        Transaction detail.
     *
     * @return object
     */
    public function placeTransaction($gateway, $transactionId, $detail = null, $token = null)
    {
        return call_user_func(Config::get('shop.transaction') . '::create', [
            'order_id'          => $this->attributes['id'],
            'gateway'           => $gateway,
            'transaction_id'    => $transactionId,
            'detail'            => $detail,
            'token'             => $token,
        ]);
    }

I guess that it's the place where I need to put my event_id. But of course that I don't want to change this file... So, to do what I need, do I need to override this method? Or do I have another way?

EDIT 2

Now I see that Amsgames\LaravelShop\Models\ShopTransactionModel uses ShopTransactionTrait. So I can override it in my model, right? And override another protected attribute if I need.

I guess that I know what I need to do to have what I want. So, do you have any suggestions? Thanks!

Undefined property: stdClass::$name

When performing a checkout using paypalExpress, i´m getting:

at HandleExceptions->handleError('8', 'Undefined property: stdClass::$name', '/home/vagrant/Code/Laravel/cookinio/vendor/amsgames/laravel-shop-gateway-paypal/src/GatewayPayPalExpress.php', '131', array('order' => object(Order), 'payer' => object(Payer), 'list' => object(ItemList), 'details' => object(Details), 'amount' => object(Amount), 'transaction' => object(Transaction), 'redirectUrls' => object(RedirectUrls), 'payment' => object(Payment), 'e' => object(PayPalConnectionException), 'response' => object(stdClass))) in GatewayPayPalExpress.php line 131

Any way way to fix this?

Cart::current() method not work properly

when I use this method Cart::current() I got following error.
This method work properly $cartUser = Cart::findByUser($user->id);

Integrity constraint violation: 1048 Column 'user_id' cannot be null (SQL: insert into shpc_cart (user_id, updated_at, created_at) values (, 2016-02-28 13:18:48, 2016-02-28 13:18:48))

I Payment via email

I can make payments to my account using this package and works great, but I want to change who I'll pay on the fly using email. Is it possible? Thank you!

'MyCustomProduct' doesn't exist

i am using laravel5.5
I have run php artisan make:migration alter_my_table and changed migration code as per documentation then php artisan migrate
i got error
[PDOException]
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ryan.MyCustomProduct' doesn't exist
Thanks

Donation link not working

Hey I would donate you because I will be using this project, but I can't click the link. It redirects me to an image.

$cart = Cart::current(); doesn't work for me in L5.2

with logged in user $cart = Cart::current(); in my controller causes

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null (SQL: insert into `cart` (`user_id`, `updated_at`, `created_at`) values (, 2016-01-14 16:17:00, 2016-01-14 16:17:00))

and further down

at call_user_func('App\Models\Cart::create', array('user_id' => null)) in ShopCartTrait.php line 225

i also notice

 public function user()
    {
        return $this->belongsTo(Config::get('auth.model'), 'user_id');
    }

in ShopCartTrait.php

but auth.model is different in L5.2's config/auth.php. Maybe the $user problems start there?

Thanks

LaravelShopProvider::boot() should be compatible with RouteServiceProvider::boot()

I just downloaded the package using composer, then configured the config/app.php file, setting up the providers and aliases arrays, then after running :
php artisan vendor:publish
I got this error message :

[ErrorException]
Declaration of Amsgames\LaravelShop\LaravelShopProvider::boot() should be compatible with Illuminate\Foundation\Sup
port\Providers\RouteServiceProvider::boot()

Screenshot :
error

FYI, I'm using laravel 5.3
Did I miss anything?

Coupons

Hello!

how I can use Coupons with your package ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.