├── config
├── .gitkeep
└── laravel-bitpay.php
├── src
├── .DS_Store
├── Http
│ ├── Controllers
│ │ ├── Controller.php
│ │ └── WebhookController.php
│ └── Middleware
│ │ └── VerifyWebhookSignature.php
├── Constants
│ ├── WebhookAutoPopulate.php
│ └── BitPayConstants.php
├── LaravelBitpayFacade.php
├── Events
│ └── BitpayWebhookReceived.php
├── Actions
│ ├── ManageCurrencies.php
│ ├── ManageLedgers.php
│ ├── ManageExchangeRates.php
│ ├── ManageSettlements.php
│ ├── ManageRefunds.php
│ ├── ManageBills.php
│ ├── ManageSubscriptions.php
│ ├── ManageInvoices.php
│ ├── ManageRecipients.php
│ └── ManagePayouts.php
├── Exceptions
│ └── InvalidConfigurationException.php
├── LaravelBitpay.php
├── LaravelBitpayServiceProvider.php
├── Traits
│ ├── MakesHttpRequests.php
│ └── CreateKeypairTrait.php
└── Console
│ └── CreateKeypairCommand.php
├── .gitignore
├── .github
├── FUNDING.yml
├── tmp_ISSUE_TEMPLATE.yml
└── workflows
│ └── php.yml
├── tests
├── LaravelBitpayCurrencyTest.php
├── LaravelBitpayRefundTest.php
├── LaravelBitpayRecipientTest.php
├── LaravelBitpayBillTest.php
├── LaravelBitpayInvoiceTest.php
├── LaravelBitpayPayoutTest.php
└── LaravelBitpaySubscriptionTest.php
├── phpunit.xml.dist
├── LICENSE.md
├── CONTRIBUTING.md
├── CHANGELOG.md
├── composer.json
├── MIGRATION.md
├── README.md
└── .editorconfig
/config/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vrajroham/laravel-bitpay/HEAD/src/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | composer.lock
3 | docs
4 | vendor
5 | coverage
6 | .idea
7 | .phpunit.result.cache
8 | .php_cs.cache
9 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [vrajroham, alexstewartja]
4 | patreon: vrajroham
5 | custom: ["https://www.buymeacoffee.com/asja", "https://bit.ly/asja_paypal_lara_bitpay"]
6 |
--------------------------------------------------------------------------------
/src/Http/Controllers/Controller.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::Currency() instanceof Currency);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/LaravelBitpayRefundTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::Refund() instanceof Refund);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/LaravelBitpayRecipientTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::PayoutRecipient() instanceof PayoutRecipient);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Events/BitpayWebhookReceived.php:
--------------------------------------------------------------------------------
1 | payload = $payload;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/LaravelBitpayBillTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::Bill() instanceof Bill);
16 | }
17 |
18 | /** @test */
19 | public function isInstanceOfBillItem()
20 | {
21 | $this->assertEquals(true, LaravelBitpay::BillItem() instanceof BillItem);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Http/Controllers/WebhookController.php:
--------------------------------------------------------------------------------
1 | middleware(VerifyWebhookSignature::class);
14 | }
15 |
16 | public function handleWebhook(Request $request)
17 | {
18 | $payload = json_decode($request->getContent(), true);
19 | BitpayWebhookReceived::dispatch($payload);
20 |
21 | return response('OK', 200);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/LaravelBitpayInvoiceTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::Invoice() instanceof BitPaySDKInvoice);
17 | }
18 |
19 | /** @test */
20 | public function isInstanceOfBuyer()
21 | {
22 | $this->assertEquals(true, LaravelBitpay::Buyer() instanceof Buyer);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Http/Middleware/VerifyWebhookSignature.php:
--------------------------------------------------------------------------------
1 | getMessage(), $exception);
27 | }
28 |
29 | return $next($request);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Actions/ManageCurrencies.php:
--------------------------------------------------------------------------------
1 | setCode($code);
22 | }
23 |
24 | return $currency;
25 | }
26 |
27 | /**
28 | * Fetch the supported currencies.
29 | *
30 | * @link https://bitpay.com/api/#rest-api-resources-currencies-retrieve-the-supported-currencies
31 | * @return array A list of supported BitPay Currency objects.
32 | * @throws BitPayException BitPayException class
33 | */
34 | public static function getCurrencies(): array
35 | {
36 | return (new self())->client->getCurrencies();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Exceptions/InvalidConfigurationException.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::Payout() instanceof Payout);
19 | }
20 |
21 | /** @test */
22 | public function isInstanceOfPayoutBatch()
23 | {
24 | $this->assertEquals(true, LaravelBitpay::PayoutBatch() instanceof PayoutBatch);
25 | }
26 |
27 | /** @test */
28 | public function isInstanceOfPayoutInstruction()
29 | {
30 | $this->assertEquals(true, LaravelBitpay::PayoutInstruction(
31 | 10,
32 | RecipientReferenceMethod::EMAIL,
33 | 'test@example.com'
34 | ) instanceof PayoutInstruction);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | tests
15 |
16 |
17 |
18 |
19 | src/
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/LaravelBitpaySubscriptionTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(true, LaravelBitpay::Subscription() instanceof Subscription);
19 | }
20 |
21 | /** @test */
22 | public function isInstanceOfSubscriptionItem()
23 | {
24 | $this->assertEquals(true, LaravelBitpay::SubscriptionItem() instanceof SubscriptionItem);
25 | }
26 |
27 | /** @test */
28 | public function isInstanceOfBillData()
29 | {
30 | $this->assertEquals(true, LaravelBitpay::BillData(
31 | Currency::USD,
32 | 'test@example.com',
33 | '2021-12-01T09:00:00Z',
34 | []) instanceof BillData);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Vaibhavraj Roham
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and will be fully **credited**.
4 |
5 | We accept contributions via Pull Requests on [Github](https://github.com/vrajroham/laravel-bitpay).
6 |
7 |
8 | ## Pull Requests
9 |
10 | - **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer).
11 |
12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests.
13 |
14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
15 |
16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option.
17 |
18 | - **Create feature branches** - Don't ask us to pull from your master branch.
19 |
20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
21 |
22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
23 |
24 |
25 | ## Running Tests
26 |
27 | ``` bash
28 | $ composer test
29 | ```
30 |
31 |
32 | **Happy coding**!
33 |
--------------------------------------------------------------------------------
/src/LaravelBitpay.php:
--------------------------------------------------------------------------------
1 | setupClient();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/LaravelBitpayServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->runningInConsole()) {
19 | $this->publishes([
20 | __DIR__ . '/../config/laravel-bitpay.php' => config_path('laravel-bitpay.php'),
21 | ], 'config');
22 | }
23 |
24 | $this->registerRoutes();
25 | }
26 |
27 | /**
28 | * Register the application services.
29 | */
30 | public function register()
31 | {
32 | $this->mergeConfigFrom(__DIR__ . '/../config/laravel-bitpay.php', 'laravel-bitpay');
33 | $this->app->bind('command.laravel-bitpay:createkeypair', CreateKeypairCommand::class);
34 | $this->commands([
35 | 'command.laravel-bitpay:createkeypair',
36 | ]);
37 | }
38 |
39 | protected function registerRoutes()
40 | {
41 | Route::macro('bitPayWebhook',
42 | function (string $uri = 'laravel-bitpay/webhook') {
43 | Route::post($uri, [WebhookController::class, 'handleWebhook'])
44 | ->name('laravel-bitpay.webhook.capture');
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to `vrajroham/laravel-bitpay` will be documented in this file
4 |
5 | ---
6 |
7 | #### v6.0.0 - 2022-12-18
8 |
9 | * Updated BitPay client dependency to v7.1.0
10 | * Bumped minimum PHP version to 7.4
11 | * Implemented the invoice webhook/notification resend action
12 | * Isolated implementation of the `Refunds` resource
13 |
14 | #### v5.3.0 - 2022-06-20
15 |
16 | * Fixed issues, updated deps & corrected typos by @alexstewartja in https://github.com/vrajroham/laravel-bitpay/pull/42
17 |
18 | #### v5.0.1 - 2021-12-18
19 |
20 | * Make newLine() calls compatible with Laravel versions below 8 by @Ririshi in https://github.com/vrajroham/laravel-bitpay/pull/41
21 |
22 | #### v5.0.0 - 2021-12-09
23 |
24 | * v5 Upgrade by @alexstewartja in https://github.com/vrajroham/laravel-bitpay/pull/38:
25 | + Updated BitPay client dependency to v6.0.2111
26 | + Implemented exchange rates (single/pair)
27 | + Deprecated constants that already exist in core library
28 | - Also added return codes that can be used to verify webhooks for the following resources:
29 | + Invoices
30 | + Recipients
31 | + Payouts
32 | + Implemented `Settlements` resource
33 | + Implemented `Ledgers` resource
34 | + Implemented `Recipients` resource
35 | + Implemented `Payouts`/`PayoutBatches` resources
36 | + Added support for `payout` facade
37 | + Updated UX of API Token generation command
38 | + Optimized webhook URL (notificationURL) auto-population
39 | + Added v4 -> v5 to migration guide
40 |
41 | #### v2.0.2
42 |
43 | - Fixed **livenet** token `URL` [#14](https://github.com/vrajroham/laravel-bitpay/pull/14) by [@IvanG11](https://github.com/IvanG11)
44 |
--------------------------------------------------------------------------------
/src/Actions/ManageLedgers.php:
--------------------------------------------------------------------------------
1 | client->getLedgers();
29 | }
30 |
31 | /**
32 | * Retrieve ledger entries.
33 | *
34 | * @link https://bitpay.com/api/#rest-api-resources-ledgers-retrieve-ledger-entries
35 | *
36 | * @param $currency string ISO 4217 3-character currency code for the ledger to retrieve.
37 | * @param $startDate string The start date for fetching ledger entries. Format YYYY-MM-DD
38 | * @param $endDate string The end date for fetching ledger entries. Format YYYY-MM-DD
39 | *
40 | * @return LedgerEntry[] A list of LedgerEntry objects that match the provided filters.
41 | * @throws BitPayException BitPayException class
42 | */
43 | public static function getLedger(string $currency, string $startDate, string $endDate): array
44 | {
45 | return (new self())->client->getLedger($currency, $startDate, $endDate);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vrajroham/laravel-bitpay",
3 | "description": "BitPay wrapper for laravel",
4 | "keywords": [
5 | "bitpay",
6 | "BTC",
7 | "laravel"
8 | ],
9 | "homepage": "https://github.com/vrajroham/laravel-bitpay",
10 | "license": "MIT",
11 | "authors": [
12 | {
13 | "name": "Vaibhavraj Roham",
14 | "email": "vaibhavraj@vrajroham.me",
15 | "homepage": "https://vrajroham.me",
16 | "role": "Developer"
17 | },
18 | {
19 | "name": "Alex Stewart",
20 | "email": "iamalexstewart@gmail.com",
21 | "homepage": "https://github.com/alexstewartja",
22 | "role": "Developer"
23 | }
24 | ],
25 | "require": {
26 | "php": "^7.4 || ^8.0 || ^8.1",
27 | "ext-json": "*",
28 | "bitpay/sdk": "~7.1.0"
29 | },
30 | "require-dev": {
31 | "phpunit/phpunit": ">=9.5"
32 | },
33 | "autoload": {
34 | "psr-4": {
35 | "Vrajroham\\LaravelBitpay\\": "src"
36 | }
37 | },
38 | "autoload-dev": {
39 | "psr-4": {
40 | "Vrajroham\\LaravelBitpay\\Tests\\": "tests"
41 | }
42 | },
43 | "scripts": {
44 | "test": "vendor/bin/phpunit",
45 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage"
46 | },
47 | "config": {
48 | "sort-packages": true
49 | },
50 | "extra": {
51 | "laravel": {
52 | "providers": [
53 | "Vrajroham\\LaravelBitpay\\LaravelBitpayServiceProvider"
54 | ],
55 | "aliases": {
56 | "LaravelBitpay": "Vrajroham\\LaravelBitpay\\LaravelBitpayFacade"
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.github/tmp_ISSUE_TEMPLATE.yml:
--------------------------------------------------------------------------------
1 | name: 🐞 Bug
2 | description: File a bug/issue
3 | title: "[BUG] "
4 | labels: [Bug, Needs Triage]
5 | body:
6 | - type: checkboxes
7 | attributes:
8 | label: Is there an existing issue for this?
9 | description: Please search to see if an issue already exists for the bug you encountered.
10 | options:
11 | - label: I have searched the existing issues
12 | required: true
13 | - type: textarea
14 | attributes:
15 | label: Current Behavior
16 | description: A concise description of what you're experiencing.
17 | validations:
18 | required: false
19 | - type: textarea
20 | attributes:
21 | label: Expected Behavior
22 | description: A concise description of what you expected to happen.
23 | validations:
24 | required: false
25 | - type: textarea
26 | attributes:
27 | label: Steps To Reproduce
28 | description: Steps to reproduce the behavior.
29 | placeholder: |
30 | 1. In this environment...
31 | 2. With this config...
32 | 3. Run '...'
33 | 4. See error...
34 | validations:
35 | required: false
36 | - type: textarea
37 | attributes:
38 | label: Environment
39 | description: |
40 | examples:
41 | - **OS**: Ubuntu 20.04
42 | - **PHP**: 7.4
43 | - **Laravel**: 8.0
44 | value: |
45 | - OS:
46 | - PHP:
47 | - Laravel:
48 | render: markdown
49 | validations:
50 | required: false
51 | - type: textarea
52 | attributes:
53 | label: Anything else?
54 | description: |
55 | Links? References? Anything that will give us more context about the issue you are encountering!
56 |
57 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
58 | validations:
59 | required: false
60 |
--------------------------------------------------------------------------------
/src/Constants/BitPayConstants.php:
--------------------------------------------------------------------------------
1 | 'invoice_paidInFull',
30 | 1004 => 'invoice_expired',
31 | 1005 => 'invoice_confirmed',
32 | 1006 => 'invoice_completed',
33 | 1012 => 'invoice_manuallyNotified',
34 | 1013 => 'invoice_failedToConfirm',
35 | 1016 => 'invoice_refundComplete',
36 | ];
37 |
38 | // Recipient Webhook Codes
39 | const RECIPIENT_WEBHOOK_CODES = [
40 | 4001 => 'recipient_invited',
41 | 4002 => 'recipient_unverified',
42 | 4003 => 'recipient_verified',
43 | 4004 => 'recipient_active',
44 | 4005 => 'recipient_paused',
45 | 4006 => 'recipient_removed',
46 | ];
47 |
48 | // Payout Webhook Codes
49 | const PAYOUT_WEBHOOK_CODES = [
50 | 2001 => 'payoutRequest_funded',
51 | 2002 => 'payoutRequest_completed',
52 | 2003 => 'payoutRequest_cancelled',
53 | ];
54 | }
55 |
--------------------------------------------------------------------------------
/MIGRATION.md:
--------------------------------------------------------------------------------
1 | # LaravelBitPay Migration Guide
2 |
3 | This guide will serve as a single source of truth, regarding breaking changes and necessary actions one must take when
4 | upgrading to major versions.
5 |
6 | ## From v4 to v5
7 |
8 | ### Configuration
9 |
10 | - Ensure `BITPAY_*` values inside your `.env` follows the updated naming conventions outlined
11 | here: https://github.com/vrajroham/laravel-bitpay#add-configuration-values. Specifically:
12 | + Removed:
13 | - `BITPAY_PUBLIC_KEY_PATH`
14 | + Changed:
15 | - `BITPAY_TOKEN` renamed to `BITPAY_MERCHANT_TOKEN`
16 | + Added:
17 | - `BITPAY_ENABLE_MERCHANT`
18 | - `BITPAY_ENABLE_PAYOUT`
19 | - `BITPAY_PAYOUT_TOKEN`
20 |
21 |
22 | - Ensure the contents of your `laravel-bitpay.php` config file is on par with the updated one found
23 | here: https://github.com/vrajroham/laravel-bitpay/blob/master/config/laravel-bitpay.php
24 |
25 | ### API Tokens
26 |
27 | LaravelBitPay now supports the `payout` facade, along with generating a Payout API Token, which allows you to interact
28 | with [Recipients](https://bitpay.com/api/#rest-api-resources-recipients)
29 | and [Payouts](https://bitpay.com/api/#rest-api-resources-payouts) resources.
30 |
31 | It's as easy as setting `BITPAY_ENABLE_PAYOUT` to `true` inside your `.env` file then
32 | following: https://github.com/vrajroham/laravel-bitpay#generate-key-pair-and-api-tokens.
33 |
34 | ### Webhooks
35 |
36 | Webhooks are now an optional feature. Your event listener should work the same, but to configure your webhook URL
37 | (notificationURL) please refer here: https://github.com/vrajroham/laravel-bitpay#configure-webhooks-optional.
38 |
39 | ### Constants
40 |
41 | + Removed:
42 | - `BitPayConstants::BILL_STATUS_*` in favor of core `BillStatus::*`
43 | - `BitPayConstants::SUBSCRIPTION_STATUS_*` in favor of core `SubscriptionStatus::*`
44 | + Added:
45 | - `BitPayConstants::INVOICE_EXCEPTION_*`
46 | - `BitPayConstants::INVOICE_WEBHOOK_CODES`
47 | - `BitPayConstants::RECIPIENT_WEBHOOK_CODES`
48 | - `BitPayConstants::PAYOUT_WEBHOOK_CODES`
49 |
--------------------------------------------------------------------------------
/src/Traits/MakesHttpRequests.php:
--------------------------------------------------------------------------------
1 | validateAndLoadConfig();
23 |
24 | $this->client = BitpayClient::create()->withData(
25 | 'testnet' == $this->config['network'] ? Env::Test : Env::Prod,
26 | $this->config['private_key'],
27 | new Tokens(
28 | $this->config['merchant_token'], //merchant
29 | $this->config['payout_token'] //payout
30 | ),
31 | $this->config['key_storage_password'] //used to decrypt your private key, if encrypted
32 | );
33 | }
34 |
35 | /**
36 | * Validate and load the config.
37 | *
38 | * @throws InvalidConfigurationException
39 | */
40 | public function validateAndLoadConfig()
41 | {
42 | $config = config('laravel-bitpay');
43 |
44 | if ('livenet' !== $config['network'] && 'testnet' !== $config['network']) {
45 | throw InvalidConfigurationException::invalidNetworkName();
46 | }
47 |
48 | if (! class_exists($config['key_storage'])) {
49 | throw InvalidConfigurationException::invalidStorageClass();
50 | }
51 |
52 | if ('' === trim($config['key_storage_password'])) {
53 | throw InvalidConfigurationException::invalidOrEmptyPassword();
54 | }
55 |
56 | if ((!empty($config['merchant_facade_enabled']) && $config['merchant_facade_enabled'])
57 | && empty($config['merchant_token'])) {
58 | throw InvalidConfigurationException::emptyMerchantToken();
59 | }
60 |
61 | if ((!empty($config['payout_facade_enabled']) && $config['payout_facade_enabled'])
62 | && empty($config['payout_token'])) {
63 | throw InvalidConfigurationException::emptyPayoutToken();
64 | }
65 |
66 | $this->config = $config;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Actions/ManageExchangeRates.php:
--------------------------------------------------------------------------------
1 | client->getRates();
23 | }
24 |
25 | /**
26 | * Retrieve all the rates for a given cryptocurrency
27 | *
28 | * @link https://bitpay.com/api/#rest-api-resources-rates-retrieve-all-the-rates-for-a-given-cryptocurrency
29 | *
30 | * @param string $baseCurrency The cryptocurrency for which you want to fetch the rates.
31 | * Current supported values are BTC, BCH, ETH, XRP, DOGE and LTC
32 | *
33 | * @return Rates A Rates object populated with the currency rates for the requested baseCurrency.
34 | * @throws BitPayException BitPayException class
35 | */
36 | public static function getCurrencyRates(string $baseCurrency): Rates
37 | {
38 | return (new self())->client->getCurrencyRates($baseCurrency);
39 | }
40 |
41 | /**
42 | * Retrieve the rate for a cryptocurrency / fiat pair
43 | *
44 | * @link https://bitpay.com/api/#rest-api-resources-rates-retrieve-the-rates-for-a-cryptocurrency-fiat-pair
45 | *
46 | * @param string $baseCurrency The cryptocurrency for which you want to fetch the fiat-equivalent rate.
47 | * Current supported values are BTC, BCH, ETH, XRP, DOGE and LTC
48 | * @param string $currency The fiat currency for which you want to fetch the baseCurrency rate
49 | *
50 | * @return Rate A Rate object populated with the currency rate for the requested baseCurrency.
51 | * @throws BitPayException BitPayException class
52 | */
53 | public static function getCurrencyPairRate(string $baseCurrency, string $currency): Rate
54 | {
55 | return (new self())->client->getCurrencyPairRate($baseCurrency, $currency);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/.github/workflows/php.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build_php_74:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 |
17 | - name: Setup PHP with PECL extension
18 | uses: shivammathur/setup-php@v2
19 | with:
20 | php-version: '7.4'
21 |
22 | - name: Validate composer.json and composer.lock
23 | run: composer validate --strict
24 |
25 | - name: Cache Composer packages
26 | id: composer-cache
27 | uses: actions/cache@v2
28 | with:
29 | path: vendor
30 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
31 | restore-keys: |
32 | ${{ runner.os }}-php-
33 |
34 | - name: Install dependencies
35 | run: composer install --prefer-dist --no-progress
36 |
37 | - name: Run test suite
38 | run: composer run-script test
39 |
40 | build_php_80:
41 |
42 | runs-on: ubuntu-latest
43 |
44 | steps:
45 | - uses: actions/checkout@v2
46 |
47 | - name: Setup PHP with PECL extension
48 | uses: shivammathur/setup-php@v2
49 | with:
50 | php-version: '8.0'
51 |
52 | - name: Validate composer.json and composer.lock
53 | run: composer validate --strict
54 |
55 | - name: Cache Composer packages
56 | id: composer-cache
57 | uses: actions/cache@v2
58 | with:
59 | path: vendor
60 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
61 | restore-keys: |
62 | ${{ runner.os }}-php-
63 |
64 | - name: Install dependencies
65 | run: composer install --prefer-dist --no-progress
66 |
67 | - name: Run test suite
68 | run: composer run-script test
69 |
70 | build_php_81:
71 |
72 | runs-on: ubuntu-latest
73 |
74 | steps:
75 | - uses: actions/checkout@v2
76 |
77 | - name: Setup PHP with PECL extension
78 | uses: shivammathur/setup-php@v2
79 | with:
80 | php-version: '8.1'
81 |
82 | - name: Validate composer.json and composer.lock
83 | run: composer validate --strict
84 |
85 | - name: Cache Composer packages
86 | id: composer-cache
87 | uses: actions/cache@v2
88 | with:
89 | path: vendor
90 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
91 | restore-keys: |
92 | ${{ runner.os }}-php-
93 |
94 | - name: Install dependencies
95 | run: composer install --prefer-dist --no-progress
96 |
97 | - name: Run test suite
98 | run: composer run-script test
99 |
--------------------------------------------------------------------------------
/config/laravel-bitpay.php:
--------------------------------------------------------------------------------
1 | env('BITPAY_PRIVATE_KEY_PATH') ?: storage_path($pkPath),
11 |
12 | /*
13 | * Specifies using the Live Bitcoin network or
14 | * Test Bitcoin network: livenet or testnet.
15 | *
16 | * The default is livenet
17 | */
18 | 'network' => env('BITPAY_NETWORK', 'livenet'),
19 |
20 | /*
21 | * The key_storage option allows you to specify a class for persisting and retrieving keys.
22 | *
23 | * By default this uses the Bitpay\Storage\EncryptedFilesystemStorage class.
24 | */
25 | 'key_storage' => \BitPayKeyUtils\Storage\EncryptedFilesystemStorage::class,
26 |
27 | /*
28 | * This is the password used to encrypt and decrypt keys on the filesystem.
29 | */
30 | 'key_storage_password' => env('BITPAY_KEY_STORAGE_PASSWORD', 'RandomPasswordForEncryption'),
31 |
32 | /*
33 | * Generate/Enable use of BitPay token for 'merchant' facade?
34 | *
35 | * Default: true
36 | */
37 | 'merchant_facade_enabled' => env('BITPAY_ENABLE_MERCHANT', true),
38 |
39 | /*
40 | * Generate/Enable use of BitPay token for 'payout' facade?
41 | *
42 | * Default: false
43 | */
44 | 'payout_facade_enabled' => env('BITPAY_ENABLE_PAYOUT', false),
45 |
46 | /*
47 | * BitPay Merchant Token
48 | *
49 | * Default: null
50 | */
51 | 'merchant_token' => env('BITPAY_MERCHANT_TOKEN'),
52 |
53 | /*
54 | * BitPay Payout Token
55 | *
56 | * Default: null
57 | */
58 | 'payout_token' => env('BITPAY_PAYOUT_TOKEN'),
59 |
60 | /*
61 | * Indicates if configured webhook (notificationURL) should automatically be set on:
62 | * - Invoices
63 | * - Recipients
64 | * - Payouts/PayoutBatches
65 | *
66 | * This feature is overridden when a value is manually set on a respective resource
67 | * before submitting it to the BitPay API.
68 | *
69 | * Uncomment an entry to enable its auto-population.
70 | */
71 | 'auto_populate_webhook' => [
72 | // \Vrajroham\LaravelBitpay\Constants\WebhookAutoPopulate::For_Invoices,
73 | // \Vrajroham\LaravelBitpay\Constants\WebhookAutoPopulate::For_Recipients,
74 | // \Vrajroham\LaravelBitpay\Constants\WebhookAutoPopulate::For_Payouts,
75 | ],
76 | ];
77 |
--------------------------------------------------------------------------------
/src/Actions/ManageSettlements.php:
--------------------------------------------------------------------------------
1 | client->getSettlements($currency, $startDate, $endDate, $status, $limit, $offset);
44 | }
45 |
46 | /**
47 | * Retrieve a settlement.
48 | *
49 | * @link https://bitpay.com/api/#rest-api-resources-settlements-retrieve-settlements
50 | *
51 | * @param $settlementId string Settlement Id.
52 | *
53 | * @return Settlement A BitPay Settlement object.
54 | * @throws BitPayException BitPayException class
55 | */
56 | public static function getSettlement(string $settlementId): Settlement
57 | {
58 | return (new self())->client->getSettlement($settlementId);
59 | }
60 |
61 | /**
62 | * Fetch a reconciliation report. Allows merchant to retrieve a detailed report of the activity within
63 | * the settlement period, in order to reconcile incoming settlements from BitPay.
64 | *
65 | * @link https://bitpay.com/api/#rest-api-resources-settlements-fetch-a-reconciliation-report
66 | *
67 | * @param $settlement Settlement to generate report for.
68 | *
69 | * @return Settlement A detailed BitPay Settlement object.
70 | * @throws BitPayException BitPayException class
71 | */
72 | public static function getSettlementReconciliationReport(Settlement $settlement): Settlement
73 | {
74 | return (new self())->client->getSettlementReconciliationReport($settlement);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/Actions/ManageRefunds.php:
--------------------------------------------------------------------------------
1 | client->createRefund($invoice, $refundEmail, $amount, $currency);
48 | }
49 |
50 | /**
51 | * Retrieve all refund requests on a BitPay invoice.
52 | *
53 | * @link https://bitpay.com/api/#rest-api-resources-invoices-retrieve-all-refund-requests-on-an-invoice
54 | *
55 | * @param $invoice Invoice The BitPay invoice having the associated refunds.
56 | *
57 | * @return Refund[] An array of BitPay refund object with the associated Refund object updated.
58 | * @throws BitPayException BitPayException class
59 | */
60 | public static function getRefunds(Invoice $invoice): array
61 | {
62 | return (new self())->client->getRefunds($invoice);
63 | }
64 |
65 | /**
66 | * Retrieve a previously made refund request on a BitPay invoice.
67 | *
68 | * @link https://bitpay.com/api/#rest-api-resources-invoices-retrieve-a-refund-request
69 | *
70 | * @param $invoice Invoice The BitPay invoice having the associated refund.
71 | * @param $refundId string The refund id for the refund to be updated with new status.
72 | *
73 | * @return Refund A BitPay refund object with the associated Refund object updated.
74 | * @throws BitPayException BitPayException class
75 | */
76 | public static function getRefund(Invoice $invoice, string $refundId): Refund
77 | {
78 | return (new self())->client->getRefund($invoice, $refundId);
79 | }
80 |
81 | /**
82 | * Cancel a previously submitted refund request on a BitPay invoice.
83 | *
84 | * @link https://bitpay.com/api/#rest-api-resources-invoices-cancel-a-refund-request
85 | *
86 | * @param $invoiceId string The refund id for the refund to be canceled.
87 | * @param $refund Refund The BitPay invoice having the associated refund to be canceled.
88 | * Must have been obtained using the merchant facade.
89 | *
90 | * @return bool True if the refund was successfully canceled, false otherwise.
91 | * @throws RefundCancellationException RefundCancellationException class
92 | */
93 | public static function cancelRefund(string $invoiceId, Refund $refund): bool
94 | {
95 | return (new self())->client->cancelRefund($invoiceId, $refund);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Actions/ManageBills.php:
--------------------------------------------------------------------------------
1 | client->createBill($bill);
60 | }
61 |
62 | /**
63 | * Retrieve a BitPay bill by its id.
64 | *
65 | * @link https://bitpay.com/api/#rest-api-resources-bills-retrieve-a-bill
66 | *
67 | * @param $billId string The id of the bill to retrieve.
68 | *
69 | * @return Bill A BitPay Bill object.
70 | * @throws BitPayException BitPayException class
71 | */
72 | public static function getBill(string $billId): Bill
73 | {
74 | return (new self())->client->getBill($billId);
75 | }
76 |
77 | /**
78 | * Retrieve a collection of BitPay bills.
79 | *
80 | * @link https://bitpay.com/api/#rest-api-resources-bills-retrieve-bills-by-status
81 | *
82 | * @param $status string|null The status to filter the bills.
83 | *
84 | * @return Bill[] A list of BitPay Bill objects.
85 | * @throws BitPayException BitPayException class
86 | */
87 | public static function getBills(string $status = null): array
88 | {
89 | return (new self())->client->getBills($status);
90 | }
91 |
92 | /**
93 | * Update a BitPay Bill.
94 | *
95 | * @link https://bitpay.com/api/#rest-api-resources-bills-update-a-bill
96 | *
97 | * @param $bill Bill A Bill object with the parameters to update defined.
98 | * @param $billId string The ID of the Bill to update.
99 | *
100 | * @return Bill An updated Bill object.
101 | * @throws BitPayException BitPayException class
102 | */
103 | public static function updateBill(Bill $bill, string $billId): Bill
104 | {
105 | return (new self())->client->updateBill($bill, $billId);
106 | }
107 |
108 | /**
109 | * Deliver a BitPay Bill.
110 | *
111 | * @link https://bitpay.com/api/#rest-api-resources-bills-deliver-a-bill-via-email
112 | *
113 | * @param $billId string The id of the requested bill.
114 | * @param $billToken string The token of the requested bill.
115 | *
116 | * @return bool True if the bill has been delivered, false otherwise.
117 | * @throws BitPayException BitPayException class
118 | */
119 | public static function deliverBill(string $billId, string $billToken): bool
120 | {
121 | return strtolower((new self())->client->deliverBill($billId, $billToken)) === "success";
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/Traits/CreateKeypairTrait.php:
--------------------------------------------------------------------------------
1 | config = $config;
27 | }
28 |
29 | protected function getEnabledFacades(): array
30 | {
31 | $facades = [];
32 |
33 | if (! empty($this->config['merchant_facade_enabled']) && $this->config['merchant_facade_enabled']) {
34 | $facades[] = 'merchant';
35 | }
36 |
37 | if (! empty($this->config['payout_facade_enabled']) && $this->config['payout_facade_enabled']) {
38 | $facades[] = 'payout';
39 | }
40 |
41 | return $facades;
42 | }
43 |
44 | /**
45 | *
46 | * @param string $facade One of 'merchant' or 'payout'
47 | *
48 | * @throws \Exception
49 | */
50 | private function getEnvReplacementString(string $facade): string
51 | {
52 | if ($facade === 'merchant') {
53 | return "BITPAY_MERCHANT_TOKEN";
54 | } elseif ($facade === 'payout') {
55 | return "BITPAY_PAYOUT_TOKEN";
56 | }
57 |
58 | throw new \Exception("'$facade' is not a valid BitPay facade!", 1);
59 | }
60 |
61 | /**
62 | * Write facade-specific token to .env
63 | * Update it if it exists, otherwise add it below existing BITPAY_* entries.
64 | * Finally, and very unlikely, if it doesn't exist nor does any other BITPAY_* entries, write it to the end
65 | * of the .env
66 | *
67 | * @param string $facade One of 'merchant' or 'payout'
68 | *
69 | * @throws \Exception
70 | */
71 | protected function writeNewEnvironmentFileWith(string $facade)
72 | {
73 | $replString = $this->getEnvReplacementString($facade) . '=' . $this->token;
74 | $envFilePath = $this->laravel->environmentFilePath();
75 | $envFileContents = file_get_contents($envFilePath);
76 |
77 | if (strpos($envFileContents, $this->getEnvReplacementString($facade)) !== false) {
78 | file_put_contents($envFilePath, preg_replace(
79 | $this->keyReplacementPattern($facade),
80 | $replString,
81 | $envFileContents)
82 | );
83 | } else {
84 | $envLines = file($envFilePath, FILE_IGNORE_NEW_LINES);
85 | $offset = null;
86 |
87 | foreach ($envLines as $line) {
88 | if (strpos($line, "BITPAY_") === 0) {
89 | $offset = array_search($line, $envLines);
90 | }
91 | }
92 |
93 | // Highly unlikely, but place token at end of .env if no other BITPAY_* entries exist
94 | if ($offset === null) {
95 | $offset = count($envLines) - 1;
96 | $replString = "\n" . $replString;
97 | }
98 |
99 | array_splice($envLines, $offset + 1, 0, $replString);
100 | file_put_contents($envFilePath, implode("\n", $envLines));
101 | }
102 | }
103 |
104 | /**
105 | *
106 | * @param string $facade One of 'merchant' or 'payout'
107 | *
108 | * @throws \Exception
109 | */
110 | protected function keyReplacementPattern(string $facade): string
111 | {
112 | if ($facade === 'merchant') {
113 | $token = $this->laravel['config']['laravel-bitpay.merchant_token'];
114 | } elseif ($facade === 'payout') {
115 | $token = $this->laravel['config']['laravel-bitpay.payout_token'];
116 | } else {
117 | throw new \Exception("'$facade' is not a valid BitPay facade!", 1);
118 | }
119 |
120 | $replString = $this->getEnvReplacementString($facade);
121 | $escaped = preg_quote('=' . $token, '/');
122 |
123 | return "/^" . $replString . "{$escaped}/m";
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/Actions/ManageSubscriptions.php:
--------------------------------------------------------------------------------
1 | client->createSubscription($subscription);
63 | }
64 |
65 | /**
66 | * Retrieve a BitPay subscription by its id.
67 | *
68 | * @link https://bitpay.com/api/#rest-api-resources-subscriptions-retrieve-a-subscription
69 | *
70 | * @param $subscriptionId string The id of the subscription to retrieve.
71 | *
72 | * @return Subscription A BitPay Subscription object.
73 | * @throws \BitPaySDK\Exceptions\BitPayException BitPayException class
74 | */
75 | public static function getSubscription(string $subscriptionId): Subscription
76 | {
77 | return (new self())->client->getSubscription($subscriptionId);
78 | }
79 |
80 | /**
81 | * Retrieve a collection of BitPay subscriptions.
82 | *
83 | * @link https://bitpay.com/api/#rest-api-resources-subscriptions-retrieve-subscriptions-based-on-status
84 | *
85 | * @param $status string|null The status to filter the subscriptions.
86 | *
87 | * @return Subscription[] A list of BitPay Subscription objects.
88 | * @throws \BitPaySDK\Exceptions\BitPayException BitPayException class
89 | */
90 | public static function getSubscriptions(string $status = null): array
91 | {
92 | return (new self())->client->getSubscriptions($status);
93 | }
94 |
95 | /**
96 | * Update a BitPay Subscription.
97 | *
98 | * @link https://bitpay.com/api/#rest-api-resources-subscriptions-update-a-subscription
99 | *
100 | * @param $subscription Subscription A Subscription object with the parameters to update defined.
101 | * @param $subscriptionId string $subscriptionIdThe Id of the Subscription to update.
102 | *
103 | * @return Subscription An updated Subscription object.
104 | * @throws \BitPaySDK\Exceptions\BitPayException BitPayException class
105 | */
106 | public static function updateSubscription(Subscription $subscription, string $subscriptionId): Subscription
107 | {
108 | return (new self())->client->updateSubscription($subscription, $subscriptionId);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/Actions/ManageInvoices.php:
--------------------------------------------------------------------------------
1 | getNotificationURL()) &&
52 | in_array(WebhookAutoPopulate::For_Invoices, $thisInstance->config['auto_populate_webhook'])) {
53 | $invoice->setNotificationURL(route('laravel-bitpay.webhook.capture'));
54 | }
55 | } catch (\Throwable $exception) {
56 | // Misconfiguration or route macro not in use
57 | }
58 |
59 | return $thisInstance->client->createInvoice($invoice);
60 | }
61 |
62 | /**
63 | * Retrieve a BitPay invoice by its id.
64 | *
65 | * @link https://bitpay.com/api/#rest-api-resources-invoices-retrieve-an-invoice
66 | *
67 | * @param $invoiceId string The id of the invoice to retrieve.
68 | *
69 | * @return Invoice A BitPay Invoice object.
70 | * @throws BitPayException BitPayException class
71 | */
72 | public static function getInvoice(string $invoiceId): Invoice
73 | {
74 | return (new self())->client->getInvoice($invoiceId);
75 | }
76 |
77 | /**
78 | * Retrieve a collection of BitPay invoices.
79 | *
80 | * @link https://bitpay.com/api/#rest-api-resources-invoices-retrieve-invoices-filtered-by-query
81 | *
82 | * @param $dateStart string The start of the date window to query for invoices. Format YYYY-MM-DD.
83 | * @param $dateEnd string The end of the date window to query for invoices. Format YYYY-MM-DD.
84 | * @param $status string|null The invoice status you want to query on.
85 | * @param $orderId string|null The optional order id specified at time of invoice creation.
86 | * @param $limit int|null Maximum results that the query will return (useful for paging results).
87 | * @param $offset int|null Number of results to offset (ex. skip 10 will give you results starting with the 11th result).
88 | *
89 | * @return Invoice[] A list of BitPay Invoice objects.
90 | * @throws BitPayException BitPayException class
91 | */
92 | public static function getInvoices(
93 | string $dateStart,
94 | string $dateEnd,
95 | string $status = null,
96 | string $orderId = null,
97 | int $limit = null,
98 | int $offset = null
99 | ): array {
100 | return (new self())->client->getInvoices($dateStart, $dateEnd, $status, $orderId, $limit, $offset);
101 | }
102 |
103 | /**
104 | * Request the last BitPay Invoice webhook to be resent.
105 | *
106 | * @link https://bitpay.com/api/#rest-api-resources-invoices-request-a-webhook-to-be-resent
107 | *
108 | * @param string $invoiceId The id of the invoice for which you want the last webhook to be resent.
109 | *
110 | * @return bool True if the webhook has been resent for the current invoice status, false otherwise.
111 | * @throws \BitPaySDK\Exceptions\BitPayException BitPayException class
112 | */
113 | public static function requestInvoiceWebhook(string $invoiceId): bool
114 | {
115 | return (new self())->client->requestInvoiceNotification($invoiceId);
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/Actions/ManageRecipients.php:
--------------------------------------------------------------------------------
1 | getRecipients() as $recipient) {
82 | if (empty($recipient['notificationURL']) &&
83 | in_array(WebhookAutoPopulate::For_Recipients, $thisInstance->config['auto_populate_webhook'])) {
84 | $recipient['notificationURL'] = route('laravel-bitpay.webhook.capture');
85 | }
86 | }
87 | } catch (\Throwable $exception) {
88 | // Misconfiguration or route macro not in use
89 | }
90 |
91 | return $thisInstance->client->submitPayoutRecipients($recipients);
92 | }
93 |
94 | /**
95 | * Retrieve a BitPay payout recipient by its ID.
96 | *
97 | * @link https://bitpay.com/api/#rest-api-resources-recipients-retrieve-a-recipient
98 | *
99 | * @param $recipientId string The id of the recipient to retrieve.
100 | *
101 | * @return PayoutRecipient A BitPay PayoutRecipient object.
102 | * @throws PayoutQueryException BitPayException class
103 | */
104 | public static function getPayoutRecipient(string $recipientId): PayoutRecipient
105 | {
106 | return (new self())->client->getPayoutRecipient($recipientId);
107 | }
108 |
109 | /**
110 | * Retrieve recipients by status.
111 | *
112 | * @link https://bitpay.com/api/#rest-api-resources-recipients-retrieve-recipients-by-status
113 | *
114 | * @param $status string|null The recipient status you want to query on.
115 | * @param $limit int|null Maximum results that the query will return (useful for paging results).
116 | * @param $offset int|null Number of results to offset (ex. skip 10 will give you results starting with the 11th result).
117 | *
118 | * @return PayoutRecipient[] A list of BitPay PayoutRecipient objects.
119 | * @throws BitPayException BitPayException class
120 | */
121 | public static function getPayoutRecipients(string $status = null, int $limit = null, int $offset = null): array
122 | {
123 | return (new self())->client->getPayoutRecipients($status, $limit, $offset);
124 | }
125 |
126 | /**
127 | * Update a Recipient.
128 | *
129 | * @link https://bitpay.com/api/#rest-api-resources-recipients-update-a-recipient
130 | *
131 | * @param $recipientId string The ID for the recipient to be updated.
132 | * @param $recipient PayoutRecipient A PayoutRecipient object with updated parameters defined.
133 | *
134 | * @return PayoutRecipient The updated PayoutRecipient object.
135 | * @throws PayoutRecipientUpdateException PayoutRecipientUpdateException class
136 | */
137 | public static function updatePayoutRecipient(string $recipientId, PayoutRecipient $recipient): PayoutRecipient
138 | {
139 | return (new self())->client->updatePayoutRecipient($recipientId, $recipient);
140 | }
141 |
142 | /**
143 | * Remove a recipient
144 | *
145 | * @link https://bitpay.com/api/#rest-api-resources-recipients-remove-a-recipient
146 | *
147 | * @param $recipientId string The ID of the recipient to be removed.
148 | *
149 | * @return bool True if the recipient was successfully removed, false otherwise.
150 | * @throws PayoutRecipientCancellationException PayoutRecipientCancellationException class
151 | */
152 | public static function removePayoutRecipient(string $recipientId): bool
153 | {
154 | return (new self())->client->deletePayoutRecipient($recipientId);
155 | }
156 |
157 | /**
158 | * Request a Recipient webhook to be resent.
159 | *
160 | * @link https://bitpay.com/api/#rest-api-resources-recipients-request-a-webhook-to-be-resent
161 | *
162 | * @param $recipientId string The id of the recipient for which you want the last webhook to be resent.
163 | *
164 | * @return bool True if the webhook has been resent for the current recipient status, false otherwise.
165 | * @throws PayoutRecipientNotificationException PayoutRecipientNotificationException class
166 | */
167 | public static function requestPayoutRecipientWebhook(string $recipientId): bool
168 | {
169 | return (new self())->client->requestPayoutRecipientNotification($recipientId);
170 | }
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/src/Console/CreateKeypairCommand.php:
--------------------------------------------------------------------------------
1 | addOption('fresh', 'f', InputOption::VALUE_NONE, 'Explicitly generate a ' .
55 | 'fresh private key. By default, if a (valid) key exists, it will be used instead.');
56 | }
57 |
58 | /**
59 | * @inheritDoc
60 | * Polyfill which enables compatibility with Laravel <8.x
61 | *
62 | * @param int $count
63 | *
64 | * @return void
65 | * @since 5.0.1
66 | */
67 | public function newLine($count = 1)
68 | {
69 | $this->output->newLine($count);
70 | }
71 |
72 | /**
73 | * Advance progress bar by $steps, and write 'info' level $message to console, optionally skipping by $skipSteps.
74 | *
75 | * @param string $message
76 | * @param int $steps
77 | * @param int $skipSteps
78 | */
79 | private function advanceWithInfo(string $message, int $steps = 1, int $skipSteps = 0)
80 | {
81 | $this->bar->clear();
82 | if ($skipSteps > 0) {
83 | $this->bar->setMaxSteps($this->bar->getMaxSteps() - $skipSteps);
84 | }
85 | $this->bar->advance($steps);
86 | $this->info($message);
87 | }
88 |
89 | private function sectionHeader(string $sectionTitle)
90 | {
91 | $diffWidth = self::HEADER_FOOTER_WIDTH - (strlen($sectionTitle) + 2);
92 | $borderWidth = round($diffWidth / 2, 0, PHP_ROUND_HALF_DOWN);
93 |
94 | $this->info('' . str_repeat('#', $borderWidth) . ' '
95 | . $sectionTitle . ' ' . str_repeat('#', $borderWidth) . '>');
96 | $this->newLine();
97 | }
98 |
99 | private function sectionFooter()
100 | {
101 | $this->newLine();
102 | $this->info('' . str_repeat('#', self::HEADER_FOOTER_WIDTH) . '>');
103 | $this->newLine(2);
104 | }
105 |
106 | /**
107 | * Execute the console command.
108 | */
109 | public function handle()
110 | {
111 | try {
112 | $this->validateAndLoadConfig();
113 |
114 | $enabled_facades = $this->getEnabledFacades();
115 |
116 | if (empty($enabled_facades)) {
117 | $error_message = 'No facades enabled for token generation! Open your .env>' .
118 | ' file and set values for BITPAY_ENABLE_MERCHANT> and/or ' .
119 | 'BITPAY_ENABLE_PAYOUT>';
120 | $this->error($error_message);
121 | exit(1);
122 | }
123 |
124 | // Each facade effects 2 progress advances and keypair loading/generation effects a max of 5.
125 | $this->bar = $this->output->createProgressBar((count($enabled_facades) * 2) + 5);
126 |
127 | $this->bar->setProgressCharacter('⚡');
128 | $this->bar->setBarCharacter('-');
129 | $this->bar->setEmptyBarCharacter(' ');
130 | $this->bar->minSecondsBetweenRedraws(0);
131 |
132 | $this->newLine();
133 |
134 | $this->createAndPersistKeypair();
135 |
136 | foreach ($enabled_facades as $facade) {
137 | $this->sectionHeader(strtoupper($facade) . ' FACADE');
138 |
139 | $this->pairWithServerAndCreateToken($facade);
140 |
141 | $this->writeNewEnvironmentFileWith($facade);
142 |
143 | // Convert to IF-ELSE construct if BitPay ever use additional facades. if, if, iffity if.
144 | $this->laravel['config']['laravel-bitpay.' .
145 | ($facade === 'merchant' ? 'merchant_' : ($facade === 'payout' ? 'payout_' : '')) . 'token'] = $this->token;
146 |
147 | $this->newLine();
148 |
149 | $this->line('Token Label> : ' . $this->tokenLabel . '>');
150 |
151 | $this->line('Token> : ' . $this->token
152 | . '> (Copied to .env> for your convenience)');
153 |
154 | $this->line('Pairing Code>: ' . $this->pairingCode
155 | . '> (Expires: ' . $this->pairingExpiration . '>)');
156 |
157 | $this->newLine();
158 |
159 | $this->line('Approve your API Token by visiting: approveLink . '>' . $this->approveLink . '>');
160 |
161 | $this->sectionFooter();
162 | }
163 | } catch (\Throwable $exception) {
164 | $this->error('Whoops! We have a problem: ' . $exception->getMessage());
165 | exit(1);
166 | }
167 | }
168 |
169 | /**
170 | * @throws \Exception
171 | */
172 | private function generateFreshKeyPair()
173 | {
174 | $this->advanceWithInfo(' 🔑 - Generating private key.');
175 |
176 | $this->privateKey = new PrivateKey($this->config['private_key']);
177 | $this->privateKey->generate();
178 |
179 | $this->advanceWithInfo(' 🌐 - Generating public key.');
180 |
181 | $this->publicKey = $this->privateKey->getPublicKey();
182 |
183 | $this->advanceWithInfo(' 🧰 - Using ' . get_class($this->storageEngine) . '> for secure storage.');
184 |
185 | $this->storageEngine->persist($this->privateKey);
186 |
187 | $this->advanceWithInfo(' 🔐 - Private key stored securely.');
188 | }
189 |
190 | /**
191 | * Create private key and public keypair and store in secure file storage, using an existing (valid) keypair by
192 | * default.
193 | *
194 | *
195 | * @throws \Exception
196 | */
197 | public function createAndPersistKeypair()
198 | {
199 | $this->sectionHeader('KEYPAIR GENERATION');
200 |
201 | if (in_array('__construct', get_class_methods($this->config['key_storage']))) {
202 | $this->storageEngine = new $this->config['key_storage']($this->config['key_storage_password']);
203 | } else {
204 | $this->storageEngine = new $this->config['key_storage']();
205 | }
206 |
207 | if ($this->option('fresh')) {
208 | $this->generateFreshKeyPair();
209 | } else {
210 | try {
211 | // Try to load the configured Private Key, expect it to be missing or corrupted
212 | $this->privateKey = $this->storageEngine->load($this->config['private_key']);
213 |
214 | // Private Key may be uncorrupted but has invalid hexits or decimals
215 | if ($this->privateKey->isValid()) {
216 | $this->publicKey = $this->privateKey->getPublicKey();
217 |
218 | $this->advanceWithInfo(' 🗝️ - Using existing private key.', 1, 3);
219 | } else {
220 | $this->generateFreshKeyPair();
221 | }
222 | } catch (\Throwable $exception) {
223 | $this->generateFreshKeyPair();
224 | }
225 | }
226 |
227 | $this->sin = $this->publicKey->getSin()->__toString();
228 |
229 | $this->advanceWithInfo(' 🆔 - Created Service Identification Number (SIN Key) for client.');
230 |
231 | $this->sectionFooter();
232 | }
233 |
234 | /**
235 | * Initiates client-server pairing. Create token and pairing code on BitPay server for provided facade.
236 | *
237 | * @param string $facade One of 'merchant' or 'payout'
238 | *
239 | * @throws \GuzzleHttp\Exception\GuzzleException
240 | */
241 | public function pairWithServerAndCreateToken(string $facade)
242 | {
243 | if ('testnet' === $this->config['network']) {
244 | $this->network = 'https://test.bitpay.com';
245 | } elseif ('livenet' === $this->config['network']) {
246 | $this->network = 'https://bitpay.com';
247 | } else {
248 | $this->network = 'https://bitpay.com';
249 | }
250 |
251 | $bitpayClient = new Client(['base_uri' => $this->network]);
252 |
253 | $this->advanceWithInfo(" 🖥️ - Connecting to BitPay server and generating $facade token.");
254 |
255 | // Token label is limited to 60 characters
256 | $this->tokenLabel = Str::substr(ucwords(str_replace(" ", "-", config('app.name'))), 0, 36)
257 | . '__' . Str::ucfirst($facade) . '__' . date('h-i-s_A');
258 |
259 | $postData = [
260 | 'id' => (string)$this->sin,
261 | 'label' => $this->tokenLabel,
262 | 'facade' => $facade,
263 | ];
264 | $response = $bitpayClient->post('/tokens', [
265 | 'json' => $postData,
266 | 'headers' => [
267 | 'x-accept-version' => '2.0.0',
268 | 'Content-Type' => 'application/json',
269 | ],
270 | ]);
271 | $response = json_decode($response->getBody()->getContents());
272 |
273 | $this->advanceWithInfo(" 🥳 - New $facade token and pairing code received from BitPay server.");
274 |
275 | $this->token = $response->data[0]->token;
276 | $this->pairingCode = $response->data[0]->pairingCode;
277 | $this->pairingExpiration = date('M j, Y h:i:s A', intval($response->data[0]->pairingExpiration) / 1000);
278 |
279 | $this->approveLink = $this->network . '/api-access-request?' .
280 | http_build_query(['pairingCode' => $this->pairingCode]);
281 | }
282 | }
283 |
--------------------------------------------------------------------------------
/src/Actions/ManagePayouts.php:
--------------------------------------------------------------------------------
1 | getNotificationURL()) &&
98 | in_array(WebhookAutoPopulate::For_Payouts, $thisInstance->config['auto_populate_webhook'])) {
99 | $payout->setNotificationURL(route('laravel-bitpay.webhook.capture'));
100 | }
101 | } catch (\Throwable $exception) {
102 | // Misconfiguration or route macro not in use
103 | }
104 |
105 | return $thisInstance->client->submitPayout($payout);
106 | }
107 |
108 | /**
109 | * Retrieve a payout
110 | *
111 | * @param string $payoutId The id of the payout to retrieve.
112 | *
113 | * @return Payout A BitPay Payout object.
114 | * @throws PayoutQueryException PayoutQueryException class
115 | */
116 | public static function getPayout(string $payoutId): Payout
117 | {
118 | return (new self)->client->getPayout($payoutId);
119 | }
120 |
121 | /**
122 | * Retrieve payouts based on status
123 | *
124 | * @param string|null $startDate The start date to filter the Payouts.
125 | * @param string|null $endDate The end date to filter the Payout.
126 | * @param string|null $status The payout status you want to query on
127 | * @param string|null $reference The optional reference specified at payout request creation.
128 | * @param int|null $limit Maximum results that the query will return (useful for paging results).
129 | * @param int|null $offset number of results to offset (ex. skip 10 will give you results starting
130 | * with the 11th result).
131 | *
132 | * @return Payout[] A list of BitPay Payout objects.
133 | * @throws PayoutQueryException PayoutQueryException class
134 | */
135 | public static function getPayouts(
136 | string $startDate = null,
137 | string $endDate = null,
138 | string $status = null,
139 | string $reference = null,
140 | int $limit = null,
141 | int $offset = null): array
142 | {
143 | return (new self())->client->getPayouts(
144 | $startDate,
145 | $endDate,
146 | $status,
147 | $reference,
148 | $limit,
149 | $offset
150 | );
151 | }
152 |
153 | /**
154 | * Cancel a payout
155 | *
156 | * @param string $payoutId The id of the payout to cancel.
157 | *
158 | * @return bool True if payout was canceled successfully, false otherwise.
159 | * @throws PayoutCancellationException PayoutCancellationException class
160 | */
161 | public static function cancelPayout(string $payoutId): bool
162 | {
163 | return (new self())->client->cancelPayout($payoutId);
164 | }
165 |
166 | /**
167 | * Request a Payout webhook to be resent.
168 | *
169 | * @param $payoutId string The id of the payout for which you want the last webhook to be resent.
170 | *
171 | * @return bool True if the webhook has been resent for the current payout status, false otherwise.
172 | * @throws PayoutNotificationException PayoutNotificationException class
173 | */
174 | public static function requestPayoutWebhook(string $payoutId): bool
175 | {
176 | return (new self())->client->requestPayoutNotification($payoutId);
177 | }
178 |
179 | /**
180 | * Create a payout batch
181 | *
182 | * @link https://bitpay.com/api/#rest-api-resources-payouts-create-a-payout-batch
183 | *
184 | * @param PayoutBatch $payoutBatch A PayoutBatch object with request parameters defined.
185 | *
186 | * @return PayoutBatch A BitPay generated PayoutBatch object.
187 | * @throws PayoutBatchCreationException PayoutBatchCreationException class
188 | */
189 | public static function createPayoutBatch(PayoutBatch $payoutBatch): PayoutBatch
190 | {
191 | $thisInstance = new self();
192 |
193 | try {
194 | if (empty($payoutBatch->getNotificationURL()) &&
195 | in_array(WebhookAutoPopulate::For_Payouts, $thisInstance->config['auto_populate_webhook'])) {
196 | $payoutBatch->setNotificationURL(route('laravel-bitpay.webhook.capture'));
197 | }
198 | } catch (\Throwable $exception) {
199 | // Misconfiguration or route macro not in use
200 | }
201 |
202 | return $thisInstance->client->submitPayoutBatch($payoutBatch);
203 | }
204 |
205 | /**
206 | * Retrieve a payout batch
207 | *
208 | * @link https://bitpay.com/api/#rest-api-resources-payouts-retrieve-a-payout-batch
209 | *
210 | * @param string $payoutBatchId The id of the payout batch to retrieve.
211 | *
212 | * @return PayoutBatch A BitPay PayoutBatch object.
213 | * @throws PayoutBatchQueryException PayoutBatchQueryException class
214 | */
215 | public static function getPayoutBatch(string $payoutBatchId): PayoutBatch
216 | {
217 | return (new self)->client->getPayoutBatch($payoutBatchId);
218 | }
219 |
220 | /**
221 | * Retrieve payout batches based on status
222 | *
223 | * @link https://bitpay.com/api/#rest-api-resources-payouts-retrieve-payout-batches-based-on-status
224 | *
225 | * @param string|null $startDate The start date to filter the PayoutBatch Batches.
226 | * @param string|null $endDate The end date to filter the PayoutBatch Batches.
227 | * @param string|null $status The payout status you want to query on
228 | * @param int|null $limit Maximum results that the query will return (useful for paging results).
229 | * @param int|null $offset number of results to offset (ex. skip 10 will give you results starting
230 | * with the 11th result).
231 | *
232 | * @return PayoutBatch[] A list of BitPay PayoutBatch objects.
233 | * @throws PayoutBatchQueryException PayoutBatchQueryException class
234 | */
235 | public static function getPayoutBatches(
236 | string $startDate = null,
237 | string $endDate = null,
238 | string $status = null,
239 | int $limit = null,
240 | int $offset = null): array
241 | {
242 | return (new self())->client->getPayoutBatches(
243 | $startDate,
244 | $endDate,
245 | $status,
246 | $limit,
247 | $offset
248 | );
249 | }
250 |
251 | /**
252 | * Cancel a payout batch
253 | *
254 | * @link https://bitpay.com/api/#rest-api-resources-payouts-cancel-a-payout-batch
255 | *
256 | * @param string $payoutBatchId The id of the payout batch to cancel.
257 | *
258 | * @return bool True if payout batch was canceled successfully, false otherwise.
259 | * @throws PayoutBatchCancellationException PayoutBatchCancellationException class
260 | */
261 | public static function cancelPayoutBatch(string $payoutBatchId): bool
262 | {
263 | return (new self())->client->cancelPayoutBatch($payoutBatchId);
264 | }
265 |
266 | /**
267 | * Request a PayoutBatch webhook to be resent.
268 | *
269 | * @param $payoutBatchId string The id of the payout batch for which you want the last webhook to be resent.
270 | *
271 | * @return bool True if the webhook has been resent for the current payout batch status, false otherwise.
272 | * @throws PayoutBatchNotificationException PayoutBatchNotificationException class
273 | */
274 | public static function requestPayoutBatchWebhook(string $payoutBatchId): bool
275 | {
276 | return (new self())->client->requestPayoutBatchNotification($payoutBatchId);
277 | }
278 |
279 | }
280 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LaravelBitPay
2 |
3 | 
4 |
5 | [](https://packagist.org/packages/vrajroham/laravel-bitpay)
6 | [](https://travis-ci.org/vrajroham/laravel-bitpay)
7 | [](https://scrutinizer-ci.com/g/vrajroham/laravel-bitpay)
8 | [](https://packagist.org/packages/vrajroham/laravel-bitpay)
9 |
10 | LaravelBitPay enables you and your business to transact in Bitcoin, Bitcoin Cash and 10+ other BitPay-supported
11 | cryptocurrencies within your Laravel application.
12 |
13 | > Requires PHP 7.4+
14 |
15 | ## :warning: Migration From v4 :warning:
16 |
17 | If upgrading from v4, please follow [MIGRATION.md](./MIGRATION.md)
18 |
19 | ## Supported Resources
20 |
21 | - :white_check_mark: [Invoices](https://bitpay.com/api/#rest-api-resources-invoices)
22 | - :white_check_mark: [Refunds](https://bitpay.com/api/#rest-api-resources-refunds)
23 | - :white_check_mark: [Bills](https://bitpay.com/api/#rest-api-resources-bills)
24 | - :white_check_mark: [Subscriptions](https://bitpay.com/api/#rest-api-resources-subscriptions)
25 | - :white_check_mark: [Settlements](https://bitpay.com/api/#rest-api-resources-settlements)
26 | - :white_check_mark: [Ledgers](https://bitpay.com/api/#rest-api-resources-ledgers)
27 | - :white_check_mark: [Recipients](https://bitpay.com/api/#rest-api-resources-recipients)
28 | - :white_check_mark: [Payouts](https://bitpay.com/api/#rest-api-resources-payouts)
29 | - :white_check_mark: [Currencies](https://bitpay.com/api/#rest-api-resources-currencies)
30 | - :white_check_mark: [Rates](https://bitpay.com/api/#rest-api-resources-rates)
31 |
32 | ## Contents
33 |
34 | - [Installation](#installation)
35 | + [Install Package](#install-package)
36 | + [Publish config file](#publish-config-file)
37 | + [Add configuration values](#add-configuration-values)
38 | + [Generate Key-Pair and API Token(s)](#generate-key-pair-and-api-tokens)
39 | + [Configure Webhooks (Optional)](#configure-webhooks-optional)
40 | + [1. Setup your webhook route](#1-setup-your-webhook-route)
41 | + [2. Setup your webhook listener](#2-setup-your-webhook-listener)
42 | - [Examples](#examples)
43 | + [Invoices](#invoices)
44 | + [Create an invoice](#create-an-invoice)
45 | + [Retrieve an existing invoice](#retrieve-an-existing-invoice)
46 | + [Retrieve a list of existing invoices](#retrieve-a-list-of-existing-invoices)
47 | + [Refunds](#refunds)
48 | + [Refund an invoice](#refund-an-invoice)
49 | + [Retrieve a refund request](#retrieve-a-refund-request)
50 | + [Retrieve all refund requests on an invoice](#retrieve-all-refund-requests-on-an-invoice)
51 | + [Cancel a refund request](#cancel-a-refund-request)
52 | + [Bills](#bills)
53 | + [Create a bill](#create-a-bill)
54 | + [Retrieve a bill](#retrieve-a-bill)
55 | + [Retrieve a list of existing bills](#retrieve-a-list-of-existing-bills)
56 | + [Update a bill](#update-a-bill)
57 | + [Deliver a bill via email](#deliver-a-bill-via-email)
58 | + [Subscriptions](#subscriptions)
59 | + [Create a subscription](#create-a-subscription)
60 | + [Retrieve a subscription](#retrieve-a-subscription)
61 | + [Retrieve a list of existing subscriptions](#retrieve-a-list-of-existing-subscriptions)
62 | + [Update a subscription](#update-a-subscription)
63 | + [Settlements](#settlements)
64 | + [Retrieve settlements](#retrieve-settlements)
65 | + [Retrieve a settlement](#retrieve-a-settlement)
66 | + [Fetch a reconciliation report](#fetch-a-reconciliation-report)
67 | + [Ledgers](#ledgers)
68 | + [Retrieve account balances](#retrieve-account-balances)
69 | + [Retrieve ledger entries](#retrieve-ledger-entries)
70 | + [Recipients](#recipients)
71 | + [Invite Recipients](#invite-recipients)
72 | + [Retrieve a recipient](#retrieve-a-recipient)
73 | + [Retrieve recipients by status](#retrieve-recipients-by-status)
74 | + [Update a recipient](#update-a-recipient)
75 | + [Remove a recipient](#remove-a-recipient)
76 | + [Request a recipient webhook to be resent](#request-a-recipient-webhook-to-be-resent)
77 | + [Payouts](#payouts)
78 | + [Create a payout](#create-a-payout)
79 | + [Create a payout batch](#create-a-payout-batch)
80 | + [Retrieve a payout](#retrieve-a-payout)
81 | + [Retrieve a payout batch](#retrieve-a-payout-batch)
82 | + [Retrieve payouts based on status](#retrieve-payouts-based-on-status)
83 | + [Retrieve payout batches based on status](#retrieve-payout-batches-based-on-status)
84 | + [Cancel a payout](#cancel-a-payout)
85 | + [Cancel a payout batch](#cancel-a-payout-batch)
86 | + [Request a payout webhook to be resent](#request-a-payout-webhook-to-be-resent)
87 | + [Request a payout batch webhook to be resent](#request-a-payout-batch-webhook-to-be-resent)
88 | + [Currencies](#currencies)
89 | + [Retrieve the supported currencies](#retrieve-the-supported-currencies)
90 | + [Rates](#rates)
91 | + [Retrieve the exchange rate table maintained by BitPay](#retrieve-the-exchange-rate-table-maintained-by-bitpay)
92 | + [Retrieve all the rates for a given cryptocurrency](#retrieve-all-the-rates-for-a-given-cryptocurrency)
93 | + [Retrieve the rate for a cryptocurrency / fiat pair](#retrieve-the-rate-for-a-cryptocurrency--fiat-pair)
94 | - [Testing](#testing)
95 | - [Changelog](#changelog)
96 | - [Contributing](#contributing)
97 | - [Security](#security)
98 | - [Credits](#credits)
99 | - [License](#license)
100 |
101 | ## Installation
102 |
103 | ### Install package
104 |
105 | You can install the package via composer:
106 |
107 | ```bash
108 | composer require vrajroham/laravel-bitpay
109 | ```
110 |
111 | ### Publish config file
112 |
113 | Publish config file with:
114 |
115 | ```bash
116 | php artisan vendor:publish --provider="Vrajroham\LaravelBitpay\LaravelBitpayServiceProvider"
117 | ```
118 |
119 | This will create a `laravel-bitpay.php` file inside your **config** directory.
120 |
121 | ### Add configuration values
122 |
123 | Add the following keys to your `.env` file and update the values to match your
124 | preferences ([read more about configuration](https://support.bitpay.com/hc/en-us/articles/115003001063-How-do-I-configure-the-PHP-BitPay-Client-Library-)):
125 |
126 | ```dotenv
127 | BITPAY_PRIVATE_KEY_PATH=
128 | BITPAY_NETWORK=testnet
129 | BITPAY_KEY_STORAGE_PASSWORD=RandomPasswordForEncryption
130 | BITPAY_ENABLE_MERCHANT=true
131 | BITPAY_ENABLE_PAYOUT=false
132 | BITPAY_MERCHANT_TOKEN=
133 | BITPAY_PAYOUT_TOKEN=
134 | ```
135 |
136 | ### Generate Key-Pair and API Token(s)
137 |
138 | The `laravel-bitpay:createkeypair` command generates a BitPay API Token and Pairing Code for each enabled facade:
139 |
140 | ```bash
141 | php artisan laravel-bitpay:createkeypair
142 | ```
143 |
144 |
145 |
146 | > :information_source: By default, the command will use the (valid) existing private key located
147 | > at `BITPAY_PRIVATE_KEY_PATH`.
148 | > You may specify the `--fresh` or `-f` option to explicitly generate a fresh private key, from which tokens are
149 | > derived.
150 |
151 | After successful API Token generation, you will need to approve it by visiting the provided link.
152 |
153 | :warning: **Note that the `payout` facade must be enabled on your BitPay merchant account before you can approve and use
154 | the related API Token. This means you won't be able to perform actions on the [Recipients](#recipients)
155 | and [Payouts](#payouts) resources. To enable Payouts
156 | functionality, [Contact BitPay Support](https://bitpay.com/request-help/wizard?category=merchant).**
157 |
158 | ### Configure Webhooks (Optional)
159 |
160 | BitPay resource status updates are completely based on webhooks (IPNs). LaravelBitPay is fully capable of automatically
161 | handling webhook requests. Whenever a webhook is received from BitPay's server, `BitpayWebhookReceived` event is
162 | dispatched. Take the following steps to configure your application for webhook listening:
163 |
164 | #### 1. Setup your webhook route
165 |
166 | Resolve the `bitPayWebhook` route macro in your desired route file (`web.php` is recommended). The macro accepts a
167 | single, optional argument, which is the URI path at which you want to receive BitPay webhook `POST` requests. If none is
168 | provided, it defaults to `'laravel-bitpay/webhook'`:
169 |
170 | ```php
171 | // ... your other 'web' routes
172 |
173 | Route::bitPayWebhook(); // https://example.com/laravel-bitpay/webhook
174 |
175 | // OR ...
176 |
177 | Route::bitPayWebhook('receive/webhooks/here'); // https://example.com/receive/webhooks/here
178 | ```
179 |
180 | > :information_source: To retrieve your newly created webhook route anywhere in your application,
181 | > use: `route('laravel-bitpay.webhook.capture')`
182 |
183 | LaravelBitPay also offers the convenience of auto-populating your configured webhook url on applicable resources.
184 | Specifically when:
185 |
186 | - [Creating an Invoice](#create-an-invoice)
187 | - [Inviting Recipients](#invite-recipients)
188 | - Creating a [Payout](#create-a-payout)/[Payout Batch](#create-a-payout-batch)
189 |
190 | You may enable this feature per-resource by uncommenting the respective entry within the `auto_populate_webhook` array
191 | found in the `laravel-bitpay.php` config file.
192 |
193 | :warning: **If a value is manually set, most likely via `$resource->setNotificationURL('https://...')` during resource
194 | initialization, auto-population is overridden.**
195 |
196 | #### 2. Setup your webhook listener
197 |
198 | Start by generating an event listener:
199 |
200 | ```bash
201 | php artisan make:listener BitPayWebhookListener --event=\Vrajroham\LaravelBitpay\Events\BitpayWebhookReceived
202 | ```
203 |
204 | Then, implement your application-specific logic in the `handle(...)` function of the generated listener.
205 |
206 | In the following example, we assume you have previously [created an invoice](#create-an-invoice), storing its `token`
207 | on your internal `Order` model:
208 |
209 | ```php
210 | /**
211 | * Handle the webhook event, keeping in mind that the server doesn't trust the client (us), so neither should
212 | * we trust the server. Well, trust, but verify.
213 | *
214 | * @param BitpayWebhookReceived $event
215 | * @return void
216 | */
217 | public function handle(BitpayWebhookReceived $event)
218 | {
219 | // Extract event payload
220 | $payload = $event->payload;
221 |
222 | // Verify that webhook is for a BitPay Invoice resource
223 | if (in_array($payload['event']['code'], array_keys(BitPayConstants::INVOICE_WEBHOOK_CODES))) {
224 | try {
225 | // Do not trust the webhook data. Pull the referenced Invoice from BitPay's server
226 | $invoice = LaravelBitpay::getInvoice($payload['data']['id']);
227 |
228 | // Now grab our internal Order instance for this supposed Invoice
229 | $order = Order::whereOrderId($invoice->getOrderId())->first();
230 |
231 | // Verify Invoice token, previously stored at time of creation
232 | // Learn more at: https://github.com/vrajroham/laravel-bitpay#create-an-invoice
233 | if ($invoice->getToken() !== $order->invoice_token) {
234 | return;
235 | }
236 |
237 | $invoice_status = $invoice->getStatus();
238 |
239 | // Do something about the new Invoice status
240 | if ($invoice_status === InvoiceStatus::Paid) {
241 | $order->update(['status' => $invoice_status]) && OrderStatusChanged::dispatch($order->refresh());
242 | }
243 | } catch (BitPayException $e) {
244 | Log::error($e);
245 | }
246 | }
247 | }
248 | ```
249 |
250 | Finally, map your listener to the `BitpayWebhookReceived` event inside the `$listen` array of
251 | your `EventServiceProvider`:
252 |
253 | ```php
254 | /**
255 | * The event listener mappings for the application.
256 | *
257 | * @var array
258 | */
259 | protected $listen = [
260 | // ... other event-listener mappings
261 | BitpayWebhookReceived::class => [
262 | BitPayWebhookListener::class,
263 | ],
264 | ]
265 | ```
266 |
267 | ## Examples
268 |
269 | ### Invoices
270 |
271 | Invoices are time-sensitive payment requests addressed to specific buyers. An invoice has a fixed price, typically
272 | denominated in fiat currency. It also has an equivalent price in the supported cryptocurrencies, calculated by BitPay,
273 | at a locked exchange rate with an expiration time of 15 minutes.
274 |
275 | #### Create an invoice
276 |
277 | In this example we assume you've already created an instance of your equivalent `Order` model, to be associated with
278 | this Invoice (referred to as `$order`):
279 |
280 | ```php
281 | // Create instance of Invoice
282 | $invoice = LaravelBitpay::Invoice(449.99, Currency::USD); // Always use the BitPay Currency model to prevent typos
283 |
284 | // Set item details (Only 1 item per Invoice)
285 | $invoice->setItemDesc('You "Joe Goldberg" Life-Size Wax Figure');
286 | $invoice->setItemCode('sku-1234');
287 | $invoice->setPhysical(true); // Set to false for digital/virtual items
288 |
289 | // Ensure you provide a unique OrderId for each Invoice
290 | $invoice->setOrderId($order->order_id);
291 |
292 | // Create Buyer Instance
293 | $buyer = LaravelBitpay::Buyer();
294 | $buyer->setName('John Doe');
295 | $buyer->setEmail('john.doe@example.com');
296 | $buyer->setAddress1('2630 Hegal Place');
297 | $buyer->setAddress2('Apt 42');
298 | $buyer->setLocality('Alexandria');
299 | $buyer->setRegion('VA');
300 | $buyer->setPostalCode(23242);
301 | $buyer->setCountry('US');
302 | $buyer->setNotify(true); // Instructs BitPay to email Buyer about their Invoice
303 |
304 | // Attach Buyer to Invoice
305 | $invoice->setBuyer($buyer);
306 |
307 | // Set URL that Buyer will be redirected to after completing the payment, via GET Request
308 | $invoice->setRedirectURL(route('your-bitpay-success-url'));
309 | // Set URL that Buyer will be redirected to after closing the invoice or after the invoice expires, via GET Request
310 | $invoice->setCloseURL(route('your-bitpay-cancel-url'));
311 | $invoice->setAutoRedirect(true);
312 |
313 | // Optional. Learn more at: https://github.com/vrajroham/laravel-bitpay#1-setup-your-webhook-route
314 | $invoice->setNotificationUrl('https://example.com/your-custom-webhook-url');
315 |
316 | // This is the recommended IPN format that BitPay advises for all new implementations
317 | $invoice->setExtendedNotifications(true);
318 |
319 | // Create invoice on BitPay's server
320 | $invoice = LaravelBitpay::createInvoice($invoice);
321 |
322 | $invoiceId = $invoice->getId();
323 | $invoiceToken = $invoice->getToken();
324 |
325 | // You should save Invoice ID and Token, for your reference
326 | $order->update(['invoice_id' => $invoiceId, 'invoice_token' => $invoiceToken]);
327 |
328 | // Redirect user to the Invoice's hosted URL to complete payment
329 | $paymentUrl = $invoice->getUrl();
330 | return Redirect::to($paymentUrl);
331 | ```
332 |
333 | > :information_source: It is highly recommended you store the Invoice ID and Token on your internal model(s). The token
334 | > can come in handy when verifying webhooks.
335 |
336 | #### Retrieve an existing invoice
337 |
338 | ```php
339 | $invoice = LaravelBitpay::getInvoice('invoiceId_sGsdVsgheF');
340 | ```
341 |
342 | #### Retrieve a list of existing invoices
343 |
344 | In this example we retrieve all MTD (Month-To-Date) invoices:
345 |
346 | ```php
347 | $startDate = date('Y-m-d', strtotime('first day of this month'));
348 | $endDate = date('Y-m-d');
349 |
350 | $invoices = LaravelBitpay::getInvoices($startDate, $endDate);
351 | ```
352 |
353 | #### Request an Invoice webhook to be resent
354 |
355 | ```php
356 | // True if the webhook has been resent for the current invoice status, false otherwise.
357 | $webhookResent = LaravelBitpay::requestInvoiceWebhook('invoiceId_sGsdVsgheF');
358 | ```
359 |
360 | ### Refunds
361 |
362 | Refund requests are full or partial refunds associated to an invoice. Fully paid invoices can be refunded via the
363 | merchant's authorization to issue a refund, while underpaid and overpaid invoices are automatically executed by BitPay
364 | to issue the underpayment or overpayment amount to the customer.
365 |
366 | #### Refund an invoice
367 |
368 | The item Jane purchased was dead on arrival. Give back the lady her crypto:
369 |
370 | ```php
371 | $invoice = LaravelBitpay::getInvoice('invoiceId_sGsdVsgheF');
372 |
373 | $refundRequested = LaravelBitpay::createRefund($invoice, 'jane.doe@example.com', 0.016, 'ETH');
374 |
375 | if ($refundRequested) {
376 | // Don't just sit there. Do something!
377 | }
378 | ```
379 |
380 | #### Retrieve a refund request
381 |
382 | Let's periodically retrieve (and check the status of) Jane's refund request:
383 |
384 | ```php
385 | $invoice = LaravelBitpay::getInvoice('invoiceId_sGsdVsgheF');
386 |
387 | $refund = LaravelBitpay::getRefund($invoice, 'refundId_pUdhjwGjsg');
388 | ```
389 |
390 | #### Retrieve all refund requests on an invoice
391 |
392 | In this example we retrieve all refund requests related to Jane's invoice:
393 |
394 | ```php
395 | $invoice = LaravelBitpay::getInvoice('invoiceId_sGsdVsgheF');
396 |
397 | $refundRequests = LaravelBitpay::getRefunds($invoice);
398 | ```
399 |
400 | #### Cancel a refund request
401 |
402 | Turns out Jane didn't initially follow the instruction manual. The item works and she no longer wants a refund:
403 |
404 | ```php
405 | $invoice = LaravelBitpay::getInvoice('invoiceId_sGsdVsgheF');
406 |
407 | $refundRequestCancelled = LaravelBitpay::cancelRefund($invoice->getId(), 'refundId_pUdhjwGjsg');
408 | ```
409 |
410 | ### Bills
411 |
412 | Bills are payment requests addressed to specific buyers. Bill line items have fixed prices, typically denominated in
413 | fiat currency.
414 |
415 | #### Create a bill
416 |
417 | In the following example, we create a bill that's due in 10 days:
418 |
419 | ```php
420 | // Initialize Bill
421 | $billData = LaravelBitpay::Bill();
422 | $billData->setNumber('bill1234-EFGH');
423 | $billData->setCurrency(Currency::USD); // Always use the BitPay Currency model to prevent typos
424 | $dueDate = date(BitPayConstants::DATETIME_FORMAT, strtotime('+10 days')); // ISO-8601 formatted date
425 | $billData->setDueDate($dueDate);
426 | $billData->setPassProcessingFee(true); // Let the recipient shoulder BitPay's processing fee
427 |
428 | // Prepare Bill recipient's data
429 | $billData->setName('John Doe');
430 | $billData->setAddress1('2630 Hegal Place');
431 | $billData->setAddress2('Apt 42');
432 | $billData->setCity('Alexandria');
433 | $billData->setState('VA');
434 | $billData->setZip(23242);
435 | $billData->setCountry('US');
436 | $billData->setEmail('john.doe@example.com');
437 | $billData->setCc(['jane.doe@example.com']);
438 | $billData->setPhone('555-123-456');
439 |
440 | // Prepare Bill's line item(s)
441 | $itemUno = LaravelBitpay::BillItem();
442 | $itemUno->setDescription('Squid Game "Front Man" Costume');
443 | $itemUno->setPrice(49.99);
444 | $itemUno->setQuantity(2);
445 |
446 | $itemDos = LaravelBitpay::BillItem();
447 | $itemDos->setDescription('GOT "House Stark" Sterling Silver Pendant');
448 | $itemDos->setPrice(35);
449 | $itemDos->setQuantity(1);
450 |
451 | $billData->setItems([$itemUno, $itemDos]);
452 |
453 | // Create Bill
454 | $bill = LaravelBitpay::createBill($billData);
455 |
456 | // Store the Bill's BitPay ID and URL for future reference
457 | $billId = $bill->getId();
458 | $billPaymentUrl = $bill->getUrl();
459 |
460 | // OR
461 |
462 | // Redirect the recipient to BitPay's hosted Bill payment page
463 | Redirect::to($billPaymentUrl);
464 | ```
465 |
466 | #### Retrieve a bill
467 |
468 | ```php
469 | $bill = LaravelBitpay::getBill('bill1234-EFGH');
470 | ```
471 |
472 | #### Retrieve a list of existing bills
473 |
474 | You can narrow down the retrieved list by specifying a Bill status:
475 |
476 | ```php
477 | $paidBills = LaravelBitpay::getBills(BillStatus::Paid);
478 | ```
479 |
480 | #### Update a bill
481 |
482 | We managed to upsell a product to our client. Let's add an extra line item to their existing Bill:
483 |
484 | ```php
485 | $existingBill = LaravelBitpay::getBill('bill1234-EFGH');
486 | $existingItems = $existingBill->getItems();
487 |
488 | $billData = LaravelBitpay::Bill();
489 | $billData->setId($existingBill->getId());
490 |
491 | $itemTres = LaravelBitpay::BillItem();
492 | $itemTres->setDescription('The Tomorrow War "White Spike" Life-Size Wax Figure');
493 | $itemTres->setPrice(189.99);
494 | $itemTres->setQuantity(1);
495 |
496 | $billData->setItems(array_merge($existingItems, [$itemTres]));
497 |
498 | // Update Bill
499 | $updatedBill = LaravelBitpay::updateBill($billData, $billData->getId());
500 | ```
501 |
502 | #### Deliver a bill via email
503 |
504 | ```php
505 | $bill = LaravelBitpay::getBill('bill1234-EFGH');
506 |
507 | $billDelivered = LaravelBitpay::deliverBill($bill->getId(), $bill->getToken());
508 |
509 | if ($billDelivered) {
510 | // Bill delivered successfully. Do something about that... or not.
511 | }
512 | ```
513 |
514 | ### Subscriptions
515 |
516 | Subscriptions are repeat billing agreements with specific buyers. BitPay sends bill emails to buyers identified in
517 | active subscriptions according to the specified schedule.
518 |
519 | #### Create a subscription
520 |
521 | Let's create a subscription that's delivered on the 28th of each month and due on the first of the following month, at 9
522 | AM, respectively:
523 |
524 | ```php
525 | // Initialize Subscription
526 | $subscriptionData = LaravelBitpay::Subscription();
527 | $subscriptionData->setSchedule(BitPayConstants::SUBSCRIPTION_SCHEDULE_MONTHLY);
528 |
529 | // Optional recurring bill data
530 | $billData = [
531 | 'number' => 'subscription1234-ABCD',
532 | 'name' => 'John Doe',
533 | 'address1' => '2630 Hegal Place',
534 | 'address2' => 'Apt 42',
535 | 'city' => 'Alexandria',
536 | 'state' => 'VA',
537 | 'zip' => 23242,
538 | 'country' => 'US',
539 | 'cc' => ['jane.doe@example.com'],
540 | 'phone' => '555-123-456',
541 | 'passProcessingFee' => true,
542 | ];
543 |
544 | $dueDate = date(BitPayConstants::DATETIME_FORMAT, strtotime('first day of next month 9 AM'));
545 |
546 | $billItems = array(
547 | LaravelBitpay::SubscriptionItem(100.00, 1, 'Web Hosting - 4 CPUs | 16GB Memory | 400GB SSD'),
548 | LaravelBitpay::SubscriptionItem(80.00, 1, 'Basic Website Maintenance'),
549 | );
550 |
551 | // Autofill optional bill data
552 | $mapper = new JsonMapper();
553 | $billData = $mapper->map(
554 | $billData,
555 | LaravelBitpay::BillData(
556 | Currency::USD, // Always use the BitPay Currency model to prevent typos
557 | 'john.doe@example.com',
558 | $dueDate,
559 | $billItems
560 | )
561 | );
562 |
563 | $subscriptionData->setBillData($billData);
564 |
565 | // A little wizardry to always get the 28th day of the current month (leap year safe)
566 | $deliveryDate = strtotime('first day of this month 9 AM');
567 | $deliveryDate = new \DateTime("@$deliveryDate");
568 | $deliveryDate = $deliveryDate->modify('+27 days')->getTimestamp();
569 | $deliveryDate = date(BitPayConstants::DATETIME_FORMAT, $deliveryDate);
570 |
571 | $subscriptionData->setNextDelivery($deliveryDate);
572 |
573 | // Create the Subscription on BitPay
574 | $subscription = LaravelBitpay::createSubscription($subscriptionData);
575 |
576 | // You may then store the Subscription ID for future reference
577 | $subscriptionId = $subscription->getId();
578 | ```
579 |
580 | #### Retrieve a subscription
581 |
582 | ```php
583 | $subscription = LaravelBitpay::getSubscription('6gqe8y5mkc5Qx2a9zmspgx');
584 | ```
585 |
586 | #### Retrieve a list of existing subscriptions
587 |
588 | You can narrow down the retrieved list by specifying a Subscription status:
589 |
590 | ```php
591 | $activeSubscriptions = LaravelBitpay::getSubscriptions(SubscriptionStatus::Active);
592 | ```
593 |
594 | #### Update a subscription
595 |
596 | In this example we activate a Subscription by updating its status:
597 |
598 | ```php
599 | $subscriptionData = LaravelBitpay::Subscription();
600 | $subscriptionData->setId('6gqe8y5mkc5Qx2a9zmspgx');
601 | $subscriptionData->setStatus(SubscriptionStatus::Active);
602 |
603 | $activatedSubscription = LaravelBitpay::updateSubscription($subscriptionData, $subscriptionData->getId());
604 | ```
605 |
606 | ### Settlements
607 |
608 | Settlements are transfers of payment profits from BitPay to bank accounts and cryptocurrency wallets owned by merchants,
609 | partners, etc.
610 |
611 | #### Retrieve settlements
612 |
613 | In this example we retrieve completed YTD (Year-To-Date) settlements denominated in Euros (EUR). We only need 100
614 | records, starting from the 5th one:
615 |
616 | ```php
617 | $startDate = date('Y-m-d', strtotime('first day of this year'));
618 | $endDate = date('Y-m-d');
619 |
620 | $eurSettlements = LaravelBitpay::getSettlements(
621 | Currency::EUR,
622 | $startDate,
623 | $endDate,
624 | BitPayConstants::SETTLEMENT_STATUS_COMPLETED,
625 | 100,
626 | 4
627 | );
628 | ```
629 |
630 | #### Retrieve a settlement
631 |
632 | ```php
633 | $settlement = LaravelBitpay::getSettlement('settlementId_uidwb3668');
634 | ```
635 |
636 | #### Fetch a reconciliation report
637 |
638 | A reconciliation report is a detailed report of the activity within the settlement period, in order to reconcile
639 | incoming settlements from BitPay.
640 |
641 | ```php
642 | $settlement = LaravelBitpay::getSettlement('settlementId_uidwb3668');
643 |
644 | $settlementReport = LaravelBitpay::getSettlementReconciliationReport($settlement);
645 | ```
646 |
647 | ### Ledgers
648 |
649 | Ledgers are records of money movement.
650 |
651 | #### Retrieve account balances
652 |
653 | ```php
654 | $accountBalances = LaravelBitpay::getLedgers();
655 | ```
656 |
657 | #### Retrieve ledger entries
658 |
659 | In this example we retrieve MTD (Month-To-Date) ledger entries denominated in United States Dollars (USD).
660 |
661 | ```php
662 | $startDate = date('Y-m-d', strtotime('first day of this month'));
663 | $endDate = date('Y-m-d');
664 |
665 | $usdLedgerEntries = LaravelBitpay::getLedger(Currency::USD, $startDate, $endDate);
666 | ```
667 |
668 | ### Recipients
669 |
670 | The Recipient resource allows a merchant to invite their clients to signup for a BitPay personal account.
671 |
672 | :warning: **Your BitPay Merchant account must be authorized for Payouts functionality. To enable Payouts
673 | functionality, [Contact BitPay Support](https://bitpay.com/request-help/wizard?category=merchant).**
674 |
675 | #### Invite Recipients
676 |
677 | ```php
678 | // Init individual recipients
679 | $jane = LaravelBitpay::PayoutRecipient('jane.doe@example.com', 'Plain Jane');
680 | $ada = LaravelBitpay::PayoutRecipient('ada@cardano.org', 'Ada Lovelace');
681 |
682 | // Optional. Learn more at https://github.com/vrajroham/laravel-bitpay#1-setup-your-webhook-route
683 | $ada->setNotificationUrl('https://example.com/your-custom-webhook-url');
684 |
685 | // Batch all individual recipients
686 | $recipients = LaravelBitpay::PayoutRecipients([$jane, $ada]);
687 |
688 | // Submit invites
689 | $recipientsInvited = LaravelBitpay::invitePayoutRecipients($recipients);
690 |
691 | // Do something with the returned invitees
692 | foreach ($recipientsInvited as $recipient) {
693 | $recipientId = $recipient->getId();
694 | $recipientToken = $recipient->getToken();
695 |
696 | // ... store Recipient ID and Token somewhere persistent
697 |
698 | // Perform other desired actions
699 | \App\Events\LookOutForAnInviteEmail::dispatch($recipient->getEmail());
700 | }
701 | ```
702 |
703 | > :information_source: It is highly recommended you store the Recipient ID and Token on your internal model(s). The
704 | > token can come in handy when verifying webhooks.
705 |
706 | #### Retrieve a recipient
707 |
708 | ```php
709 | $recipient = LaravelBitpay::getPayoutRecipient('recipientId_adaLovelace')
710 | ```
711 |
712 | #### Retrieve recipients by status
713 |
714 | In this example, we retrieve 100 recipients (starting from the 50th) that have passed the good 'ole Onfido ID
715 | verification checks:
716 |
717 | ```php
718 | $verifiedRecipients = LaravelBitpay::getPayoutRecipients(RecipientStatus::VERIFIED, 100, 49);
719 | ```
720 |
721 | #### Update a recipient
722 |
723 | ```php
724 | $recipient = LaravelBitpay::getPayoutRecipient('recipientId_adaLovelace');
725 | $recipient->setLabel('Cardano To The Moon');
726 |
727 | $updatedRecipient = LaravelBitpay::updatePayoutRecipient($recipient->getId(), $recipient);
728 | ```
729 |
730 | #### Remove a recipient
731 |
732 | ```php
733 | $recipientRemoved = LaravelBitpay::removePayoutRecipient('recipientId_janeDoe');
734 | ```
735 |
736 | #### Request a recipient webhook to be resent
737 |
738 | ```php
739 | // True if the webhook has been resent for the current recipient status, false otherwise.
740 | $webhookResent = LaravelBitpay::requestPayoutRecipientWebhook('recipientId_adaLovelace');
741 | ```
742 |
743 | ### Payouts
744 |
745 | Payouts are individual (or batches of) bitcoin payments to employees, customers, partners, etc.
746 |
747 | :warning: **Your BitPay Merchant account must be authorized for Payouts functionality. To enable Payouts
748 | functionality, [Contact BitPay Support](https://bitpay.com/request-help/wizard?category=merchant).**
749 |
750 | #### Create a payout
751 |
752 | Let's assume Ada Lovelace accepted our [invitation](#invite-recipients). In this example, we schedule her an individual
753 | payout for a 5-star rating she received from a referral:
754 |
755 | ```php
756 | // Initialize a Payout
757 | // Pay Ada in USD and record it on the BTC ledger
758 | $payoutData = LaravelBitpay::Payout(50.00, Currency::USD, Currency::BTC);
759 |
760 | // Set Payout details
761 | $payoutData->setRecipientId('recipientId_adaLovelace'); // From previously invited Recipient
762 | $payoutData->setReference('1234'); // Uniquely identifies an equivalent payout entry in your system
763 | $payoutData->setLabel('5-Star Bonus Affiliate Payment #1234 for Dec 2021');
764 | $payoutData->setEffectiveDate('2021-12-31');
765 |
766 | // Optional. Learn more at https://github.com/vrajroham/laravel-bitpay#1-setup-your-webhook-route
767 | $payoutData->setNotificationURL('https://example.com/your-custom-webhook-url');
768 |
769 | // Create Payout on BitPay's server
770 | $payout = LaravelBitpay::createPayout($payoutData);
771 |
772 | $payoutId = $payout->getId();
773 | $payoutToken = $payout->getToken();
774 |
775 | // ... store Payout ID and Token somewhere persistent
776 | ```
777 |
778 | > :information_source: It is highly recommended you store the Payout ID and Token on your internal model(s). The token
779 | > can come in handy when verifying webhooks.
780 |
781 | #### Create a payout batch
782 |
783 | Let's pay our two top-tier affiliates for all their hard work, batching both payments into a single API call, for the
784 | efficiency of it.
785 |
786 | ```php
787 | // Initialize a Payout Batch
788 | $payoutBatchData = LaravelBitpay::PayoutBatch(Currency::USD); // Pay recipients in USD
789 | $payoutBatchData->setLedgerCurrency(Currency::ETH); // Record the payout batch on the ETH ledger
790 | $payoutBatchData->setAmount(500.00);
791 | $payoutBatchData->setReference('Aff_Jan-Feb_2022'); // Uniquely identifies an equivalent payout batch in your system
792 | $payoutBatchData->setLabel('Affiliate Payments for Jan-Feb 2022');
793 | $payoutBatchData->setEffectiveDate('2022-02-28');
794 |
795 | // Optional. Learn more at https://github.com/vrajroham/laravel-bitpay#1-setup-your-webhook-route
796 | $payoutBatchData->setNotificationURL('https://example.com/your-custom-webhook-url');
797 |
798 | // Define Instruction(s)
799 | $payJane = LaravelBitpay::PayoutInstruction(
800 | 250.00,
801 | RecipientReferenceMethod::RECIPIENT_ID,
802 | 'recipientId_janeDoe'
803 | );
804 | $payJane->setLabel('Affiliate Payment #1234 for Jan-Feb 2022');
805 |
806 | $payAda = LaravelBitpay::PayoutInstruction(
807 | 250.00,
808 | RecipientReferenceMethod::RECIPIENT_ID,
809 | 'recipientId_adaLovelace'
810 | );
811 | $payAda->setLabel('Affiliate Payment #5678 for Jan-Feb 2022');
812 |
813 | // Attach Instruction(s) to Payout Batch
814 | $payoutBatchData->setInstructions([$payJane, $payAda]);
815 |
816 | // Create Payout Batch on BitPay's server
817 | $payoutBatch = LaravelBitpay::createPayoutBatch($payoutBatchData);
818 |
819 | $payoutBatchId = $payoutBatch->getId();
820 | $payoutBatchToken = $payoutBatch->getToken();
821 |
822 | // ... store Payout Batch ID and Token somewhere persistent
823 | ```
824 |
825 | > :information_source: It is highly recommended you store the Payout Batch ID and Token on your internal model(s).
826 | > The token can come in handy when verifying webhooks.
827 |
828 | #### Retrieve a payout
829 |
830 | ```php
831 | $payout = LaravelBitpay::getPayout('payoutId_jws43dbnfpg');
832 | ```
833 |
834 | #### Retrieve a payout batch
835 |
836 | ```php
837 | $payoutBatch = LaravelBitpay::getPayoutBatch('payoutBatchId_jws43dbnfpg');
838 | ```
839 |
840 | #### Retrieve payouts based on status
841 |
842 | In this example, we retrieve all completed, Year-To-Date (YTD) payouts.
843 |
844 | ```php
845 | $startDate = date('Y-m-d', strtotime('first day of this year'));
846 | $endDate = date('Y-m-d');
847 |
848 | $completedPayouts = LaravelBitpay::getPayouts($startDate, $endDate, PayoutStatus::Complete);
849 | ```
850 |
851 | #### Retrieve payout batches based on status
852 |
853 | In this example, we retrieve all cancelled, Year-To-Date (YTD) payout batches.
854 |
855 | ```php
856 | $startDate = date('Y-m-d', strtotime('first day of this year'));
857 | $endDate = date('Y-m-d');
858 |
859 | $cancelledPayoutBatches = LaravelBitpay::getPayoutBatches($startDate, $endDate, PayoutStatus::Cancelled);
860 | ```
861 |
862 | #### Cancel a payout
863 |
864 | ```php
865 | $payoutCancelled = LaravelBitpay::cancelPayout('payoutId_jws43dbnfpg');
866 | ```
867 |
868 | #### Cancel a payout batch
869 |
870 | ```php
871 | $payoutBatchCancelled = LaravelBitpay::cancelPayoutBatch('payoutBatchId_jws43dbnfpg');
872 | ```
873 |
874 | #### Request a payout webhook to be resent
875 |
876 | ```php
877 | // True if the webhook has been resent for the current payout status, false otherwise.
878 | $webhookResent = LaravelBitpay::requestPayoutWebhook('payoutId_jws43dbnfpg');
879 | ```
880 |
881 | #### Request a payout batch webhook to be resent
882 |
883 | ```php
884 | // True if the webhook has been resent for the current payout batch status, false otherwise.
885 | $webhookResent = LaravelBitpay::requestPayoutBatchWebhook('payoutBatchId_jws43dbnfpg');
886 | ```
887 |
888 | ### Currencies
889 |
890 | Currencies are fiat currencies supported by BitPay.
891 |
892 | #### Retrieve the supported currencies
893 |
894 | In this example, we retrieve the list of supported BitPay Currency objects.
895 |
896 | ```php
897 | $supportedCurrencies = LaravelBitpay::getCurrencies();
898 | ```
899 |
900 | ### Rates
901 |
902 | Rates are exchange rates, representing the number of fiat currency units equivalent to one BTC.
903 |
904 | #### Retrieve the exchange rate table maintained by BitPay
905 |
906 | ```php
907 | $rates = LaravelBitpay::getRates();
908 |
909 | $btcToUsdRate = $rates->getRate(Currency::USD); // Always use the BitPay Currency model to prevent typos
910 | ```
911 |
912 | #### Retrieve all the rates for a given cryptocurrency
913 |
914 | ```php
915 | $ethRates = LaravelBitpay::getCurrencyRates(Currency::ETH);
916 |
917 | $ethToUsdRate = $ethRates->getRate(Currency::USD);
918 | ```
919 |
920 | #### Retrieve the rate for a cryptocurrency / fiat pair
921 |
922 | ```php
923 | $dogeToUsdRate = LaravelBitpay::getCurrencyPairRate(Currrency::DOGE, Currency::USD);
924 | ```
925 |
926 | ## Testing
927 |
928 | ```bash
929 | composer test
930 | ```
931 |
932 | ## Changelog
933 |
934 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
935 |
936 | ## Contributing
937 |
938 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
939 |
940 | ## Security
941 |
942 | If you discover any security related issues, please email vaibhavraj@vrajroham.me or iamalexstewart@gmail.com instead of
943 | using the issue tracker.
944 |
945 | ## Credits
946 |
947 | - [Vaibhavraj Roham](https://github.com/vrajroham)
948 | - [Alex Stewart](https://github.com/alexstewartja)
949 | - [All Contributors](../../contributors)
950 |
951 | ## License
952 |
953 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
954 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | charset = utf-8
3 | end_of_line = lf
4 | indent_size = 4
5 | indent_style = space
6 | insert_final_newline = true
7 | max_line_length = 120
8 | tab_width = 4
9 | ij_continuation_indent_size = 8
10 | ij_formatter_off_tag = @formatter:off
11 | ij_formatter_on_tag = @formatter:on
12 | ij_formatter_tags_enabled = false
13 | ij_smart_tabs = false
14 | ij_visual_guides = none
15 | ij_wrap_on_typing = false
16 |
17 | [*.blade.php]
18 | ij_blade_keep_indents_on_empty_lines = false
19 |
20 | [*.css]
21 | ij_css_align_closing_brace_with_properties = false
22 | ij_css_blank_lines_around_nested_selector = 1
23 | ij_css_blank_lines_between_blocks = 1
24 | ij_css_brace_placement = end_of_line
25 | ij_css_enforce_quotes_on_format = false
26 | ij_css_hex_color_long_format = false
27 | ij_css_hex_color_lower_case = false
28 | ij_css_hex_color_short_format = false
29 | ij_css_hex_color_upper_case = false
30 | ij_css_keep_blank_lines_in_code = 2
31 | ij_css_keep_indents_on_empty_lines = false
32 | ij_css_keep_single_line_blocks = false
33 | ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
34 | ij_css_space_after_colon = true
35 | ij_css_space_before_opening_brace = true
36 | ij_css_use_double_quotes = true
37 | ij_css_value_alignment = do_not_align
38 |
39 | [*.feature]
40 | indent_size = 2
41 | ij_gherkin_keep_indents_on_empty_lines = false
42 |
43 | [*.haml]
44 | indent_size = 2
45 | ij_haml_keep_indents_on_empty_lines = false
46 |
47 | [*.less]
48 | indent_size = 2
49 | ij_less_align_closing_brace_with_properties = false
50 | ij_less_blank_lines_around_nested_selector = 1
51 | ij_less_blank_lines_between_blocks = 1
52 | ij_less_brace_placement = 0
53 | ij_less_enforce_quotes_on_format = false
54 | ij_less_hex_color_long_format = false
55 | ij_less_hex_color_lower_case = false
56 | ij_less_hex_color_short_format = false
57 | ij_less_hex_color_upper_case = false
58 | ij_less_keep_blank_lines_in_code = 2
59 | ij_less_keep_indents_on_empty_lines = false
60 | ij_less_keep_single_line_blocks = false
61 | ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
62 | ij_less_space_after_colon = true
63 | ij_less_space_before_opening_brace = true
64 | ij_less_use_double_quotes = true
65 | ij_less_value_alignment = 0
66 |
67 | [*.sass]
68 | indent_size = 2
69 | ij_sass_align_closing_brace_with_properties = false
70 | ij_sass_blank_lines_around_nested_selector = 1
71 | ij_sass_blank_lines_between_blocks = 1
72 | ij_sass_brace_placement = 0
73 | ij_sass_enforce_quotes_on_format = false
74 | ij_sass_hex_color_long_format = false
75 | ij_sass_hex_color_lower_case = false
76 | ij_sass_hex_color_short_format = false
77 | ij_sass_hex_color_upper_case = false
78 | ij_sass_keep_blank_lines_in_code = 2
79 | ij_sass_keep_indents_on_empty_lines = false
80 | ij_sass_keep_single_line_blocks = false
81 | ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
82 | ij_sass_space_after_colon = true
83 | ij_sass_space_before_opening_brace = true
84 | ij_sass_use_double_quotes = true
85 | ij_sass_value_alignment = 0
86 |
87 | [*.scss]
88 | indent_size = 2
89 | ij_scss_align_closing_brace_with_properties = false
90 | ij_scss_blank_lines_around_nested_selector = 1
91 | ij_scss_blank_lines_between_blocks = 1
92 | ij_scss_brace_placement = 0
93 | ij_scss_enforce_quotes_on_format = false
94 | ij_scss_hex_color_long_format = false
95 | ij_scss_hex_color_lower_case = false
96 | ij_scss_hex_color_short_format = false
97 | ij_scss_hex_color_upper_case = false
98 | ij_scss_keep_blank_lines_in_code = 2
99 | ij_scss_keep_indents_on_empty_lines = false
100 | ij_scss_keep_single_line_blocks = false
101 | ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow
102 | ij_scss_space_after_colon = true
103 | ij_scss_space_before_opening_brace = true
104 | ij_scss_use_double_quotes = true
105 | ij_scss_value_alignment = 0
106 |
107 | [*.twig]
108 | ij_twig_keep_indents_on_empty_lines = false
109 | ij_twig_spaces_inside_comments_delimiters = true
110 | ij_twig_spaces_inside_delimiters = true
111 | ij_twig_spaces_inside_variable_delimiters = true
112 |
113 | [*.vue]
114 | indent_size = 2
115 | tab_width = 2
116 | ij_continuation_indent_size = 4
117 | ij_vue_indent_children_of_top_level = template
118 | ij_vue_interpolation_new_line_after_start_delimiter = true
119 | ij_vue_interpolation_new_line_before_end_delimiter = true
120 | ij_vue_interpolation_wrap = off
121 | ij_vue_keep_indents_on_empty_lines = false
122 | ij_vue_spaces_within_interpolation_expressions = true
123 | ij_vue_uniform_indent = true
124 |
125 | [.editorconfig]
126 | ij_editorconfig_align_group_field_declarations = false
127 | ij_editorconfig_space_after_colon = false
128 | ij_editorconfig_space_after_comma = true
129 | ij_editorconfig_space_before_colon = false
130 | ij_editorconfig_space_before_comma = false
131 | ij_editorconfig_spaces_around_assignment_operators = true
132 |
133 | [{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}]
134 | ij_xml_align_attributes = true
135 | ij_xml_align_text = false
136 | ij_xml_attribute_wrap = normal
137 | ij_xml_block_comment_at_first_column = true
138 | ij_xml_keep_blank_lines = 2
139 | ij_xml_keep_indents_on_empty_lines = false
140 | ij_xml_keep_line_breaks = true
141 | ij_xml_keep_line_breaks_in_text = true
142 | ij_xml_keep_whitespaces = false
143 | ij_xml_keep_whitespaces_around_cdata = preserve
144 | ij_xml_keep_whitespaces_inside_cdata = false
145 | ij_xml_line_comment_at_first_column = true
146 | ij_xml_space_after_tag_name = false
147 | ij_xml_space_around_equals_in_attribute = false
148 | ij_xml_space_inside_empty_tag = false
149 | ij_xml_text_wrap = normal
150 |
151 | [{*.ats,*.ts}]
152 | ij_continuation_indent_size = 4
153 | ij_typescript_align_imports = false
154 | ij_typescript_align_multiline_array_initializer_expression = false
155 | ij_typescript_align_multiline_binary_operation = false
156 | ij_typescript_align_multiline_chained_methods = false
157 | ij_typescript_align_multiline_extends_list = false
158 | ij_typescript_align_multiline_for = true
159 | ij_typescript_align_multiline_parameters = true
160 | ij_typescript_align_multiline_parameters_in_calls = false
161 | ij_typescript_align_multiline_ternary_operation = false
162 | ij_typescript_align_object_properties = 0
163 | ij_typescript_align_union_types = false
164 | ij_typescript_align_var_statements = 0
165 | ij_typescript_array_initializer_new_line_after_left_brace = false
166 | ij_typescript_array_initializer_right_brace_on_new_line = false
167 | ij_typescript_array_initializer_wrap = off
168 | ij_typescript_assignment_wrap = off
169 | ij_typescript_binary_operation_sign_on_next_line = false
170 | ij_typescript_binary_operation_wrap = off
171 | ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
172 | ij_typescript_blank_lines_after_imports = 1
173 | ij_typescript_blank_lines_around_class = 1
174 | ij_typescript_blank_lines_around_field = 0
175 | ij_typescript_blank_lines_around_field_in_interface = 0
176 | ij_typescript_blank_lines_around_function = 1
177 | ij_typescript_blank_lines_around_method = 1
178 | ij_typescript_blank_lines_around_method_in_interface = 1
179 | ij_typescript_block_brace_style = end_of_line
180 | ij_typescript_call_parameters_new_line_after_left_paren = false
181 | ij_typescript_call_parameters_right_paren_on_new_line = false
182 | ij_typescript_call_parameters_wrap = off
183 | ij_typescript_catch_on_new_line = false
184 | ij_typescript_chained_call_dot_on_new_line = true
185 | ij_typescript_class_brace_style = end_of_line
186 | ij_typescript_comma_on_new_line = false
187 | ij_typescript_do_while_brace_force = never
188 | ij_typescript_else_on_new_line = false
189 | ij_typescript_enforce_trailing_comma = keep
190 | ij_typescript_extends_keyword_wrap = off
191 | ij_typescript_extends_list_wrap = off
192 | ij_typescript_field_prefix = _
193 | ij_typescript_file_name_style = relaxed
194 | ij_typescript_finally_on_new_line = false
195 | ij_typescript_for_brace_force = never
196 | ij_typescript_for_statement_new_line_after_left_paren = false
197 | ij_typescript_for_statement_right_paren_on_new_line = false
198 | ij_typescript_for_statement_wrap = off
199 | ij_typescript_force_quote_style = false
200 | ij_typescript_force_semicolon_style = false
201 | ij_typescript_function_expression_brace_style = end_of_line
202 | ij_typescript_if_brace_force = never
203 | ij_typescript_import_merge_members = global
204 | ij_typescript_import_prefer_absolute_path = global
205 | ij_typescript_import_sort_members = true
206 | ij_typescript_import_sort_module_name = false
207 | ij_typescript_import_use_node_resolution = true
208 | ij_typescript_imports_wrap = on_every_item
209 | ij_typescript_indent_case_from_switch = true
210 | ij_typescript_indent_chained_calls = true
211 | ij_typescript_indent_package_children = 0
212 | ij_typescript_jsdoc_include_types = false
213 | ij_typescript_jsx_attribute_value = braces
214 | ij_typescript_keep_blank_lines_in_code = 2
215 | ij_typescript_keep_first_column_comment = true
216 | ij_typescript_keep_indents_on_empty_lines = false
217 | ij_typescript_keep_line_breaks = true
218 | ij_typescript_keep_simple_blocks_in_one_line = false
219 | ij_typescript_keep_simple_methods_in_one_line = false
220 | ij_typescript_line_comment_add_space = true
221 | ij_typescript_line_comment_at_first_column = false
222 | ij_typescript_method_brace_style = end_of_line
223 | ij_typescript_method_call_chain_wrap = off
224 | ij_typescript_method_parameters_new_line_after_left_paren = false
225 | ij_typescript_method_parameters_right_paren_on_new_line = false
226 | ij_typescript_method_parameters_wrap = off
227 | ij_typescript_object_literal_wrap = on_every_item
228 | ij_typescript_parentheses_expression_new_line_after_left_paren = false
229 | ij_typescript_parentheses_expression_right_paren_on_new_line = false
230 | ij_typescript_place_assignment_sign_on_next_line = false
231 | ij_typescript_prefer_as_type_cast = false
232 | ij_typescript_prefer_explicit_types_function_expression_returns = false
233 | ij_typescript_prefer_explicit_types_function_returns = false
234 | ij_typescript_prefer_explicit_types_vars_fields = false
235 | ij_typescript_prefer_parameters_wrap = false
236 | ij_typescript_reformat_c_style_comments = false
237 | ij_typescript_space_after_colon = true
238 | ij_typescript_space_after_comma = true
239 | ij_typescript_space_after_dots_in_rest_parameter = false
240 | ij_typescript_space_after_generator_mult = true
241 | ij_typescript_space_after_property_colon = true
242 | ij_typescript_space_after_quest = true
243 | ij_typescript_space_after_type_colon = true
244 | ij_typescript_space_after_unary_not = false
245 | ij_typescript_space_before_async_arrow_lparen = true
246 | ij_typescript_space_before_catch_keyword = true
247 | ij_typescript_space_before_catch_left_brace = true
248 | ij_typescript_space_before_catch_parentheses = true
249 | ij_typescript_space_before_class_lbrace = true
250 | ij_typescript_space_before_class_left_brace = true
251 | ij_typescript_space_before_colon = true
252 | ij_typescript_space_before_comma = false
253 | ij_typescript_space_before_do_left_brace = true
254 | ij_typescript_space_before_else_keyword = true
255 | ij_typescript_space_before_else_left_brace = true
256 | ij_typescript_space_before_finally_keyword = true
257 | ij_typescript_space_before_finally_left_brace = true
258 | ij_typescript_space_before_for_left_brace = true
259 | ij_typescript_space_before_for_parentheses = true
260 | ij_typescript_space_before_for_semicolon = false
261 | ij_typescript_space_before_function_left_parenth = true
262 | ij_typescript_space_before_generator_mult = false
263 | ij_typescript_space_before_if_left_brace = true
264 | ij_typescript_space_before_if_parentheses = true
265 | ij_typescript_space_before_method_call_parentheses = false
266 | ij_typescript_space_before_method_left_brace = true
267 | ij_typescript_space_before_method_parentheses = false
268 | ij_typescript_space_before_property_colon = false
269 | ij_typescript_space_before_quest = true
270 | ij_typescript_space_before_switch_left_brace = true
271 | ij_typescript_space_before_switch_parentheses = true
272 | ij_typescript_space_before_try_left_brace = true
273 | ij_typescript_space_before_type_colon = false
274 | ij_typescript_space_before_unary_not = false
275 | ij_typescript_space_before_while_keyword = true
276 | ij_typescript_space_before_while_left_brace = true
277 | ij_typescript_space_before_while_parentheses = true
278 | ij_typescript_spaces_around_additive_operators = true
279 | ij_typescript_spaces_around_arrow_function_operator = true
280 | ij_typescript_spaces_around_assignment_operators = true
281 | ij_typescript_spaces_around_bitwise_operators = true
282 | ij_typescript_spaces_around_equality_operators = true
283 | ij_typescript_spaces_around_logical_operators = true
284 | ij_typescript_spaces_around_multiplicative_operators = true
285 | ij_typescript_spaces_around_relational_operators = true
286 | ij_typescript_spaces_around_shift_operators = true
287 | ij_typescript_spaces_around_unary_operator = false
288 | ij_typescript_spaces_within_array_initializer_brackets = false
289 | ij_typescript_spaces_within_brackets = false
290 | ij_typescript_spaces_within_catch_parentheses = false
291 | ij_typescript_spaces_within_for_parentheses = false
292 | ij_typescript_spaces_within_if_parentheses = false
293 | ij_typescript_spaces_within_imports = false
294 | ij_typescript_spaces_within_interpolation_expressions = false
295 | ij_typescript_spaces_within_method_call_parentheses = false
296 | ij_typescript_spaces_within_method_parentheses = false
297 | ij_typescript_spaces_within_object_literal_braces = false
298 | ij_typescript_spaces_within_object_type_braces = true
299 | ij_typescript_spaces_within_parentheses = false
300 | ij_typescript_spaces_within_switch_parentheses = false
301 | ij_typescript_spaces_within_type_assertion = false
302 | ij_typescript_spaces_within_union_types = true
303 | ij_typescript_spaces_within_while_parentheses = false
304 | ij_typescript_special_else_if_treatment = true
305 | ij_typescript_ternary_operation_signs_on_next_line = false
306 | ij_typescript_ternary_operation_wrap = off
307 | ij_typescript_union_types_wrap = on_every_item
308 | ij_typescript_use_chained_calls_group_indents = false
309 | ij_typescript_use_double_quotes = true
310 | ij_typescript_use_explicit_js_extension = global
311 | ij_typescript_use_path_mapping = always
312 | ij_typescript_use_public_modifier = false
313 | ij_typescript_use_semicolon_after_statement = true
314 | ij_typescript_var_declaration_wrap = normal
315 | ij_typescript_while_brace_force = never
316 | ij_typescript_while_on_new_line = false
317 | ij_typescript_wrap_comments = false
318 |
319 | [{*.bash,*.sh,*.zsh,release}]
320 | indent_size = 2
321 | tab_width = 2
322 | ij_shell_binary_ops_start_line = false
323 | ij_shell_keep_column_alignment_padding = false
324 | ij_shell_minify_program = false
325 | ij_shell_redirect_followed_by_space = false
326 | ij_shell_switch_cases_indented = false
327 |
328 | [{*.cjs,*.js,ProductSearchAutoComplete,RegisterSessionList}]
329 | indent_size = 2
330 | tab_width = 2
331 | ij_continuation_indent_size = 2
332 | ij_javascript_align_imports = false
333 | ij_javascript_align_multiline_array_initializer_expression = false
334 | ij_javascript_align_multiline_binary_operation = false
335 | ij_javascript_align_multiline_chained_methods = false
336 | ij_javascript_align_multiline_extends_list = false
337 | ij_javascript_align_multiline_for = true
338 | ij_javascript_align_multiline_parameters = false
339 | ij_javascript_align_multiline_parameters_in_calls = false
340 | ij_javascript_align_multiline_ternary_operation = false
341 | ij_javascript_align_object_properties = 0
342 | ij_javascript_align_union_types = false
343 | ij_javascript_align_var_statements = 0
344 | ij_javascript_array_initializer_new_line_after_left_brace = false
345 | ij_javascript_array_initializer_right_brace_on_new_line = false
346 | ij_javascript_array_initializer_wrap = off
347 | ij_javascript_assignment_wrap = off
348 | ij_javascript_binary_operation_sign_on_next_line = false
349 | ij_javascript_binary_operation_wrap = off
350 | ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
351 | ij_javascript_blank_lines_after_imports = 1
352 | ij_javascript_blank_lines_around_class = 1
353 | ij_javascript_blank_lines_around_field = 0
354 | ij_javascript_blank_lines_around_function = 1
355 | ij_javascript_blank_lines_around_method = 1
356 | ij_javascript_block_brace_style = end_of_line
357 | ij_javascript_call_parameters_new_line_after_left_paren = false
358 | ij_javascript_call_parameters_right_paren_on_new_line = false
359 | ij_javascript_call_parameters_wrap = off
360 | ij_javascript_catch_on_new_line = false
361 | ij_javascript_chained_call_dot_on_new_line = true
362 | ij_javascript_class_brace_style = end_of_line
363 | ij_javascript_comma_on_new_line = false
364 | ij_javascript_do_while_brace_force = never
365 | ij_javascript_else_on_new_line = false
366 | ij_javascript_enforce_trailing_comma = keep
367 | ij_javascript_extends_keyword_wrap = off
368 | ij_javascript_extends_list_wrap = off
369 | ij_javascript_field_prefix = _
370 | ij_javascript_file_name_style = relaxed
371 | ij_javascript_finally_on_new_line = false
372 | ij_javascript_for_brace_force = never
373 | ij_javascript_for_statement_new_line_after_left_paren = false
374 | ij_javascript_for_statement_right_paren_on_new_line = false
375 | ij_javascript_for_statement_wrap = off
376 | ij_javascript_force_quote_style = false
377 | ij_javascript_force_semicolon_style = false
378 | ij_javascript_function_expression_brace_style = end_of_line
379 | ij_javascript_if_brace_force = never
380 | ij_javascript_import_merge_members = global
381 | ij_javascript_import_prefer_absolute_path = global
382 | ij_javascript_import_sort_members = true
383 | ij_javascript_import_sort_module_name = false
384 | ij_javascript_import_use_node_resolution = true
385 | ij_javascript_imports_wrap = on_every_item
386 | ij_javascript_indent_case_from_switch = true
387 | ij_javascript_indent_chained_calls = true
388 | ij_javascript_indent_package_children = 0
389 | ij_javascript_jsx_attribute_value = braces
390 | ij_javascript_keep_blank_lines_in_code = 2
391 | ij_javascript_keep_first_column_comment = true
392 | ij_javascript_keep_indents_on_empty_lines = false
393 | ij_javascript_keep_line_breaks = true
394 | ij_javascript_keep_simple_blocks_in_one_line = false
395 | ij_javascript_keep_simple_methods_in_one_line = false
396 | ij_javascript_line_comment_add_space = true
397 | ij_javascript_line_comment_at_first_column = false
398 | ij_javascript_method_brace_style = end_of_line
399 | ij_javascript_method_call_chain_wrap = off
400 | ij_javascript_method_parameters_new_line_after_left_paren = false
401 | ij_javascript_method_parameters_right_paren_on_new_line = false
402 | ij_javascript_method_parameters_wrap = off
403 | ij_javascript_object_literal_wrap = on_every_item
404 | ij_javascript_parentheses_expression_new_line_after_left_paren = false
405 | ij_javascript_parentheses_expression_right_paren_on_new_line = false
406 | ij_javascript_place_assignment_sign_on_next_line = false
407 | ij_javascript_prefer_as_type_cast = false
408 | ij_javascript_prefer_explicit_types_function_expression_returns = false
409 | ij_javascript_prefer_explicit_types_function_returns = false
410 | ij_javascript_prefer_explicit_types_vars_fields = false
411 | ij_javascript_prefer_parameters_wrap = false
412 | ij_javascript_reformat_c_style_comments = false
413 | ij_javascript_space_after_colon = true
414 | ij_javascript_space_after_comma = true
415 | ij_javascript_space_after_dots_in_rest_parameter = false
416 | ij_javascript_space_after_generator_mult = false
417 | ij_javascript_space_after_property_colon = true
418 | ij_javascript_space_after_quest = true
419 | ij_javascript_space_after_type_colon = true
420 | ij_javascript_space_after_unary_not = false
421 | ij_javascript_space_before_async_arrow_lparen = true
422 | ij_javascript_space_before_catch_keyword = true
423 | ij_javascript_space_before_catch_left_brace = true
424 | ij_javascript_space_before_catch_parentheses = true
425 | ij_javascript_space_before_class_lbrace = true
426 | ij_javascript_space_before_class_left_brace = true
427 | ij_javascript_space_before_colon = true
428 | ij_javascript_space_before_comma = false
429 | ij_javascript_space_before_do_left_brace = true
430 | ij_javascript_space_before_else_keyword = true
431 | ij_javascript_space_before_else_left_brace = true
432 | ij_javascript_space_before_finally_keyword = true
433 | ij_javascript_space_before_finally_left_brace = true
434 | ij_javascript_space_before_for_left_brace = true
435 | ij_javascript_space_before_for_parentheses = true
436 | ij_javascript_space_before_for_semicolon = false
437 | ij_javascript_space_before_function_left_parenth = true
438 | ij_javascript_space_before_generator_mult = false
439 | ij_javascript_space_before_if_left_brace = true
440 | ij_javascript_space_before_if_parentheses = true
441 | ij_javascript_space_before_method_call_parentheses = false
442 | ij_javascript_space_before_method_left_brace = true
443 | ij_javascript_space_before_method_parentheses = false
444 | ij_javascript_space_before_property_colon = false
445 | ij_javascript_space_before_quest = true
446 | ij_javascript_space_before_switch_left_brace = true
447 | ij_javascript_space_before_switch_parentheses = true
448 | ij_javascript_space_before_try_left_brace = true
449 | ij_javascript_space_before_type_colon = false
450 | ij_javascript_space_before_unary_not = false
451 | ij_javascript_space_before_while_keyword = true
452 | ij_javascript_space_before_while_left_brace = true
453 | ij_javascript_space_before_while_parentheses = true
454 | ij_javascript_spaces_around_additive_operators = true
455 | ij_javascript_spaces_around_arrow_function_operator = true
456 | ij_javascript_spaces_around_assignment_operators = true
457 | ij_javascript_spaces_around_bitwise_operators = true
458 | ij_javascript_spaces_around_equality_operators = true
459 | ij_javascript_spaces_around_logical_operators = true
460 | ij_javascript_spaces_around_multiplicative_operators = true
461 | ij_javascript_spaces_around_relational_operators = true
462 | ij_javascript_spaces_around_shift_operators = true
463 | ij_javascript_spaces_around_unary_operator = false
464 | ij_javascript_spaces_within_array_initializer_brackets = false
465 | ij_javascript_spaces_within_brackets = false
466 | ij_javascript_spaces_within_catch_parentheses = false
467 | ij_javascript_spaces_within_for_parentheses = false
468 | ij_javascript_spaces_within_if_parentheses = false
469 | ij_javascript_spaces_within_imports = true
470 | ij_javascript_spaces_within_interpolation_expressions = false
471 | ij_javascript_spaces_within_method_call_parentheses = false
472 | ij_javascript_spaces_within_method_parentheses = false
473 | ij_javascript_spaces_within_object_literal_braces = true
474 | ij_javascript_spaces_within_object_type_braces = true
475 | ij_javascript_spaces_within_parentheses = false
476 | ij_javascript_spaces_within_switch_parentheses = false
477 | ij_javascript_spaces_within_type_assertion = false
478 | ij_javascript_spaces_within_union_types = true
479 | ij_javascript_spaces_within_while_parentheses = false
480 | ij_javascript_special_else_if_treatment = true
481 | ij_javascript_ternary_operation_signs_on_next_line = false
482 | ij_javascript_ternary_operation_wrap = off
483 | ij_javascript_union_types_wrap = on_every_item
484 | ij_javascript_use_chained_calls_group_indents = false
485 | ij_javascript_use_double_quotes = true
486 | ij_javascript_use_explicit_js_extension = global
487 | ij_javascript_use_path_mapping = always
488 | ij_javascript_use_public_modifier = false
489 | ij_javascript_use_semicolon_after_statement = true
490 | ij_javascript_var_declaration_wrap = normal
491 | ij_javascript_while_brace_force = never
492 | ij_javascript_while_on_new_line = false
493 | ij_javascript_wrap_comments = false
494 |
495 | [{*.cjsx,*.coffee}]
496 | indent_size = 2
497 | tab_width = 2
498 | ij_continuation_indent_size = 2
499 | ij_coffeescript_align_function_body = false
500 | ij_coffeescript_align_imports = false
501 | ij_coffeescript_align_multiline_array_initializer_expression = true
502 | ij_coffeescript_align_multiline_parameters = true
503 | ij_coffeescript_align_multiline_parameters_in_calls = false
504 | ij_coffeescript_align_object_properties = 0
505 | ij_coffeescript_align_union_types = false
506 | ij_coffeescript_align_var_statements = 0
507 | ij_coffeescript_array_initializer_new_line_after_left_brace = false
508 | ij_coffeescript_array_initializer_right_brace_on_new_line = false
509 | ij_coffeescript_array_initializer_wrap = normal
510 | ij_coffeescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/**
511 | ij_coffeescript_blank_lines_around_function = 1
512 | ij_coffeescript_call_parameters_new_line_after_left_paren = false
513 | ij_coffeescript_call_parameters_right_paren_on_new_line = false
514 | ij_coffeescript_call_parameters_wrap = normal
515 | ij_coffeescript_chained_call_dot_on_new_line = true
516 | ij_coffeescript_comma_on_new_line = false
517 | ij_coffeescript_enforce_trailing_comma = keep
518 | ij_coffeescript_field_prefix = _
519 | ij_coffeescript_file_name_style = relaxed
520 | ij_coffeescript_force_quote_style = false
521 | ij_coffeescript_force_semicolon_style = false
522 | ij_coffeescript_function_expression_brace_style = end_of_line
523 | ij_coffeescript_import_merge_members = global
524 | ij_coffeescript_import_prefer_absolute_path = global
525 | ij_coffeescript_import_sort_members = true
526 | ij_coffeescript_import_sort_module_name = false
527 | ij_coffeescript_import_use_node_resolution = true
528 | ij_coffeescript_imports_wrap = on_every_item
529 | ij_coffeescript_indent_chained_calls = true
530 | ij_coffeescript_indent_package_children = 0
531 | ij_coffeescript_jsx_attribute_value = braces
532 | ij_coffeescript_keep_blank_lines_in_code = 2
533 | ij_coffeescript_keep_first_column_comment = true
534 | ij_coffeescript_keep_indents_on_empty_lines = false
535 | ij_coffeescript_keep_line_breaks = true
536 | ij_coffeescript_keep_simple_methods_in_one_line = false
537 | ij_coffeescript_method_parameters_new_line_after_left_paren = false
538 | ij_coffeescript_method_parameters_right_paren_on_new_line = false
539 | ij_coffeescript_method_parameters_wrap = off
540 | ij_coffeescript_object_literal_wrap = on_every_item
541 | ij_coffeescript_prefer_as_type_cast = false
542 | ij_coffeescript_prefer_explicit_types_function_expression_returns = false
543 | ij_coffeescript_prefer_explicit_types_function_returns = false
544 | ij_coffeescript_prefer_explicit_types_vars_fields = false
545 | ij_coffeescript_reformat_c_style_comments = false
546 | ij_coffeescript_space_after_comma = true
547 | ij_coffeescript_space_after_dots_in_rest_parameter = false
548 | ij_coffeescript_space_after_generator_mult = true
549 | ij_coffeescript_space_after_property_colon = true
550 | ij_coffeescript_space_after_type_colon = true
551 | ij_coffeescript_space_after_unary_not = false
552 | ij_coffeescript_space_before_async_arrow_lparen = true
553 | ij_coffeescript_space_before_class_lbrace = true
554 | ij_coffeescript_space_before_comma = false
555 | ij_coffeescript_space_before_function_left_parenth = true
556 | ij_coffeescript_space_before_generator_mult = false
557 | ij_coffeescript_space_before_property_colon = false
558 | ij_coffeescript_space_before_type_colon = false
559 | ij_coffeescript_space_before_unary_not = false
560 | ij_coffeescript_spaces_around_additive_operators = true
561 | ij_coffeescript_spaces_around_arrow_function_operator = true
562 | ij_coffeescript_spaces_around_assignment_operators = true
563 | ij_coffeescript_spaces_around_bitwise_operators = true
564 | ij_coffeescript_spaces_around_equality_operators = true
565 | ij_coffeescript_spaces_around_logical_operators = true
566 | ij_coffeescript_spaces_around_multiplicative_operators = true
567 | ij_coffeescript_spaces_around_relational_operators = true
568 | ij_coffeescript_spaces_around_shift_operators = true
569 | ij_coffeescript_spaces_around_unary_operator = false
570 | ij_coffeescript_spaces_within_array_initializer_braces = false
571 | ij_coffeescript_spaces_within_array_initializer_brackets = false
572 | ij_coffeescript_spaces_within_imports = false
573 | ij_coffeescript_spaces_within_index_brackets = false
574 | ij_coffeescript_spaces_within_interpolation_expressions = false
575 | ij_coffeescript_spaces_within_method_call_parentheses = false
576 | ij_coffeescript_spaces_within_method_parentheses = false
577 | ij_coffeescript_spaces_within_object_braces = false
578 | ij_coffeescript_spaces_within_object_literal_braces = false
579 | ij_coffeescript_spaces_within_object_type_braces = true
580 | ij_coffeescript_spaces_within_range_brackets = false
581 | ij_coffeescript_spaces_within_type_assertion = false
582 | ij_coffeescript_spaces_within_union_types = true
583 | ij_coffeescript_union_types_wrap = on_every_item
584 | ij_coffeescript_use_chained_calls_group_indents = false
585 | ij_coffeescript_use_double_quotes = true
586 | ij_coffeescript_use_explicit_js_extension = global
587 | ij_coffeescript_use_path_mapping = always
588 | ij_coffeescript_use_public_modifier = false
589 | ij_coffeescript_use_semicolon_after_statement = false
590 | ij_coffeescript_var_declaration_wrap = normal
591 |
592 | [{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml}]
593 | ij_continuation_indent_size = 4
594 | ij_php_align_assignments = true
595 | ij_php_align_class_constants = true
596 | ij_php_align_group_field_declarations = true
597 | ij_php_align_inline_comments = false
598 | ij_php_align_key_value_pairs = true
599 | ij_php_align_multiline_array_initializer_expression = true
600 | ij_php_align_multiline_binary_operation = false
601 | ij_php_align_multiline_chained_methods = false
602 | ij_php_align_multiline_extends_list = true
603 | ij_php_align_multiline_for = true
604 | ij_php_align_multiline_parameters = true
605 | ij_php_align_multiline_parameters_in_calls = false
606 | ij_php_align_multiline_ternary_operation = false
607 | ij_php_align_phpdoc_comments = true
608 | ij_php_align_phpdoc_param_names = true
609 | ij_php_anonymous_brace_style = end_of_line
610 | ij_php_api_weight = 28
611 | ij_php_array_initializer_new_line_after_left_brace = false
612 | ij_php_array_initializer_right_brace_on_new_line = false
613 | ij_php_array_initializer_wrap = off
614 | ij_php_assignment_wrap = off
615 | ij_php_attributes_wrap = off
616 | ij_php_author_weight = 28
617 | ij_php_binary_operation_sign_on_next_line = false
618 | ij_php_binary_operation_wrap = off
619 | ij_php_blank_lines_after_class_header = 0
620 | ij_php_blank_lines_after_function = 1
621 | ij_php_blank_lines_after_imports = 2
622 | ij_php_blank_lines_after_opening_tag = 0
623 | ij_php_blank_lines_after_package = 0
624 | ij_php_blank_lines_around_class = 1
625 | ij_php_blank_lines_around_constants = 0
626 | ij_php_blank_lines_around_field = 0
627 | ij_php_blank_lines_around_method = 1
628 | ij_php_blank_lines_before_class_end = 0
629 | ij_php_blank_lines_before_imports = 1
630 | ij_php_blank_lines_before_method_body = 0
631 | ij_php_blank_lines_before_package = 1
632 | ij_php_blank_lines_before_return_statement = 1
633 | ij_php_blank_lines_between_imports = 0
634 | ij_php_block_brace_style = end_of_line
635 | ij_php_call_parameters_new_line_after_left_paren = false
636 | ij_php_call_parameters_right_paren_on_new_line = false
637 | ij_php_call_parameters_wrap = off
638 | ij_php_catch_on_new_line = false
639 | ij_php_category_weight = 28
640 | ij_php_class_brace_style = next_line
641 | ij_php_comma_after_last_array_element = true
642 | ij_php_concat_spaces = true
643 | ij_php_copyright_weight = 28
644 | ij_php_deprecated_weight = 28
645 | ij_php_do_while_brace_force = never
646 | ij_php_else_if_style = combine
647 | ij_php_else_on_new_line = false
648 | ij_php_example_weight = 28
649 | ij_php_extends_keyword_wrap = off
650 | ij_php_extends_list_wrap = off
651 | ij_php_fields_default_visibility = private
652 | ij_php_filesource_weight = 28
653 | ij_php_finally_on_new_line = false
654 | ij_php_for_brace_force = never
655 | ij_php_for_statement_new_line_after_left_paren = false
656 | ij_php_for_statement_right_paren_on_new_line = false
657 | ij_php_for_statement_wrap = off
658 | ij_php_force_short_declaration_array_style = true
659 | ij_php_getters_setters_naming_style = camel_case
660 | ij_php_getters_setters_order_style = getters_first
661 | ij_php_global_weight = 28
662 | ij_php_group_use_wrap = on_every_item
663 | ij_php_if_brace_force = never
664 | ij_php_if_lparen_on_next_line = false
665 | ij_php_if_rparen_on_next_line = false
666 | ij_php_ignore_weight = 28
667 | ij_php_import_sorting = alphabetic
668 | ij_php_indent_break_from_case = true
669 | ij_php_indent_case_from_switch = true
670 | ij_php_indent_code_in_php_tags = false
671 | ij_php_internal_weight = 28
672 | ij_php_keep_blank_lines_after_lbrace = 2
673 | ij_php_keep_blank_lines_before_right_brace = 2
674 | ij_php_keep_blank_lines_in_code = 2
675 | ij_php_keep_blank_lines_in_declarations = 2
676 | ij_php_keep_control_statement_in_one_line = true
677 | ij_php_keep_first_column_comment = true
678 | ij_php_keep_indents_on_empty_lines = false
679 | ij_php_keep_line_breaks = true
680 | ij_php_keep_rparen_and_lbrace_on_one_line = true
681 | ij_php_keep_simple_classes_in_one_line = false
682 | ij_php_keep_simple_methods_in_one_line = false
683 | ij_php_lambda_brace_style = end_of_line
684 | ij_php_license_weight = 28
685 | ij_php_line_comment_add_space = false
686 | ij_php_line_comment_at_first_column = true
687 | ij_php_link_weight = 28
688 | ij_php_lower_case_boolean_const = true
689 | ij_php_lower_case_keywords = true
690 | ij_php_lower_case_null_const = true
691 | ij_php_method_brace_style = next_line
692 | ij_php_method_call_chain_wrap = off
693 | ij_php_method_parameters_new_line_after_left_paren = false
694 | ij_php_method_parameters_right_paren_on_new_line = false
695 | ij_php_method_parameters_wrap = off
696 | ij_php_method_weight = 28
697 | ij_php_modifier_list_wrap = false
698 | ij_php_multiline_chained_calls_semicolon_on_new_line = false
699 | ij_php_namespace_brace_style = 1
700 | ij_php_new_line_after_php_opening_tag = false
701 | ij_php_null_type_position = in_the_end
702 | ij_php_package_weight = 28
703 | ij_php_param_weight = 0
704 | ij_php_parameters_attributes_wrap = off
705 | ij_php_parentheses_expression_new_line_after_left_paren = false
706 | ij_php_parentheses_expression_right_paren_on_new_line = false
707 | ij_php_phpdoc_blank_line_before_tags = true
708 | ij_php_phpdoc_blank_lines_around_parameters = true
709 | ij_php_phpdoc_keep_blank_lines = true
710 | ij_php_phpdoc_param_spaces_between_name_and_description = 1
711 | ij_php_phpdoc_param_spaces_between_tag_and_type = 1
712 | ij_php_phpdoc_param_spaces_between_type_and_name = 1
713 | ij_php_phpdoc_use_fqcn = false
714 | ij_php_phpdoc_wrap_long_lines = false
715 | ij_php_place_assignment_sign_on_next_line = false
716 | ij_php_place_parens_for_constructor = 0
717 | ij_php_property_read_weight = 28
718 | ij_php_property_weight = 28
719 | ij_php_property_write_weight = 28
720 | ij_php_return_type_on_new_line = false
721 | ij_php_return_weight = 1
722 | ij_php_see_weight = 28
723 | ij_php_since_weight = 28
724 | ij_php_sort_phpdoc_elements = true
725 | ij_php_space_after_colon = true
726 | ij_php_space_after_colon_in_named_argument = true
727 | ij_php_space_after_colon_in_return_type = true
728 | ij_php_space_after_comma = true
729 | ij_php_space_after_for_semicolon = true
730 | ij_php_space_after_quest = true
731 | ij_php_space_after_type_cast = false
732 | ij_php_space_after_unary_not = true
733 | ij_php_space_before_array_initializer_left_brace = false
734 | ij_php_space_before_catch_keyword = true
735 | ij_php_space_before_catch_left_brace = true
736 | ij_php_space_before_catch_parentheses = true
737 | ij_php_space_before_class_left_brace = true
738 | ij_php_space_before_closure_left_parenthesis = true
739 | ij_php_space_before_colon = true
740 | ij_php_space_before_colon_in_named_argument = false
741 | ij_php_space_before_colon_in_return_type = false
742 | ij_php_space_before_comma = false
743 | ij_php_space_before_do_left_brace = true
744 | ij_php_space_before_else_keyword = true
745 | ij_php_space_before_else_left_brace = true
746 | ij_php_space_before_finally_keyword = true
747 | ij_php_space_before_finally_left_brace = true
748 | ij_php_space_before_for_left_brace = true
749 | ij_php_space_before_for_parentheses = true
750 | ij_php_space_before_for_semicolon = false
751 | ij_php_space_before_if_left_brace = true
752 | ij_php_space_before_if_parentheses = true
753 | ij_php_space_before_method_call_parentheses = false
754 | ij_php_space_before_method_left_brace = true
755 | ij_php_space_before_method_parentheses = false
756 | ij_php_space_before_quest = true
757 | ij_php_space_before_short_closure_left_parenthesis = false
758 | ij_php_space_before_switch_left_brace = true
759 | ij_php_space_before_switch_parentheses = true
760 | ij_php_space_before_try_left_brace = true
761 | ij_php_space_before_unary_not = false
762 | ij_php_space_before_while_keyword = true
763 | ij_php_space_before_while_left_brace = true
764 | ij_php_space_before_while_parentheses = true
765 | ij_php_space_between_ternary_quest_and_colon = false
766 | ij_php_spaces_around_additive_operators = true
767 | ij_php_spaces_around_arrow = false
768 | ij_php_spaces_around_assignment_in_declare = false
769 | ij_php_spaces_around_assignment_operators = true
770 | ij_php_spaces_around_bitwise_operators = true
771 | ij_php_spaces_around_equality_operators = true
772 | ij_php_spaces_around_logical_operators = true
773 | ij_php_spaces_around_multiplicative_operators = true
774 | ij_php_spaces_around_null_coalesce_operator = true
775 | ij_php_spaces_around_relational_operators = true
776 | ij_php_spaces_around_shift_operators = true
777 | ij_php_spaces_around_unary_operator = false
778 | ij_php_spaces_around_var_within_brackets = false
779 | ij_php_spaces_within_array_initializer_braces = false
780 | ij_php_spaces_within_brackets = false
781 | ij_php_spaces_within_catch_parentheses = false
782 | ij_php_spaces_within_for_parentheses = false
783 | ij_php_spaces_within_if_parentheses = false
784 | ij_php_spaces_within_method_call_parentheses = false
785 | ij_php_spaces_within_method_parentheses = false
786 | ij_php_spaces_within_parentheses = false
787 | ij_php_spaces_within_short_echo_tags = true
788 | ij_php_spaces_within_switch_parentheses = false
789 | ij_php_spaces_within_while_parentheses = false
790 | ij_php_special_else_if_treatment = false
791 | ij_php_subpackage_weight = 28
792 | ij_php_ternary_operation_signs_on_next_line = false
793 | ij_php_ternary_operation_wrap = off
794 | ij_php_throws_weight = 2
795 | ij_php_todo_weight = 28
796 | ij_php_unknown_tag_weight = 28
797 | ij_php_upper_case_boolean_const = false
798 | ij_php_upper_case_null_const = false
799 | ij_php_uses_weight = 28
800 | ij_php_var_weight = 28
801 | ij_php_variable_naming_style = mixed
802 | ij_php_version_weight = 28
803 | ij_php_while_brace_force = never
804 | ij_php_while_on_new_line = false
805 |
806 | [{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,composer.lock,jest.config}]
807 | indent_size = 2
808 | ij_json_keep_blank_lines_in_code = 0
809 | ij_json_keep_indents_on_empty_lines = false
810 | ij_json_keep_line_breaks = true
811 | ij_json_space_after_colon = true
812 | ij_json_space_after_comma = true
813 | ij_json_space_before_colon = true
814 | ij_json_space_before_comma = false
815 | ij_json_spaces_within_braces = false
816 | ij_json_spaces_within_brackets = false
817 | ij_json_wrap_long_lines = false
818 |
819 | [{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml,index.ejs}]
820 | ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3
821 | ij_html_align_attributes = true
822 | ij_html_align_text = false
823 | ij_html_attribute_wrap = normal
824 | ij_html_block_comment_at_first_column = true
825 | ij_html_do_not_align_children_of_min_lines = 0
826 | ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p
827 | ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot
828 | ij_html_enforce_quotes = false
829 | ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var
830 | ij_html_keep_blank_lines = 2
831 | ij_html_keep_indents_on_empty_lines = false
832 | ij_html_keep_line_breaks = true
833 | ij_html_keep_line_breaks_in_text = true
834 | ij_html_keep_whitespaces = false
835 | ij_html_keep_whitespaces_inside = span,pre,textarea
836 | ij_html_line_comment_at_first_column = true
837 | ij_html_new_line_after_last_attribute = never
838 | ij_html_new_line_before_first_attribute = never
839 | ij_html_quote_style = double
840 | ij_html_remove_new_line_before_tags = br
841 | ij_html_space_after_tag_name = false
842 | ij_html_space_around_equality_in_attribute = false
843 | ij_html_space_inside_empty_tag = true
844 | ij_html_text_wrap = normal
845 | ij_html_uniform_ident = false
846 |
847 | [{*.markdown,*.md}]
848 | ij_markdown_force_one_space_after_blockquote_symbol = true
849 | ij_markdown_force_one_space_after_header_symbol = true
850 | ij_markdown_force_one_space_after_list_bullet = true
851 | ij_markdown_force_one_space_between_words = true
852 | ij_markdown_keep_indents_on_empty_lines = false
853 | ij_markdown_max_lines_around_block_elements = 1
854 | ij_markdown_max_lines_around_header = 1
855 | ij_markdown_max_lines_between_paragraphs = 1
856 | ij_markdown_min_lines_around_block_elements = 1
857 | ij_markdown_min_lines_around_header = 1
858 | ij_markdown_min_lines_between_paragraphs = 1
859 |
860 | [{*.yaml,*.yml}]
861 | indent_size = 2
862 | ij_yaml_align_values_properties = do_not_align
863 | ij_yaml_autoinsert_sequence_marker = true
864 | ij_yaml_block_mapping_on_new_line = false
865 | ij_yaml_indent_sequence_value = true
866 | ij_yaml_keep_indents_on_empty_lines = false
867 | ij_yaml_keep_line_breaks = true
868 | ij_yaml_sequence_on_new_line = false
869 | ij_yaml_space_before_colon = false
870 | ij_yaml_spaces_within_braces = true
871 | ij_yaml_spaces_within_brackets = true
872 |
--------------------------------------------------------------------------------