Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Commit

Permalink
Merge pull request #10 from ohmybrew/billable-feature
Browse files Browse the repository at this point in the history
Billable feature
  • Loading branch information
gnikyt committed Jan 25, 2018
2 parents 6af3ca7 + 65f2e4a commit b1fa0aa
Show file tree
Hide file tree
Showing 55 changed files with 1,137 additions and 230 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

[![Build Status](https://secure.travis-ci.org/ohmybrew/laravel-shopify.png?branch=master)](http://travis-ci.org/ohmybrew/laravel-shopify)
[![Coverage Status](https://coveralls.io/repos/github/ohmybrew/laravel-shopify/badge.svg?branch=master)](https://coveralls.io/github/ohmybrew/laravel-shopify?branch=master)
[![StyleCI](https://styleci.io/repos/96462257/shield?branch=master)](https://styleci.io/repos/96462257)
[![License](https://poser.pugx.org/ohmybrew/laravel-shopify/license)](https://packagist.org/packages/ohmybrew/laravel-shopify)

A Laravel package for aiding in Shopify App development, similar to `shopify_app` for Rails. Works for Laravel 5.4-5.5.
A full-featured Laravel package for aiding in Shopify App development, similar to `shopify_app` for Rails. Works for Laravel 5.4-5.5.

![Screenshot](https://github.com/ohmybrew/laravel-shopify/raw/master/screenshot.png)

Expand All @@ -29,6 +30,7 @@ For more information, tutorials, etc., please view the project's [wiki](https://
- [x] Provide assistance in developing Shopify apps with Laravel
- [x] Integration with Shopify API
- [x] Authentication & installation for shops
- [x] Billing integration built-in for single and recurring application charges
- [x] Auto install app webhooks and scripttags thorugh background jobs
- [x] Provide basic ESDK views
- [x] Handles and processes incoming webhooks
Expand All @@ -38,6 +40,8 @@ For more information, tutorials, etc., please view the project's [wiki](https://

For full resources on this package, see the [wiki](https://github.com/ohmybrew/laravel-shopify/wiki).

For internal documentation, you may run `phpdoc` (hopefully host this online at somepoint).

## LICENSE

This project is released under the MIT [license](https://github.com/ohmybrew/laravel-shopify/blob/master/LICENSE).
10 changes: 6 additions & 4 deletions src/ShopifyApp/Console/WebhookJobMakeCommand.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<?php namespace OhMyBrew\ShopifyApp\Console;
<?php

namespace OhMyBrew\ShopifyApp\Console;

use Illuminate\Support\Str;
use Illuminate\Foundation\Console\JobMakeCommand;
use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputArgument;

class WebhookJobMakeCommand extends JobMakeCommand
Expand Down Expand Up @@ -44,7 +46,7 @@ protected function getArguments()
}

/**
* Execute the console command (>=5.5)
* Execute the console command (>=5.5).
*
* @return void
*/
Expand All @@ -67,7 +69,7 @@ public function handle()
}

/**
* Converts the job class name into a URL endpoint
* Converts the job class name into a URL endpoint.
*
* @param string $name The name of the job
*
Expand Down
4 changes: 3 additions & 1 deletion src/ShopifyApp/Controllers/AuthController.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php namespace OhMyBrew\ShopifyApp\Controllers;
<?php

namespace OhMyBrew\ShopifyApp\Controllers;

use Illuminate\Routing\Controller;
use OhMyBrew\ShopifyApp\Traits\AuthControllerTrait;
Expand Down
11 changes: 11 additions & 0 deletions src/ShopifyApp/Controllers/BillingController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace OhMyBrew\ShopifyApp\Controllers;

use Illuminate\Routing\Controller;
use OhMyBrew\ShopifyApp\Traits\BillingControllerTrait;

class BillingController extends Controller
{
use BillingControllerTrait;
}
4 changes: 3 additions & 1 deletion src/ShopifyApp/Controllers/HomeController.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php namespace OhMyBrew\ShopifyApp\Controllers;
<?php

namespace OhMyBrew\ShopifyApp\Controllers;

use Illuminate\Routing\Controller;
use OhMyBrew\ShopifyApp\Traits\HomeControllerTrait;
Expand Down
4 changes: 3 additions & 1 deletion src/ShopifyApp/Controllers/WebhookController.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php namespace OhMyBrew\ShopifyApp\Controllers;
<?php

namespace OhMyBrew\ShopifyApp\Controllers;

use Illuminate\Routing\Controller;
use OhMyBrew\ShopifyApp\Traits\WebhookControllerTrait;
Expand Down
4 changes: 3 additions & 1 deletion src/ShopifyApp/Facades/ShopifyApp.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php namespace OhMyBrew\ShopifyApp\Facades;
<?php

namespace OhMyBrew\ShopifyApp\Facades;

use Illuminate\Support\Facades\Facade;

Expand Down
15 changes: 8 additions & 7 deletions src/ShopifyApp/Jobs/ScripttagInstaller.php
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
<?php namespace OhMyBrew\ShopifyApp\Jobs;
<?php

namespace OhMyBrew\ShopifyApp\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use OhMyBrew\ShopifyApp\Models\Shop;
use OhMyBrew\ShopifyApp\Facades\ShopifyApp;

class ScripttagInstaller implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

/**
* The shop
* The shop.
*
* @var \OhMyBrew\ShopifyApp\Models\Shop
*/
protected $shop;

/**
* Scripttag list
* Scripttag list.
*
* @var array
*/
Expand Down Expand Up @@ -76,7 +77,7 @@ public function handle()
* @param array $shopScripttags The scripttags installed on the shop
* @param array $scripttag The scripttag
*
* @return boolean
* @return bool
*/
protected function scripttagExists(array $shopScripttags, array $scripttag)
{
Expand Down
17 changes: 9 additions & 8 deletions src/ShopifyApp/Jobs/WebhookInstaller.php
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
<?php namespace OhMyBrew\ShopifyApp\Jobs;
<?php

namespace OhMyBrew\ShopifyApp\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use OhMyBrew\ShopifyApp\Models\Shop;
use OhMyBrew\ShopifyApp\Facades\ShopifyApp;

class WebhookInstaller implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

/**
* The shop
* The shop.
*
* @var \OhMyBrew\ShopifyApp\Models\Shop
*/
protected $shop;

/**
* Webhooks list
* Webhooks list.
*
* @var array
*/
Expand Down Expand Up @@ -74,9 +75,9 @@ public function handle()
* Check if webhook is in the list.
*
* @param array $shopWebhooks The webhooks installed on the shop
* @param array $webhook The webhook
* @param array $webhook The webhook
*
* @return boolean
* @return bool
*/
protected function webhookExists(array $shopWebhooks, array $webhook)
{
Expand Down
163 changes: 163 additions & 0 deletions src/ShopifyApp/Libraries/BillingPlan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

namespace OhMyBrew\ShopifyApp\Libraries;

use Exception;
use OhMyBrew\ShopifyApp\Models\Shop;

class BillingPlan
{
/**
* The shop to target billing.
*
* @var \OhMyBrew\ShopifyApp\Models\Shop
*/
protected $shop;

/**
* The plan details for Shopify.
*
* @var array
*/
protected $details;

/**
* The charge ID.
*
* @var int
*/
protected $chargeId;

/**
* The charge type.
*
* @var string
*/
protected $chargeType;

/**
* Constructor for billing plan class.
*
* @param Shop $shop The shop to target for billing.
* @param string $chargeType The type of charge for the plan (single or recurring).
*
* @return $this
*/
public function __construct(Shop $shop, string $chargeType = 'recurring')
{
$this->shop = $shop;
$this->chargeType = $chargeType === 'single' ? 'application_charge' : 'recurring_application_charge';

return $this;
}

/**
* Sets the plan.
*
* @param array $plan The plan details.
* $plan = [
* 'name' => (string) Plan name.
* 'price' => (float) Plan price. Required.
* 'test' => (boolean) Test mode or not.
* 'trial_days' => (int) Plan trial period in days.
* 'return_url' => (string) URL to handle response for acceptance or decline or billing. Required.
* ]
*
* @return $this
*/
public function setDetails(array $details)
{
$this->details = $details;

return $this;
}

/**
* Sets the charge ID.
*
* @param int $chargeId The charge ID to use
*
* @return $this
*/
public function setChargeId(int $chargeId)
{
$this->chargeId = $chargeId;

return $this;
}

/**
* Gets the charge information for a previously inited charge.
*
* @return object
*/
public function getCharge()
{
// Check if we have a charge ID to use
if (!$this->chargeId) {
throw new Exception('Can not get charge information without charge ID.');
}

// Run API to grab details
return $this->shop->api()->request(
'GET',
"/admin/{$this->chargeType}s/{$this->chargeId}.json"
)->body->{$this->chargeType};
}

/**
* Activates a plan to the shop.
*
* Example usage:
* (new BillingPlan([shop], 'recurring'))->setChargeId(request('charge_id'))->activate();
*
* @return object
*/
public function activate()
{
// Check if we have a charge ID to use
if (!$this->chargeId) {
throw new Exception('Can not activate plan without a charge ID.');
}

// Activate and return the API response
return $this->shop->api()->request(
'POST',
"/admin/{$this->chargeType}s/{$this->chargeId}/activate.json"
)->body->{$this->chargeType};
}

/**
* Gets the confirmation URL to redirect the customer to.
* This URL sends them to Shopify's billing page.
*
* Example usage:
* (new BillingPlan([shop], 'recurring'))->setDetails($plan)->getConfirmationUrl();
*
* @return string
*/
public function getConfirmationUrl()
{
// Check if we have plan details
if (!is_array($this->details)) {
throw new Exception('Plan details are missing for confirmation URL request.');
}

// Begin the charge request
$charge = $this->shop->api()->request(
'POST',
"/admin/{$this->chargeType}s.json",
[
"{$this->chargeType}" => [
'test' => isset($this->details['test']) ? $this->details['test'] : false,
'trial_days' => isset($this->details['trial_days']) ? $this->details['trial_days'] : 0,
'name' => $this->details['name'],
'price' => $this->details['price'],
'return_url' => $this->details['return_url'],
],
]
)->body->{$this->chargeType};

return $charge->confirmation_url;
}
}
10 changes: 6 additions & 4 deletions src/ShopifyApp/Middleware/AuthProxy.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<?php namespace OhMyBrew\ShopifyApp\Middleware;
<?php

namespace OhMyBrew\ShopifyApp\Middleware;

use Closure;
use Illuminate\Http\Request;

class AuthProxy
{
/**
* Handle an incoming request to ensure it is valid
* Handle an incoming request to ensure it is valid.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
Expand All @@ -26,9 +28,9 @@ public function handle(Request $request, Closure $next)
// Build a query string without query characters
$queryCompiled = [];
foreach ($query as $key => $value) {
$queryCompiled[] = "{$key}=" . (is_array($value) ? join($value, ',') : $value);
$queryCompiled[] = "{$key}=".(is_array($value) ? implode($value, ',') : $value);
}
$queryJoined = join($queryCompiled, '');
$queryJoined = implode($queryCompiled, '');

// Build a local signature
$signatureLocal = hash_hmac('sha256', $queryJoined, config('shopify-app.api_secret'));
Expand Down
Loading

0 comments on commit b1fa0aa

Please sign in to comment.