joeymckenzie / givebutter-php
PHP API wrapper for Givebutter's public API.
Requires
- php: >=8.4
- joeymckenzie/wrapkit: ^0.1.18
- nesbot/carbon: ^3.0
Requires (Dev)
- ergebnis/composer-normalize: ^2.47
- guzzlehttp/guzzle: ^7.9
- laravel/pint: ^1.23
- mockery/mockery: ^1.6
- peckphp/peck: ^0.1.3
- pestphp/pest: ^3.8
- pestphp/pest-plugin-faker: ^v3.0
- pestphp/pest-plugin-type-coverage: ^3.5
- pestphp/pest-plugin-watch: ^3.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- rector/rector: ^2.1
- vlucas/phpdotenv: ^5.6
README

This package was heavily inspired by openai-php/client. Consider giving it a start to support the PHP community!
🧈 Givebutter PHP
Givebutter PHP is a plug 'n play HTTP client for Givebutter's public API.
Lookging for Laravel integration? I've got you covered! See joeymckenzie/givebutter-laravel for details.
Table of Contents
Getting started
The client is available as a composer packager that can be installed in any project using composer:
composer require joeymckenzie/givebutter-php
Since the client is compatible with any PSR-18 HTTP client, any commonly used HTTP client can be used thanks
to our dependency on php-http/discovery
. Once installed, you may start interacting
with Givebutter's API:
/** @var string $apiKey */ $apiKey = $_ENV['GIVEBUTTER_API_KEY']; $client = Givebutter::client($apiKey); // Create a campaign $createdCampaign = $client ->campaigns() ->create([ 'description' => 'This is a test campaign.', 'end_at' => CarbonImmutable::now()->toIso8601String(), 'goal' => 1000, 'subtitle' => 'subtitle', 'slug' => md5(uniqid('', true)), 'title' => 'title', 'type' => 'collect', ]); // Get a campaign $campaign = $client ->campaigns() ->get(441507); // Get all campaigns $campaigns = $client ->campaigns() ->list(); // Update a campaign $updatedCampaign = $client ->campaigns() ->update($campaign->id, [ 'description' => 'This is a test campaign.', 'goal' => 1500, ]); // Delete a campaign $deleteResponse = $client ->campaigns() ->delete($campaign->id);
For a comprehensive set of examples, take a look at the examples directory.
Notes
There's some current discrepancies between the API documentation and what the API actually returns, which several resources drifting from their schema definition. I do the best I can without internal knowledge of the API to adhere to the response schema, though it may be possible there will be breaking changes.
Due to the API response structure and the lack of resource enveloping, the response fields themselves may be null
at any point. One should always check for errors before attempting to use any properties on the responses:
$createdCampaign = $client ->campaigns() ->create([ 'description' => 'This is a test campaign.', 'end_at' => CarbonImmutable::now()->toIso8601String(), 'goal' => 1000, 'subtitle' => 'subtitle', 'slug' => md5(uniqid('', true)), 'title' => 'title', 'type' => 'collect', ]); if ($createdCampaign->hasErrors()) { // Do some error handling... } else { // Safely dereference response properties assert($campaign->id !== null); // Update a campaign $updatedCampaign = $client ->campaigns() ->update($createdCampaign->id, [ 'description' => 'This is another test campaign.', 'goal' => 1500, ]); }
Usage
Campaigns
Create a campaign
Creates a campaign from a specified payload.
$response = $client ->campaigns() ->create([ 'title' => 'Campaign title', 'description' => 'Campaign description.', 'end_at' => CarbonImmutable::now()->toIso8601String(), 'goal' => 10000, 'subtitle' => 'Campaign subtitle', 'slug' => 'campaignSlug123', 'type' => 'collect', ]); echo $response->data(); // GetCampaignResponse::class echo $response->id; // 42 echo $response->title; // 'Campaign title' echo $response->goal; // 10000 echo $response->toArray(); // ['id' => 42, ...]
Get all campaigns
Gets a list of available campaigns. Optionally, accepts a scope parameter.
$response = $client ->campaigns() ->list(); echo $response->data(); // array<int, GetCampaignResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 42, ...], 'meta' => [...], 'links' => [...]]
Get a campaign
Gets a single campaign.
$response = $client ->campaigns() ->get(42); echo $response->data(); // GetCampaignResponse::class echo $response->id; // 42 echo $response->title; // 'Campaign title' echo $response->goal; // 10000 echo $response->toArray(); // ['id' => 42, ...]
Update a campaign
Updates a campaign from a specified payload.
$response = $client ->campaigns() ->update(42, [ 'description' => 'Updated campaign description.', 'goal' => 20000, ]); echo $response->data(); // GetCampaignResponse::class echo $response->id; // 42 echo $response->title; // 'Campaign title' echo $response->goal; // 20000 echo $response->toArray(); // ['id' => 42, ...]
Delete a campaign
Deletes a campaign.
$response = $client ->campaigns() ->delete(42); echo $response->getStatusCode(); // 200
Campaign Members
Get all campaign members
Gets a list of available campaign members.
$response = $client ->campaigns() ->members() ->list(123); echo $response->data(); // array<int, GetCampaignMembersResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 123, ...], 'meta' => [...], 'links' => [...]]
Get a campaign member
Gets a single campaign member.
$response = $client ->campaigns() ->members() ->get(123, 42); echo $response->data(); // GetCampaignMemberResponse::class echo $response->id; // 123 echo $response->firstName; // 'John' echo $response->lastName; // 'Smith' echo $response->raised; // 10000 echo $response->toArray(); // ['id' => 123, ...]
Delete a campaign member
Deletes a campaign member.
$response = $client ->campaigns() ->members() ->delete(123, 42); echo $response->getStatusCode(); // 200
Campaign Teams
Get all campaign teams
Gets a list of available campaign teams.
$response = $client ->campaigns() ->teams() ->list(123); echo $response->data(); // array<int, GetCampaignTeamsResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 123, ...], 'meta' => [...], 'links' => [...]]
Get a campaign team
Gets a single campaign team.
$response = $client ->campaigns() ->teams() ->get(123, 42); echo $response->data(); // GetCampaignTeamResponse::class echo $response->id; // 123 echo $response->name; // 'Team 1' echo $response->logo; // 'https://domain.com/photo123' echo $response->raised; // 10000 echo $response->toArray(); // ['id' => 123, ...]
Contacts
Create a contact
Creates a contact from a specified payload.
$response = $client ->contacts() ->create([ 'first_name' => 'Michael', 'middle_name' => 'Gary', 'last_name' => 'Scott', 'email' => [ [ 'type' => 'work', 'value' => 'michael.scott@dundermifflin.com', ], ], 'phones' => [ [ 'type' => 'work', 'value' => '+15303567734', ], ], 'addresses' => [ [ 'address_1' => '123 Paper St.', 'city' => 'Scranton', 'state' => 'PA', 'zipcode' => '18507', 'country' => 'US', ], ], 'tags' => [ 'paper', 'dunder mifflin', ], 'dob' => '03/15/1965', 'company' => 'Dunder Mifflin', 'title' => 'Regional Manager', 'twitter_url' => 'https://twitter.com/dundermifflin', 'linkedin_url' => 'https://linkedin.com/in/dundermifflin', 'facebook_url' => 'https://facebook.com/dundermifflin', ]); echo $response->data(); // GetContactResponse::class echo $response->id; // 42 echo $response->firstName; // 'Michael' echo $response->lastName; // 'Scott' echo $response->toArray(); // ['id' => 42, ...]
Get all contacts
Gets a list of available contacts. Optionally, accepts a scope parameter.
$response = $client ->contacts() ->list(); echo $response->data(); // array<int, GetContactResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 42, ...], 'meta' => [...], 'links' => [...]]
Get a contact
Gets a single contact.
$response = $client ->contact() ->get(42); echo $response->data(); // GetContactResponse::class echo $response->id; // 42 echo $response->firstName; // 'Michael' echo $response->lastName; // 'Scott' echo $response->toArray(); // ['id' => 42, ...]
Update a contact
Updates a contact from a specified payload.
$response = $client ->campaigns() ->update(42, [ 'first_name' => 'Michael', 'last_name' => 'Scarn', 'company' => 'CIA', 'title' => 'Secret Agent' ]); echo $response->data(); // GetContactResponse::class echo $response->firstName; // 'Michael' echo $response->lastName; // 'Scarn' echo $response->company; // 'CIA' echo $response->title; // 'Secret Agent' echo $response->toArray(); // ['id' => 42, ...]
Archive a contact
Archives a contact.
$response = $client ->contacts() ->archive(42); echo $response->getStatusCode(); // 200
Restore a contact
Gets an archived contact.
$response = $client ->contacts() ->restore(42); echo $response->data(); // GetContactResponse::class echo $response->id; // 42 echo $response->firstName; // 'Michael' echo $response->lastName; // 'Scott' echo $response->toArray(); // ['id' => 42, ...]
Tickets
Get all tickets
Gets a list of tickets.
$response = $client ->tickets() ->list(); echo $response->data(); // array<int, GetTicketsResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 'abc123', ...], 'meta' => [...], 'links' => [...]]
Get a ticket
Gets a single ticket.
$response = $client ->tickets() ->get('ab123'); echo $response->data(); // GetTicketResponse::class echo $response->firstName; // 'Michael' echo $response->lastName; // 'Scott' echo $response->price; // 100 echo $response->toArray(); // ['id' => 'abc123', ...]
Transactions
Create a transaction
Creates a transaction from a specified payload.
$response = $client ->transactions() ->create([ 'amount' => 100.00, 'method' => 'cash', 'transacted_at' => CarbonImmutable::now()->addHour()->format('m/d/y'), 'campaign_code' => 'DEF456', 'first_name' => 'Micahel', 'last_name' => 'Scott', ]); echo $response->data(); // GetTransactionResponse::class echo $response->amount; // 100.00 echo $response->method; // 'cash' echo $response->campaignCode; // 'DEF456' echo $response->toArray(); // ['id' => 'abc123', ...]
Get all transactions
Gets a list of transactions.
$response = $client ->transactions() ->list(); echo $response->data(); // array<int, GetTransactionsResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 'abc123', ...], 'meta' => [...], 'links' => [...]]
Get a transactions
Gets a single transactions.
$response = $client ->transactions() ->get('ab123'); echo $response->data(); // GetTransactionResponse::class echo $response->amount; // 100.00 echo $response->method; // 'cash' echo $response->campaignCode; // 'DEF456' echo $response->toArray(); // ['id' => 'abc123', ...]
Payouts
Get all payouts
Gets a list of payouts.
$response = $client ->payouts() ->list(); echo $response->data(); // array<int, GetPayoutResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 'abc123', ...], 'meta' => [...], 'links' => [...]]
Get a payout
Gets a single payout.
$response = $client ->payout() ->get('ab123'); echo $response->data(); // GetPayoutResponse::class echo $response->amount; // 100.00 echo $response->fee; // 3.00 echo $response->tip; // 1.00 echo $response->toArray(); // ['id' => 'abc123', ...]
Plans
Get all plans
Gets a list of plans.
$response = $client ->plans() ->list(); echo $response->data(); // array<int, GetPlanResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 'abc123', ...], 'meta' => [...], 'links' => [...]]
Get a plan
Gets a single plan.
$response = $client ->plans() ->get('ab123'); echo $response->data(); // GetPlanResponse::class echo $response->amount; // 100.00 echo $response->firstName; // 'Michael' echo $response->lastName; // 'Scarn' echo $response->toArray(); // ['id' => 'abc123', ...]
Funds
Create a fund
Creates a fund from a specified payload.
$response = $client ->funds() ->create("Scott's Tots"); echo $response->data(); // GetFundResponse::class echo $response->id; // 'abc123' echo $response->name; // "Scott's Tots" echo $response->supporters; // 0 echo $response->toArray(); // ['id' => 'abc123', ...]
Get all funds
Gets a list of all available funds
$response = $client ->funds() ->list(); echo $response->data(); // array<int, GetFundsResponse::class> echo $response->meta; // Meta::class echo $response->links; // Links::class echo $response->toArray(); // ['data' => ['id' => 'abc123', ...], 'meta' => [...], 'links' => [...]]
Get a fund
Gets a single fund.
$response = $client ->funds() ->get('abc123'); echo $response->data(); // GetFundResponse::class echo $response->id; // 'abc123' echo $response->name; // "Scott's Tots" echo $response->supporters; // 0 echo $response->toArray(); // ['id' => 'abc123', ...]
Update a fund
Updates a fund from a specified payload.
$response = $client ->campaigns() ->update('abc123', "Scott's Tots", "ST"); echo $response->data(); // GetFundResponse::class echo $response->id; // 'abc123' echo $response->name; // "Scott's Tots" echo $response->code; // 'ST' echo $response->supporters; // 0 echo $response->toArray(); // ['id' => 'abc123', ...]
Delete a fund
Deletes a fund.
$response = $client ->funds() ->delete('abc123'); echo $response->getStatusCode(); // 200
Testing
The package provides a fake implementation of the Givebutter\Client
class that allows you to fake the API responses.
To test your code, ensure you swap the Givebutter\Client
class with the Givebutter\Testing\ClientFake
class in your
test case. Fake responses are returned in the order they are provided while creating the fake client. All responses
have a fake()
method that allows you to easily create a response object by only providing the parameters relevant
for your test case.
use Givebutter\Testing\ClientFake; use Givebutter\Responses\Campaigns\GetCampaignResponse; $fake = new ClientFake([ GetCampaignResponse::fake(GetCampaignFixture::class), ]); $campaign = $fake ->campaigns() ->create([ 'description' => 'This is a test campaign.', 'end_at' => CarbonImmutable::now()->toIso8601String(), 'goal' => 1000, 'subtitle' => 'subtitle', 'slug' => md5(uniqid('', true)), 'title' => 'title', 'type' => 'collect', ]); expect($campaign->description)->toBe('This is a test campaign.');
After the requests have been sent, there are various methods to ensure that the expected requests were sent:
// Assert completion create request was sent $fake->assertSent(CampaignsResource::class, function (string $method, array $parameters): bool { return $method === 'create' && $parameters[0]['title'] === 'title' && $parameters[0]['description'] === 'This is a test campaign.'; }); // Assert 2 completion create requests were sent $fake->assertSent(CampaignsResource::class, 2); // Assert no completion create requests were sent $fake->assertNotSent(CampaignsResource::class); // Assert no requests were sent $fake->assertNothingSent();
To write tests expecting the API request to fail, you may provide a Throwable
object as the response.
$fake = new ClientFake([ new Exception('Oops, something bad happened!') ]); // the `Exception` will be thrown $campaign = $fake ->campaigns() ->create([ 'description' => 'This is a test campaign.', 'end_at' => CarbonImmutable::now()->toIso8601String(), 'goal' => 1000, 'subtitle' => 'subtitle', 'slug' => md5(uniqid('', true)), 'title' => 'title', 'type' => 'collect', ]);
Givebutter PHP is an open-sourced software licensed under the MIT license.