Git Product home page Git Product logo

chartmogul-php's Introduction

Official ChartMogul API PHP Client

chartmogul-php provides convenient PHP bindings for ChartMogul's API.

Build Status


Installation | Configuration | Usage | Development | Contributing | License



Installation

This library requires php 5.5 or above.

For older php versions (< 7.4) use 1.x.x releases of this library.

For php version >=7.4 use the latest releases (5.x.x) of the library

The library doesn't depend on any concrete HTTP client libraries. Follow the instructions here to find out how to include a HTTP client.

Here's an example with Guzzle HTTP client:

composer require chartmogul/chartmogul-php:^5.0 php-http/guzzle6-adapter:^2.0.1 http-interop/http-factory-guzzle:^1.0

Configuration

Setup the default configuration with your ChartMogul api key:

require('./vendor/autoload.php');

ChartMogul\Configuration::getDefaultConfiguration()
    ->setApiKey('<YOUR_API_KEY>');

Test your authentication

print_r(ChartMogul\Ping::ping()->data);

Usage

try {
  $dataSources = ChartMogul\DataSource::all();
} catch(\ChartMogul\Exceptions\ForbiddenException $e){
  // handle authentication exception
} catch(\ChartMogul\Exceptions\ChartMogulException $e){
    echo $e->getResponse();
    echo $e->getStatusCode();
}

$ds = $dataSources->first();
var_dump($ds->uuid); // access Datasource properties
$dsAsArray = $ds->toArray(); // convert to array
$ds->destroy();

All array results are wrapped with Doctrine\Common\Collections\ArrayCollection for ease of access. See Exceptions for a list of exceptions thrown by this library.

Available methods in Import API:

Create Datasources

$ds = ChartMogul\DataSource::create([
  'name' => 'In-house Billing'
]);

Get a Datasource

ChartMogul\DataSource::retrieve($uuid);

List Datasources

ChartMogul\DataSource::all();

Delete a Datasource

$dataSources = ChartMogul\DataSource::all();
$ds = $dataSources->last();
$ds->destroy();

Customers

Import a Customer

ChartMogul\Customer::create([
    "data_source_uuid" => $ds->uuid,
    "external_id" => "cus_0003",
    "name" => "Adam Smith",
    "email" => "[email protected]",
    "country" => "US",
    "city" => "New York",
    "lead_created_at" => "2016-10-01T00:00:00.000Z",
    "free_trial_started_at" => "2016-11-02T00:00:00.000Z"
]);

List Customers

ChartMogul\Customer::all([
  'page' => 1,
  'data_source_uuid' => $ds->uuid
]);

Find Customer By External ID

ChartMogul\Customer::findByExternalId([
    "data_source_uuid" => "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id" => "cus_0001"
]);

Delete A Customer

$cus = ChartMogul\Customer::all()->last();
$cus->destroy();

Get a Customer

ChartMogul\Customer::retrieve($uuid);

Search for Customers

ChartMogul\Customer::search('[email protected]');

Merge Customers

ChartMogul\Customer::merge([
    'customer_uuid' => $cus1->uuid
], [
    'customer_uuid' => $cus2->uuid
]);

// alternatively:
ChartMogul\Customer::merge([
    'external_id' => $cus1->external_id,
    'data_source_uuid' => $ds->uuid
        ], [
    'external_id' => $cus2->external_id,
    'data_source_uuid' => $ds->uuid
]);

Update a Customer

$result = ChartMogul\Customer::update([
    'customer_uuid' => $cus1->uuid
        ], [
    'name' => 'New Name'
]);

Connect Subscriptions

ChartMogul\Customer::connectSubscriptions("cus_5915ee5a-babd-406b-b8ce-d207133fb4cb", [
    "subscriptions" => [
        [
            "data_source_uuid" => "ds_ade45e52-47a4-231a-1ed2-eb6b9e541213",
            "external_id" => "d1c0c885-add0-48db-8fa9-0bdf5017d6b0",
        ],
        [
            "data_source_uuid" => "ds_ade45e52-47a4-231a-1ed2-eb6b9e541213",
            "external_id" => "9db5f4a1-1695-44c0-8bd4-de7ce4d0f1d4",
        ],
    ]
]);

OR

$subscription1->connect("cus_5915ee5a-babd-406b-b8ce-d207133fb4cb", $subscriptions);

Customer Attributes

Retrieve Customer's Attributes

$customer = ChartMogul\Customer::retrieve($cus->uuid);
$customer->attributes;

Tags

Add Tags to a Customer

$customer = ChartMogul\Customer::retrieve($cus->uuid);
$tags = $customer->addTags("important", "Prio1");

Add Tags to Customers with email

$customers = ChartMogul\Customer::search('[email protected]');

foreach ($customers->entries as $customer) {
    $customer->addTags('foo', 'bar', 'baz');
}

Remove Tags from a Customer

$customer = ChartMogul\Customer::retrieve($cus->uuid);
$tags = $customer->removeTags("important", "Prio1");

Custom Attributes

Add Custom Attributes to a Customer

$customer = ChartMogul\Customer::retrieve($cus->uuid);
$custom = $customer->addCustomAttributes(
    ['type' => 'String', 'key' => 'channel', 'value' => 'Facebook'],
    ['type' => 'Integer', 'key' => 'age', 'value' => 8 ]
);

Add Custom Attributes to Customers with email

$customers = ChartMogul\Customer::search('[email protected]');

foreach ($customers->entries as $customer) {
    $customer->addCustomAttributes(
        ['type' => 'String', 'key' => 'channel', 'value' => 'Facebook'],
        ['type' => 'Integer', 'key' => 'age', 'value' => 8 ]
    );
}

Update Custom Attributes of a Customer

$customer = ChartMogul\Customer::retrieve($cus->uuid);
$custom = $customer->updateCustomAttributes(
    ['channel' => 'Twitter'],
    ['age' => 18]
);

Remove Custom Attributes from a Customer

$customer = ChartMogul\Customer::retrieve($cus->uuid);
$tags = $customer->removeCustomAttributes("age", "channel");

List Contacts from a customer

$customer = ChartMogul\Customer::retrieve($uuid);
$contacts = $customer->contacts([
  'cursor' => 'aabbccdd...'
]);

Create a Contact from a customer

$customer = ChartMogul\Customer::retrieve($uuid);
$new_customer = $customer->createContact([
  "data_source_uuid" => "ds_00000000-0000-0000-0000-000000000000",
  "first_name" => "Adam",
  "last_name" => "Smith",
]);

List Customer Notes from a customer

$customer = ChartMogul\Customer::retrieve($uuid);
$customer_notes = $customer->notes([
  'cursor' => 'aabbccdd...'
]);

Create a Customer Note from a customer

$customer = ChartMogul\Customer::retrieve($uuid);
$new_customer_note = $customer->createNote([
  'type' => 'note',
  'text' => 'This is a note'
]);

List Opportunities from a customer

$customer = ChartMogul\Customer::retrieve($uuid);
$opportunities = $customer->opportunities([
  'cursor' => 'aabbccdd...'
]);

Create an Opportunity from a customer

$customer = ChartMogul\Customer::retrieve($uuid);
$new_opportunity = $customer->createOpportunity([
  'owner' => '[email protected]',
  'pipeline' => 'Sales',
  'pipeline_stage' => 'Qualified',
  'estimated_close_date' => '2022-03-30',
  'currency' => 'USD',
  'amount_in_cents' => 10000,
  'type' => 'one-time',
  'forecast_category' => 'Best Case',
  'win_likelihood' => 80,
  'custom' => [{key: 'custom_key', value: 'custom_value'}]
]);

Customer Notes

List Customer Notes

$customer_notes = ChartMogul\CustomerNote::all([
    'customer_uuid' => $uuid,
    'cursor' => 'aabbccdd...'
])

Create a Customer Note

$customer_note = ChartMogul\CustomerNote::create([
    'customer_uuid': $uuid,
    'type' => 'note',
    'text' => 'This is a note'
])

Get a Customer Note

$customer_note = ChartMogul\CustomerNote::retrieve($note_uuid)

Update a Customer Note

$updated_customer_note = ChartMogul\CustomerNote::update($note_uuid, [
  'text' => 'This is a new note'
]);

Delete a Customer Note

$customer_note = ChartMogul\CustomerNote::retrieve($note_uuid)
$customer_note->destroy();

Contacts

List Contacts

$contacts = ChartMogul\Contacts::all([
  'cursor' => 'aabbccdd...'
]);

Create a Contact

$new_contact = ChartMogul\Contact::create([
  "customer_uuid" => "cus_00000000-0000-0000-0000-000000000000",
  "data_source_uuid" => "ds_00000000-0000-0000-0000-000000000000",
  "first_name" => "Adam",
  "last_name" => "Smith",
]);

Get a Contact

$contact = ChartMogul\Contact::retrieve($uuid);

Delete A Contact

$contact = ChartMogul\Contact::retrieve($uuid);
$contact->destroy();

Update a Contact

$updated_contact = ChartMogul\Contact::update([
    'contact_uuid' => $uuid
        ], [
    'first_name' => 'New Name'
]);

Merge Contacts

$merged_contact = ChartMogul\Contact::merge($into_contact_uuid, $from_contact_uuid);

Opportunities

List Opportunities

$opportunities = ChartMogul\Opportunity::all([
    'cursor' => 'aabbccdd...'
])

Create an Opportunity

$opportunity = ChartMogul\Opportunity::create([
    'customer_uuid' => $uuid,
    'owner' => '[email protected]',
    'pipeline' => 'New business 1',
    'pipeline_stage' => 'Discovery',
    'estimated_close_date' => '2023-12-22',
    'currency' => 'USD',
    'amount_in_cents' => 100,
    'type' => 'recurring',
    'forecast_category' => 'pipeline',
    'win_likelihood' => 3,
    'custom' => [{ 'key': 'from_campaign', 'value': true }]
])

Get an Opportunity

$opportunity = ChartMogul\Opportunity::retrieve($opportunity_uuid)

Update an Opportunity

$updated_opportunity = ChartMogul\Opportunity::update($opportunity_uuid, [
  'estimated_close_date' => '2024-12-22',
]);

Delete an Opportunity

$opportunity = ChartMogul\Opportunity::retrieve($opportunity_uuid)
$opportunity->destroy();

Plans

Import a Plan

ChartMogul\Plan::create([
    "data_source_uuid" => $ds->uuid,
    "name" => "Bronze Plan",
    "interval_count" => 1,
    "interval_unit" => "month",
    "external_id" => "plan_0001"
]);

Get a Plan by UUID

ChartMogul\Plan::retrieve($uuid);

List Plans

$plans = ChartMogul\Plan::all([
  'page' => 1
]);

Delete A Plan

$plan = ChartMogul\Plan::all()->last();
$plan->destroy();

Update A Plan

$plan = ChartMogul\Plan::update(["plan_uuid" => $plan->uuid], [
            "name" => "Bronze Monthly Plan",
            "interval_count" => 1,
            "interval_unit" => "month"
]);

Subscription Events

List Subscriptions Events

$subscription_events = ChartMogul\SubscriptionEvent::all();

Create Subscription Event

ChartMogul\SubscriptionEvent::create(['subscription_event' => [
    "external_id" => "evnt_026",
    "customer_external_id" => "cus_0003",
    "data_source_uuid" => $ds->uuid,
    "event_type" => "subscription_start_scheduled",
    "event_date" => "2022-03-30",
    "effective_date" => "2022-04-01",
    "subscription_external_id" => "sub_0001",
    "plan_external_id" => "plan_0001",
    "currency" => "USD",
    "amount_in_cents" => 1000
    "quantity" => 1
]]);

Delete Subscription Event

ChartMogul\SubscriptionEvent::destroyWithParams(['subscription_event' => [
    "id" => "some_event_id"
]]);

Update Subscription Event

ChartMogul\SubscriptionEvent::updateWithParams(['subscription_event' => [
    "id" => "some_event_id",
    "currency" => "EUR",
    "amount_in_cents" => "100"
]]);

Plan Groups

Create a Plan Group

ChartMogul\PlanGroup::create([
    "name" => "Bronze Plan",
    "plans" => [$plan_uuid_1, $plan_uuid_2],
]);

Get a Plan Group by UUID

ChartMogul\PlanGroup::retrieve($uuid);

List Plan Groups

$plan_groups = ChartMogul\PlanGroup::all([
  'page' => 1
]);

Delete A Plan Group

$plan_group = ChartMogul\PlanGroup::all()->last();
$plan_group->destroy();

Update A Plan Group

$plan_group = ChartMogul\PlanGroup::update(
  ["plan_group_uuid" => $plan_group->uuid],
  [
  "name" => "A new plan group name",
  "plans" => [$plan_uuid_1, $plan_uuid_2]
]);

List Plans In A Plan Group

$plan_group_plans = ChartMogul\PlanGroups\Plan::all(
  ["plan_group_uuid" => $plan_group->uuid]
);

Invoices

Import Invoices

$plan = ChartMogul\Plan::all()->first();
$cus = ChartMogul\Customer::all()->first();

$line_item_1 = new ChartMogul\LineItems\Subscription([
    'subscription_external_id' => "sub_0001",
    'subscription_set_external_id' => 'set_0001',
    'plan_uuid' =>  $plan->uuid,
    'service_period_start' =>  "2015-11-01 00:00:00",
    'service_period_end' =>  "2015-12-01 00:00:00",
    'amount_in_cents' => 5000,
    'quantity' => 1,
    'discount_code' => "PSO86",
    'discount_amount_in_cents' => 1000,
    'tax_amount_in_cents' => 900,
    'transaction_fees_currency' => "EUR",
    'discount_description' => "5 EUR"
]);

$line_item_2 = new ChartMogul\LineItems\OneTime([
    "description" => "Setup Fees",
    "amount_in_cents" => 2500,
    "quantity" => 1,
    "discount_code" => "PSO86",
    "discount_amount_in_cents" => 500,
    "tax_amount_in_cents" => 450,
    "transaction_fees_currency" => "EUR",
    "discount_description" => "2 EUR"
]);

$transaction = new ChartMogul\Transactions\Payment([
    "date" => "2015-11-05T00:14:23.000Z",
    "result" => "successful"
]);

$invoice = new ChartMogul\Invoice([
    'external_id' => 'INV0001',
    'date' =>  "2015-11-01 00:00:00",
    'currency' => 'USD',
    'due_date' => "2015-11-15 00:00:00",
    'line_items' => [$line_item_1, $line_item_2],
    'transactions' => [$transaction]
]);

$ci = ChartMogul\CustomerInvoices::create([
    'customer_uuid' => $cus->uuid,
    'invoices' => [$invoice]
]);

List Customer Invoices

$ci = ChartMogul\CustomerInvoices::all([
    'customer_uuid' => $cus->uuid,
    'page' => 1,
    'per_page' => 200
]);

List Invoices

$invoices = ChartMogul\Invoice::all([
    'external_id' => 'my_invoice',
    'page' => 1,
    'per_page' => 200
]);

Retrieve an Invoice

$invoice = ChartMogul\Invoice::retrieve('inv_uuid');

Transactions

Create a Transaction

ChartMogul\Transactions\Refund::create([
    "invoice_uuid" => $ci->invoices[0]->uuid,
    "date" => "2015-12-25 18:10:00",
    "result" => "successful"
]);

The same can be done with Payment class.

Subscriptions

List Customer Subscriptions

$subscriptions = $cus->subscriptions();

Cancel Customer Subscriptions

$subscription = new ChartMogul\Subscription(["uuid" => $subsUUID])
// or use some existing instance of subsctiption, eg. fetched from Customer->subscriptions
$canceldate = '2016-01-01T10:00:00.000Z';
$subscription->cancel($canceldate);

Or set the cancellation dates:

$subscription = new ChartMogul\Subscription(["uuid" => $subsUUID])
$cancellationDates = ['2016-01-01T10:00:00.000Z', '2017-01-01T10:00:00.000Z']
$subscription->setCancellationDates($cancellationDates)

Metrics API

Retrieve all key metrics

ChartMogul\Metrics::all([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
    'interval' => 'month',
    'geo' => 'GB',
    'plans' => $plan->name
]);

Retrieve MRR

ChartMogul\Metrics::mrr([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
    'interval' => 'month',
    'geo' => 'GB',
    'plans' => $plan->name
]);

Retrieve ARR

ChartMogul\Metrics::arr([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
    'interval' => 'month'
]);

Retrieve Average Revenue Per Account (ARPA)

ChartMogul\Metrics::arpa([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
    'interval' => 'month'
]);

Retrieve Average Sale Price (ASP)

ChartMogul\Metrics::asp([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
    'interval' => 'month',
]);

Retrieve Customer Count

ChartMogul\Metrics::customerCount([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
    'interval' => 'month',
]);

Retrieve Customer Churn Rate

ChartMogul\Metrics::customerChurnRate([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
]);

Retrieve MRR Churn Rate

ChartMogul\Metrics::mrrChurnRate([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
]);

Retrieve LTV

ChartMogul\Metrics::ltv([
    'start-date' => '2015-01-01',
    'end-date' => '2015-11-24',
]);

List Customer Subscriptions

ChartMogul\Metrics\Customers\Subscriptions::all([
    "customer_uuid" => $cus->uuid
]);

List Customer Activities

ChartMogul\Metrics\Customers\Activities::all([
    "customer_uuid" => $cus->uuid
]);

List Activities

ChartMogul\Metrics\Activities::all([
    'start-date' => '2020-06-02T00:00:00Z',
    'per-page' => 100
]);

**Create an Activities Export**

```php
ChartMogul\Metrics\ActivitiesExport::create([
    'start-date' => '2020-06-02T00:00:00Z',
    'end-date' =>  '2021-06-02T00:00:00Z'
    'type' => 'churn'
]);

Retrieve an Activities Export

$id = '7f554dba-4a41-4cb2-9790-2045e4c3a5b1';
ChartMogul\Metrics\ActivitiesExport::retrieve($id);

Account

Retrieve Account Details

ChartMogul\Account::retrieve();

Exceptions

The library throws following Exceptions:

  • ChartMogul\Exceptions\ChartMogulException
  • ChartMogul\Exceptions\ConfigurationException
  • ChartMogul\Exceptions\ForbiddenException
  • ChartMogul\Exceptions\NotFoundException
  • ChartMogul\Exceptions\ResourceInvalidException
  • ChartMogul\Exceptions\SchemaInvalidException

The following table describes the public methods of the error object.

Methods Type Description
getMessage() string The error message
getStatusCode() number When the error occurs during an HTTP request, the HTTP status code.
getResponse() array or string HTTP response as array, or raw response if not parsable to array

Rate Limits & Exponential Backoff

The library will keep retrying if the request exceeds the rate limit or if there's any network related error. By default, the request will be retried for 20 times (approximated 15 minutes) before finally giving up.

You can change the retry count using Configuration object:

ChartMogul\Configuration::getDefaultConfiguration()
    ->setApiKey('<YOUR_API_KEY>')
    ->setRetries(15); //0 disables retrying

Development

You need Docker installed locally to use our Makefile workflow.

  • Fork it.
  • Create your feature branch (git checkout -b my-new-feature).
  • Install dependencies: make build.
  • Install Composer vendor dependencies with make composer install
  • Write tests for your new features. Run tests and check test coverage with make test.
  • To run any composer commands or php scripts, use make composer <commands> or make php <script>.
  • If all tests are passed, push to the branch (git push origin my-new-feature).
  • Create a new Pull Request.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/chartmogul/chartmogul-php.

License

The library is available as open source under the terms of the MIT License.

The MIT License (MIT)

Copyright (c) 2019 ChartMogul Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

chartmogul-php's People

Contributors

alpdal avatar aymericderbois avatar bilbof avatar briwa avatar countless-integers avatar dina920 avatar ftipalek avatar gjuric avatar h3llr4iser avatar hassansin avatar imhmdb avatar kamilpavlicko avatar kmossco avatar kremalicious avatar mariabraganca avatar muratsac avatar pkopac avatar pscheit avatar sbrych avatar sevastyanovio avatar slepic avatar soeunsona avatar spyrbri avatar srikalab avatar swember avatar vincentlanglet avatar wh1tew0lf avatar whobubble avatar ytvinay avatar

Stargazers

 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

chartmogul-php's Issues

Version 2.2.0 is breaking 2.1.0

Because of strict return types, version 2.2 is not compatible with 2.1, therefore all projects requiring it as ^2.1 will potentially have problems (I did).

Bug: Customer::get()

When using ChartMogul\Customer::get("UUID") I am getting the following error:

FatalThrowableError in GetTrait.php line 19:
Using $this when not in object context

Replace static api with instance services

Currently, it is very easy to call the static methods.

$c1 = Customer::findByExternalId($extId1);
$c2 = Customer::findByExternalId($extId2);

But since we can inject own http client, it becomes cumbersome to call the static api of this lib.

$client = createCustomClient();
$c1 = Customer::findByExternalId($extId1, $client);
$c2 = Customer::findByExternalId($extId2, $client);

note: hehe actually looking at the code, findByExternalId currently does not even support passing the client as second argument which even makes an inconsistent and partially inaccessible api.

Let me even explain why I believe passing a custom client instance (even if the default is passed) is better and should be the prefered if not the only option.
See the first snippet, see how the client is never passed to the static methods? When it is not passed it undergoes the entire client building process again and again on every call to the static api, which is of course very ineffective.

Let's see how this can be implemented obeying the single responsibility and dependency inversion principles:

$client = createCustomClient();
$customers = new CustomersService($client); // or pass no client and default may be built, but personally i would always inject
$c1 = $customers->findByExternalId($extId1);
$c2 = $customers->findByExternalId($extId2);

See how we removed the client argument from all methods that were formerly static and part of a class that should only be responsible for holding a single customer data.

Of course this makes a completley new api and lot has to be refactored in both the lib and its consumers. However there is quite a smooth migration path:

First create the service classes and delegate to the static api while also deprecating the static api:

class CustomersService
{
  public function __construct(private ClientInterface $client) {}

  public function findByExternalId(string $externalId): ?Cursomer
  {
     return Customer::findByExternalId($externalId, $this->client);
  }
}

class Customer
{
  /** @deprecated use CustomersService */
  public function findByExternalId(string $externalId, ?ClientInterface $client = null): self
  {
    if ($client === null) {
      trigger_user_error(E_USER_DEPRECATED, '...');
    }

    // previous implementation
  }
}

Then it can be released allowing consumers to change their code.
And then you can continue working on moving the logic to the services themselves while keeping the deprecated method but adding user errors

class Customer
{
  /** @deprecated use CustomersService */
  public function findByExternalId(string $externalId, ?ClientInterface $client = null): self
  {
    trigger_user_error(E_USER_DEPRECATED, '...');
    return (new CustomersService($client))->findByExternalId($externalId);
  }
}

This all can even be done method by method, service by sevice, not at all needed to do it in one go and it will be minor releases all the time.

But when it is all finished, all logic is in services and all data classes delegate to temporary created service instance, then in one go remove all the deprecated methods and release a new major version. As the minor versions were all emitting deprecations and new way to achieve same results was always possible, consumers have had quite a lot of time for transition and the transition itself is quite straight forward.

As a cherry on top, I propose to also remove any nullable constructors parameters in the services and the client and remove http client discovery so that the end code must look minimally like this:

$psrHttpClient = psrClient(); // always custom
$config = new Configuration(); // this is the only one that has defaults and only scalars
$client = new Client($config, $psrHttpClient, $psrRequestFactory);

for simplification you could keep the client autodiscovery but this should be optional (require-dev in composer) and in a factory class:

class ClientFactory
{
  public static function create(
        Configuration $config = null,
        HttpClient $client = null,
        RequestFactoryInterface $requestFactory = null
    ): ClientInterface {
        if (!\class_exists(HttpClientDiscovery::class) || !\class_exists(Psr17FactoryDiscovery::class)) {
          throw new \Exception('Please install optional dependency php-http/discovery or pass you own psr client and request factory instances');
        }
        $config ?: new Configuration();
        $client = $client ?: HttpClientDiscovery::find();
        $requestFactory = $requestFactory ?: Psr17FactoryDiscovery::findRequestFactory();
        return new Client($config, $client, $requestFactory);
    }
}

PHP 8 support?

Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires chartmogul/chartmogul-php ^4.0.0 -> satisfiable by chartmogul/chartmogul-php[4.0.0].
    - chartmogul/chartmogul-php 4.0.0 requires php ^7.1 -> your php version (8.0.8) does not satisfy that requirement.

Laravel 8 not supporting

  • chartmogul/chartmogul-php 2.2.4 requires php-http/client-implementation ^1.0 -> satisfiable by php-http/guzzle6-adapter[dev-master, 2.x-dev, v2.0.1].
    • php-http/guzzle6-adapter v2.0.1 requires guzzlehttp/guzzle ^6.0 -> satisfiable by guzzlehttp/guzzle[6.0.0, 6.0.1, 6.0.2, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.3.0, 6.3.1, 6.3.2, 6.3.3, 6.4.0, 6.4.1, 6.5.0, 6.5.1, 6.5.2, 6.5.3, 6.5.4, 6.5.5, 6.5.x-dev].
    • php-http/guzzle6-adapter 2.x-dev requires guzzlehttp/guzzle ^6.0 -> satisfiable by guzzlehttp/guzzle[6.0.0, 6.0.1, 6.0.2, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.3.0, 6.3.1, 6.3.2, 6.3.3, 6.4.0, 6.4.1, 6.5.0, 6.5.1, 6.5.2, 6.5.3, 6.5.4, 6.5.5, 6.5.x-dev].
    • php-http/guzzle6-adapter dev-master requires guzzlehttp/guzzle ^6.0 -> satisfiable by guzzlehttp/guzzle[6.0.0, 6.0.1, 6.0.2, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.3.0, 6.3.1, 6.3.2, 6.3.3, 6.4.0, 6.4.1, 6.5.0, 6.5.1, 6.5.2, 6.5.3, 6.5.4, 6.5.5, 6.5.x-dev].
    • Conclusion: don't install guzzlehttp/guzzle 6.5.x-dev

Please update README

Instead of

ChartMogul\Configuration::getDefaultConfiguration()->setApiKey('<YOUR_API_KEY>');

It should be:

ChartMogul\Configuration::getDefaultConfiguration()->setAccountToken('<YOUR_API_KEY>');

ChartMogul\Configuration::getDefaultConfiguration()->setSecretKey('<YOUR_API_KEY>');

chartmogul api does not support http2 requests

Working example

curl -X POST "https://api.chartmogul.com/v1/data_sources" -v --http1.1 \
     -u xxxxxx:xxxxxx \
     -H "Content-Type: application/json" \
     -d '{
          "name": "In-house billing"
         }'

Not working example (if we assume that you are using latest OSx version or latest linux distro):

curl -X POST "https://api.chartmogul.com/v1/data_sources" -v \
     -u xxxxxx:xxxxxx \
     -H "Content-Type: application/json" \
     -d '{
          "name": "In-house billing"
         }'

Same with this lib, it tries to use http2 connection instead of http1.1 and every POST request fails. GET requests works as expected.

Static function should not be abstract

PHP Strict standards: Static function ChartMogul\Resource\EntryTrait::getEntryClass() should not be abstract in /var/www/smartlook/application/vendor/chartmogul/chartmogul-php/src/Resource/EntryTrait.php:12

404 error on subscription list

The following code trows a 404 if the specified customer doesn't have any subscriptions, if it is just a lead.

$cus = new ChartMogul\Customer([
			"uuid" => $user->cm_uuid
			    ]);
$subscriptions = $cus->subscriptions();

ChartMogul\Customer::findByExternalId Doesn't Work

I was able to add customers but unable to List Customers, Search by email or Find by External_Id, nor can I find plans by external_id they just don't work.

I get a response code 200, but with no result data. Dies silently.

Readme suggests abandoned package php-http/guzzle6-adapter

The readme suggests using php-http/guzzle6-adapter, but following that advice leads to a warning

Package php-http/guzzle6-adapter is abandoned, you should avoid using it. Use guzzlehttp/guzzle or php-http/guzzle7-adapter instead.

Probably, we should update that (the package suggested by the warning seems to work just fine)

Please don't rely on httpguzzle directly

Since the repo does require to use guzzle 6, it's hard to upgrade.

Better rely on the psr client interface for http clients and let the people plug in guzzle 6 or 7 or symonfy http client

thanks so much
philipp

cURL error 6: getaddrinfo() thread failed to start (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

After 100-200 requests to chartmogul php fails with exception " cURL error 6: getaddrinfo() thread failed to start (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)" Retrying same request works as expected, but it fails again after 100-200 requests.

Sometimes it fails with "Http\Client\Exception\NetworkException : cURL error 6: Could not resolve host: api.chartmogul.com (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)" error too.

Laravel

Any tips on how to include this in a Laravel project, doesn't seem to be picking it up, it's getting the namespace's confused Class 'App\Http\Controllers\ChartMogul\Configuration' not found

Class not found

Was just trying this out within the Laravel framework and I can't seem to get it to work as expected, it seems to find the Configuration class fine, but it's failing on almost any other, and I am getting:

Fatal error: Class 'ChartMogul\DataSource' not found

or if I try Ping:

Fatal error: Class 'ChartMogul\Ping' not found

Customer->subscriptions() doesn't work

$cus = new ChartMogul\Customer([
"uuid" => $user->uuid
]);

$subscriptions = $cus->subscriptions();

results in:

PHP Fatal error: Uncaught exception 'ChartMogul\Exceptions\ChartMogulException' with message 'Subscription request error has occurred. Response:

<title>We're sorry, but something went wrong (500)</title> <style> body { background-color: #EFEFEF; color: #2E2F30; text-align: center; font-family: arial, sans-serif; margin: 0; }

div.dialog {
width: 95%;
max-width: 33em;
margin: 4em auto 0;
}

div.dialog > div {
border: 1px solid #CCC;
border-right-color: #999;
border-left-color: #999;
border-bottom-color: #BBB;
border-top: #B00100 solid 4px;
border-top-left-radius: 9px;
border-top-right-radius: 9px;
background-color: white;
padding: 7px 12% 0;
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
}

h1 {
font-size: 100%;
color: #730E15;
line-height: 1.5em;
}

div.dialog > p {
margin: 0 0 1em;
padding: 1em;
background-colo in /home/bpzadmin/public_html/wp-content/mu-plugins/bookpagez-chart-mogul/chart-mogul/vendor/chartmogul/chartmogul-php/src/Http/Client.php on line 222

Error: "Undefined constant 'ChartMogul\DEFAULT_MAX_RETRIES'" after upgrading to PHP 8.2 and Symfony 6.3

I'm experiencing an issue after upgrading my project to PHP 8.2 and Symfony 6.3. The error message I'm getting is:

Undefined constant "ChartMogul\DEFAULT_MAX_RETRIES"

I managed to work around the issue by moving the constant inside the Configuration class like this:

<?php

namespace ChartMogul;

/**
 *
 * @codeCoverageIgnore
 */
class Configuration
{

    const DEFAULT_MAX_RETRIES = 20;

    /**
     * @var null|Configuration
     */
    private static $defaultConfiguration = null;

    /**
     * @var string
     */
    private $accountToken = '';
    /**
     * @var string
     */
    private $secretKey = '';
    /**
     * @var int
     * maximum retry attempts
     */
    private $retries = self::DEFAULT_MAX_RETRIES;

    /**
     * Creates new config object from accountToken and secretKey
     * @param string $accountToken
     * @param string $secretKey
     */
    public function __construct($accountToken = '', $secretKey = '', $retries = self::DEFAULT_MAX_RETRIES)
    {
        $this->accountToken = $accountToken;
        $this->secretKey = $secretKey;
        $this->retries = $retries;
    }

Related with PR #112

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.