Skip to content

Commit

Permalink
Merge pull request #26 from danrichards/add-recurring-application-cha…
Browse files Browse the repository at this point in the history
…rges

Add recurring application charges
  • Loading branch information
erikgall committed Oct 4, 2022
2 parents e9434e8 + 8ab0aa9 commit 5c5b53c
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 33 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
}
},
"require": {
"php": ">=7.0",
"php": ">=7.1",
"guzzlehttp/guzzle": "^6.2|^7.0",
"nesbot/carbon": "^1.26.3 || ^2.0",
"illuminate/http": "^8.83",
Expand Down
1 change: 1 addition & 0 deletions src/Helpers/Endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ abstract class Endpoint
'orders',
'price_rules',
'products',
'recurring_application_charges',
'risks',
'smart_collections',
'themes',
Expand Down
8 changes: 8 additions & 0 deletions src/Helpers/RecurringApplicationCharges.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Dan\Shopify\Helpers;

class RecurringApplicationCharges extends Endpoint
{
//
}
76 changes: 76 additions & 0 deletions src/Models/RecurringApplicationCharge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Dan\Shopify\Models;

class RecurringApplicationCharge extends AbstractModel
{
/**
* Constant representing an active subscription status.
*/
public const ACTIVE = 'active';

/**
* Constant representing a cancelled subscription status.
*/
public const CANCELLED = 'cancelled';

/**
* Constant representing a declined subscription status.
*/
public const DECLINED = 'declined';

/**
* Constant representing an expired subscription status.
*/
public const EXPIRED = 'expired';

/**
* Constant representing a frozen subscription status.
*/
public const FROZEN = 'frozen';

/**
* Constant representing a pending subscription status.
*/
public const PENDING = 'pending';

/** @var string */
public static $resource_name = 'recurring_application_charge';

/** @var string */
public static $resource_name_many = 'recurring_application_charges';

/**
* The recurring application charge statuses.
*
* @var string[]
*/
public static $statuses = [
self::ACTIVE, self::CANCELLED, self::DECLINED,
self::FROZEN, self::EXPIRED, self::PENDING,
];

/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'activated_on' => 'datetime',
'billing_on' => 'datetime',
'cancelled_on' => 'datetime',
'capped_amount' => 'float',
'confirmation_url' => 'string',
'created_at' => 'datetime',
'id' => 'integer',
'name' => 'string',
'price' => 'float',
'return_url' => 'string',
'status' => 'string',
'terms' => 'string',
'test' => 'bool',
'trial_days' => 'integer',
'trial_ends_on' => 'datetime',
'updated_at' => 'datetime',
];
}
69 changes: 37 additions & 32 deletions src/Shopify.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Dan\Shopify;

use BadMethodCallException;
use Dan\Shopify\Models\RecurringApplicationCharge;
use Dan\Shopify\Exceptions\InvalidOrMissingEndpointException;
use Dan\Shopify\Exceptions\ModelNotFoundException;
use Dan\Shopify\Helpers\Endpoint;
Expand Down Expand Up @@ -44,6 +45,7 @@
* @property \Dan\Shopify\Helpers\Products $products
* @property \Dan\Shopify\Helpers\SmartCollections $smart_collections
* @property \Dan\Shopify\Helpers\Themes $themes
* @property \Dan\Shopify\Helpers\RecurringApplicationCharges $recurring_application_charges
* @property \Dan\Shopify\Helpers\Risks $risks
* @property \Dan\Shopify\Helpers\Variants $variants
* @property \Dan\Shopify\Helpers\Webhooks $webhooks
Expand All @@ -57,6 +59,7 @@
* @method \Dan\Shopify\Helpers\Orders orders(string $order_id)
* @method \Dan\Shopify\Helpers\PriceRules price_rules(string $price_rule_id)
* @method \Dan\Shopify\Helpers\Products products(string $product_id)
* @method \Dan\Shopify\Helpers\RecurringApplicationCharges recurring_application_charges(string $charge_id)
* @method \Dan\Shopify\Helpers\Risks risks(string $risk_id)
* @method \Dan\Shopify\Helpers\SmartCollections smart_collections(string $smart_collection_id)
* @method \Dan\Shopify\Helpers\Themes themes(string $theme_id)
Expand Down Expand Up @@ -168,42 +171,44 @@ class Shopify
* @var array
*/
protected static $endpoints = [
'assets' => 'assets.json',
'customers' => 'customers/%s.json',
'discount_codes' => 'discount_codes/%s.json',
'disputes' => 'shopify_payments/disputes/%s.json',
'fulfillments' => 'fulfillments/%s.json',
'fulfillment_services' => 'fulfillment_services/%s.json',
'images' => 'images/%s.json',
'metafields' => 'metafields/%s.json',
'orders' => 'orders/%s.json',
'price_rules' => 'price_rules/%s.json',
'products' => 'products/%s.json',
'risks' => 'risks/%s.json',
'smart_collections' => 'smart_collections/%s.json',
'themes' => 'themes/%s.json',
'variants' => 'variants/%s.json',
'webhooks' => 'webhooks/%s.json',
'assets' => 'assets.json',
'customers' => 'customers/%s.json',
'discount_codes' => 'discount_codes/%s.json',
'disputes' => 'shopify_payments/disputes/%s.json',
'fulfillments' => 'fulfillments/%s.json',
'fulfillment_services' => 'fulfillment_services/%s.json',
'images' => 'images/%s.json',
'metafields' => 'metafields/%s.json',
'orders' => 'orders/%s.json',
'price_rules' => 'price_rules/%s.json',
'products' => 'products/%s.json',
'recurring_application_charges' => 'recurring_application_charges/%s.json',
'risks' => 'risks/%s.json',
'smart_collections' => 'smart_collections/%s.json',
'themes' => 'themes/%s.json',
'variants' => 'variants/%s.json',
'webhooks' => 'webhooks/%s.json',
];

/** @var array $resource_models */
protected static $resource_models = [
'assets' => Asset::class,
'customers' => Customer::class,
'discount_codes' => DiscountCode::class,
'disputes' => Dispute::class,
'fulfillments' => Fulfillment::class,
'fulfillment_services' => FulfillmentService::class,
'images' => Image::class,
'metafields' => Metafield::class,
'orders' => Order::class,
'price_rules' => PriceRule::class,
'products' => Product::class,
'risks' => Risk::class,
'smart_collections' => SmartCollections::class,
'themes' => Theme::class,
'variants' => Variant::class,
'webhooks' => Webhook::class,
'assets' => Asset::class,
'customers' => Customer::class,
'discount_codes' => DiscountCode::class,
'disputes' => Dispute::class,
'fulfillments' => Fulfillment::class,
'fulfillment_services' => FulfillmentService::class,
'images' => Image::class,
'metafields' => Metafield::class,
'orders' => Order::class,
'price_rules' => PriceRule::class,
'products' => Product::class,
'recurring_application_charges' => RecurringApplicationCharge::class,
'risks' => Risk::class,
'smart_collections' => SmartCollections::class,
'themes' => Theme::class,
'variants' => Variant::class,
'webhooks' => Webhook::class,
];

/** @var array $cursored_enpoints */
Expand Down
55 changes: 55 additions & 0 deletions tests/RecurringApplicationChargeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Dan\Shopify\Test;

use Carbon\Carbon;
use PHPUnit\Framework\TestCase;
use Dan\Shopify\Models\RecurringApplicationCharge;

class RecurringApplicationChargeTest extends TestCase
{
/** @test */
public function it_casts_all_attributes_to_their_native_types()
{
$model = $this->getModel();

$this->assertIsFloat($model->capped_amount);
$this->assertIsInt($model->id);
$this->assertIsFloat($model->price);
$this->assertIsInt($model->trial_days);

$this->assertInstanceOf(Carbon::class, $model->activated_on);
$this->assertInstanceOf(Carbon::class, $model->billing_on);
$this->assertInstanceOf(Carbon::class, $model->cancelled_on);
$this->assertInstanceOf(Carbon::class, $model->created_at);
$this->assertInstanceOf(Carbon::class, $model->trial_ends_on);
$this->assertInstanceOf(Carbon::class, $model->updated_at);
}

/**
* Make a new RecurringApplicationCharge instance.
*
* @return \Dan\Shopify\Models\RecurringApplicationCharge
*/
protected function getModel()
{
return new RecurringApplicationCharge([
'activated_on' => '2022-09-20T12:00:00-00:00',
'billing_on' => '2022-09-28T12:00:00-00:00',
'cancelled_on' => '2022-09-30T12:00:00-00:00',
'capped_amount' => "100",
'confirmation_url' => "https://jsmith.myshopify.com/admin/charges/confirm_recurring_application_charge?id=654381177&amp;signature=BAhpBHkQASc%3D--374c02da2ea0371b23f40781b8a6d5f4a520e77b",
'created_at' => '2022-09-20T12:00:00-00:00',
'id' => 675931192,
'name' => "Super Duper Expensive action",
'price' => "100.00",
'return_url' => "http://super-duper.shopifyapps.com",
'status' => "accepted",
'terms' => "$1 for 1000 emails",
'test' => null,
'trial_days' => 7,
'trial_ends_on' => '2022-09-27T12:00:00-00:00',
'updated_at' => '2022-09-20T12:00:00-00:00'
]);
}
}
103 changes: 103 additions & 0 deletions tests/RecurringApplicationChargesApiTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace Dan\Shopify\Test;

use Throwable;
use Dan\Shopify\Shopify;
use Orchestra\Testbench\TestCase;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;

class RecurringApplicationChargesApiTest extends TestCase
{
/**
* Create a new recurring application charge.
*
* @test
* @throws Throwable
*/
public function it_creates_a_new_recurring_application_charge(): void
{
Http::fake([
'*admin/recurring_application_charges.json' => $this->getResource(),
]);

$response = (new Shopify('shop', 'token'))->recurring_application_charges->post([
'name' => 'Charge Name',
'price' => 15.99,
'return_url' => 'https://phpunit-store.myshopifyapps.com',
'test' => true,
]);

Http::assertSent(function (Request $request) {
return $request->url() == 'https://shop.myshopify.com/admin/recurring_application_charges.json'
&& $request->method() == 'POST';
});

$this->assertEquals(123, $response['id']);
$this->assertEquals('Charge Name', $response['name']);
}

/**
* Get a list of recurring application charges.
*
* @test
* @throws Throwable
*/
public function it_gets_a_list_of_orders(): void
{
Http::fake();

(new Shopify('shop', 'token'))->recurring_application_charges->get();

Http::assertSent(function (Request $request) {
return $request->url() == 'https://shop.myshopify.com/admin/recurring_application_charges.json'
&& $request->method() == 'GET';
});
}

/**
* Fetch a recurring application charge by id.
*
* @test
* @throws Throwable
*/
public function it_gets_a_recurring_application_charge(): void
{
Http::fake();

(new Shopify('shop', 'token'))->recurring_application_charges->find(123);

Http::assertSent(function (Request $request) {
return $request->url() == 'https://shop.myshopify.com/admin/recurring_application_charges/123.json'
&& $request->method() == 'GET';
});
}

/**
* Get the resource response data for a recurring application charge.
*
* @return array
*/
protected function getResource()
{
return [
'activated_on' => '2022-09-20T12:00:00-00:00',
'billing_on' => '2022-09-28T12:00:00-00:00',
'cancelled_on' => '2022-09-30T12:00:00-00:00',
'capped_amount' => '100',
'confirmation_url' => 'https://jsmith.myshopify.com/admin/charges/confirm_recurring_application_charge?id=654381177&amp;signature=BAhpBHkQASc%3D--374c02da2ea0371b23f40781b8a6d5f4a520e77b',
'created_at' => '2022-09-20T12:00:00-00:00',
'id' => 123,
'name' => 'Charge Name',
'price' => '100.00',
'return_url' => 'http://super-duper.shopifyapps.com',
'status' => 'accepted',
'terms' => '$1 for 1000 emails',
'test' => null,
'trial_days' => 7,
'trial_ends_on' => '2022-09-27T12:00:00-00:00',
'updated_at' => '2022-09-20T12:00:00-00:00',
];
}
}

0 comments on commit 5c5b53c

Please sign in to comment.