{"action":"created","comment":{"url":"https://api.github.com/repos/laravel/cashier/pulls/comments/125379151","pull_request_review_id":47761638,"id":125379151,"diff_hunk":"@@ -0,0 +1,286 @@\n+<?php\n+\n+namespace Laravel\\Cashier\\Gateway\\Braintree;\n+\n+use Braintree\\Transaction as BraintreeTransaction;\n+use Carbon\\Carbon;\n+use Dompdf\\Dompdf;\n+use Illuminate\\Support\\Facades\\View;\n+use Symfony\\Component\\HttpFoundation\\Response;\n+\n+class Invoice extends \\Laravel\\Cashier\\Gateway\\Invoice","path":"src/Gateway/Braintree/Invoice.php","position":11,"original_position":11,"commit_id":"3d4e2d956f6d3e66ec9ac9275e28d6d064f641f1","original_commit_id":"3d4e2d956f6d3e66ec9ac9275e28d6d064f641f1","user":{"login":"inxilpro","id":21592,"avatar_url":"https://avatars2.githubusercontent.com/u/21592?v=3","gravatar_id":"","url":"https://api.github.com/users/inxilpro","html_url":"https://github.com/inxilpro","followers_url":"https://api.github.com/users/inxilpro/followers","following_url":"https://api.github.com/users/inxilpro/following{/other_user}","gists_url":"https://api.github.com/users/inxilpro/gists{/gist_id}","starred_url":"https://api.github.com/users/inxilpro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/inxilpro/subscriptions","organizations_url":"https://api.github.com/users/inxilpro/orgs","repos_url":"https://api.github.com/users/inxilpro/repos","events_url":"https://api.github.com/users/inxilpro/events{/privacy}","received_events_url":"https://api.github.com/users/inxilpro/received_events","type":"User","site_admin":false},"body":"`Invoice` instances need to be thought out a bit more.","created_at":"2017-07-04T02:32:06Z","updated_at":"2017-07-04T02:35:16Z","html_url":"https://github.com/laravel/cashier/pull/423#discussion_r125379151","pull_request_url":"https://api.github.com/repos/laravel/cashier/pulls/423","_links":{"self":{"href":"https://api.github.com/repos/laravel/cashier/pulls/comments/125379151"},"html":{"href":"https://github.com/laravel/cashier/pull/423#discussion_r125379151"},"pull_request":{"href":"https://api.github.com/repos/laravel/cashier/pulls/423"}}},"pull_request":{"url":"https://api.github.com/repos/laravel/cashier/pulls/423","id":128715184,"html_url":"https://github.com/laravel/cashier/pull/423","diff_url":"https://github.com/laravel/cashier/pull/423.diff","patch_url":"https://github.com/laravel/cashier/pull/423.patch","issue_url":"https://api.github.com/repos/laravel/cashier/issues/423","number":423,"state":"open","locked":false,"title":"[Proposal] Merge w/ cashier-braintree & add gateway API","user":{"login":"inxilpro","id":21592,"avatar_url":"https://avatars2.githubusercontent.com/u/21592?v=3","gravatar_id":"","url":"https://api.github.com/users/inxilpro","html_url":"https://github.com/inxilpro","followers_url":"https://api.github.com/users/inxilpro/followers","following_url":"https://api.github.com/users/inxilpro/following{/other_user}","gists_url":"https://api.github.com/users/inxilpro/gists{/gist_id}","starred_url":"https://api.github.com/users/inxilpro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/inxilpro/subscriptions","organizations_url":"https://api.github.com/users/inxilpro/orgs","repos_url":"https://api.github.com/users/inxilpro/repos","events_url":"https://api.github.com/users/inxilpro/events{/privacy}","received_events_url":"https://api.github.com/users/inxilpro/received_events","type":"User","site_admin":false},"body":"**This PR is not meant to be merged. It's here to facilitate a discussion (using a PR allows for better visibility into proposed code changes).**\r\n\r\nRight now there's not a huge difference between `laravel/cashier` and `laravel/cashier-braintree`. I took a day to see how hard it would be to merge the two. This PR isn't complete or tested, but I've made enough progress that I thought it would be worth discussing.\r\n\r\nThe basic idea is to refactor `stripe_id`/etc to `payment_gateway = \"stripe\"` and `payment_gateway_id`. Then, I've broken the Stripe- and Braintree-specific code into separate manager classes, and combined the shared code.\r\n\r\nA backwards-compatibility layer is available right now, although I don't know if it's necessary (or if it should be released as a separate package).\r\n\r\nBraintree- and Stripe-specific calls can be made via a `braintree()` or `stripe()` (or any other gateway) magic method. An `ifGateway()` method is also provided for packages that want to support multiple gateways, or if you're transitioning a code base from one to the other and want to support both for a period of time.\r\n\r\nFor example:\r\n\r\n```php\r\n$user->charge(1000); // Uses $user->payment_gateway or default gateway if none set\r\n\r\n$user->stripe()->deletedCards(); // deletedCards currently Stripe-only\r\n\r\n$user->ifGateway('stripe', function($stripe) {\r\n  $stripe->deletedCards();\r\n})->ifGateway('braintree', function($braintree) {\r\n  $customer = $braintree->asGatewayCustomer();\r\n  // Custom Braintree code to delete cards\r\n});\r\n```\r\n\r\n## Basic overview\r\n\r\nEach gateway implements the following:\r\n\r\n  - `Gateway` — the base Gateway\r\n  - `SubscriptionBuilder` creates new `Subscription` models\r\n  - `SubscriptionManager` for things like `cancel()` and `resume()`\r\n  - `BillingManager` for things like `charge()` and `refund()`\r\n\r\nThe `Billable` trait defers to the `BillingManager` for the model's configured gateway (or the default if none set) where appropriate. So where before `cashier` and `cashier-braintree` each implemented `invoiceFor()` differently in their `Billable` trait, now `Billable::invoiceFor()` calls `Billable::getBillingManager()->invoiceFor()`.\r\n\r\nThere's more to it, but that's the basic gist.\r\n\r\n## A few things up for discussion:\r\n\r\n  - Are you open to me continuing along this path? I think it can be done in a fairly non-breaking way, and would help open the door for other gateways/etc.\r\n  - Does it make sense to break into 3 or 4 packages (cashier/cashier-stripe/cashier-braintree/cashier-compat)\r\n  - My gut says that Cashier should exclusively use zero-decimal values for amounts (like Stripe) to allow for a more seamless transition between gateways. I've started to implement this is `Gateway::convertZeroDecimalValue` which lets each gateway convert a value into the format that it needs (so Braintree can convert `100` to `1.0`). This would be the biggest breaking change, but I think it makes a lot of sense.\r\n\r\nI realize now that I branched off of `7.0` rather than `master`. Doh. Obviously if I move forward I will refactor using the latest changes in `master`.\r\n\r\nCheers!\r\n\r\n\r\n","created_at":"2017-07-04T02:24:28Z","updated_at":"2017-07-04T02:35:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":"8ae4ef99f12cb625018e20674ccc567a73995279","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/laravel/cashier/pulls/423/commits","review_comments_url":"https://api.github.com/repos/laravel/cashier/pulls/423/comments","review_comment_url":"https://api.github.com/repos/laravel/cashier/pulls/comments{/number}","comments_url":"https://api.github.com/repos/laravel/cashier/issues/423/comments","statuses_url":"https://api.github.com/repos/laravel/cashier/statuses/3d4e2d956f6d3e66ec9ac9275e28d6d064f641f1","head":{"label":"inxilpro:plugin-architecture","ref":"plugin-architecture","sha":"3d4e2d956f6d3e66ec9ac9275e28d6d064f641f1","user":{"login":"inxilpro","id":21592,"avatar_url":"https://avatars2.githubusercontent.com/u/21592?v=3","gravatar_id":"","url":"https://api.github.com/users/inxilpro","html_url":"https://github.com/inxilpro","followers_url":"https://api.github.com/users/inxilpro/followers","following_url":"https://api.github.com/users/inxilpro/following{/other_user}","gists_url":"https://api.github.com/users/inxilpro/gists{/gist_id}","starred_url":"https://api.github.com/users/inxilpro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/inxilpro/subscriptions","organizations_url":"https://api.github.com/users/inxilpro/orgs","repos_url":"https://api.github.com/users/inxilpro/repos","events_url":"https://api.github.com/users/inxilpro/events{/privacy}","received_events_url":"https://api.github.com/users/inxilpro/received_events","type":"User","site_admin":false},"repo":{"id":96118713,"name":"laravel-cashier-fork","full_name":"inxilpro/laravel-cashier-fork","owner":{"login":"inxilpro","id":21592,"avatar_url":"https://avatars2.githubusercontent.com/u/21592?v=3","gravatar_id":"","url":"https://api.github.com/users/inxilpro","html_url":"https://github.com/inxilpro","followers_url":"https://api.github.com/users/inxilpro/followers","following_url":"https://api.github.com/users/inxilpro/following{/other_user}","gists_url":"https://api.github.com/users/inxilpro/gists{/gist_id}","starred_url":"https://api.github.com/users/inxilpro/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/inxilpro/subscriptions","organizations_url":"https://api.github.com/users/inxilpro/orgs","repos_url":"https://api.github.com/users/inxilpro/repos","events_url":"https://api.github.com/users/inxilpro/events{/privacy}","received_events_url":"https://api.github.com/users/inxilpro/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/inxilpro/laravel-cashier-fork","description":null,"fork":true,"url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork","forks_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/forks","keys_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/keys{/key_id}","collaborators_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/teams","hooks_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/hooks","issue_events_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/issues/events{/number}","events_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/events","assignees_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/assignees{/user}","branches_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/branches{/branch}","tags_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/tags","blobs_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/git/refs{/sha}","trees_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/git/trees{/sha}","statuses_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/statuses/{sha}","languages_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/languages","stargazers_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/stargazers","contributors_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/contributors","subscribers_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/subscribers","subscription_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/subscription","commits_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/commits{/sha}","git_commits_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/git/commits{/sha}","comments_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/comments{/number}","issue_comment_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/issues/comments{/number}","contents_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/contents/{+path}","compare_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/compare/{base}...{head}","merges_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/merges","archive_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/downloads","issues_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/issues{/number}","pulls_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/pulls{/number}","milestones_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/milestones{/number}","notifications_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/labels{/name}","releases_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/releases{/id}","deployments_url":"https://api.github.com/repos/inxilpro/laravel-cashier-fork/deployments","created_at":"2017-07-03T14:19:49Z","updated_at":"2017-07-03T14:20:09Z","pushed_at":"2017-07-04T01:56:54Z","git_url":"git://github.com/inxilpro/laravel-cashier-fork.git","ssh_url":"git@github.com:inxilpro/laravel-cashier-fork.git","clone_url":"https://github.com/inxilpro/laravel-cashier-fork.git","svn_url":"https://github.com/inxilpro/laravel-cashier-fork","homepage":"","size":45939,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"7.0"}},"base":{"label":"laravel:7.0","ref":"7.0","sha":"a7f3277a7cc47718d35e59a3427a707f32c4c7ff","user":{"login":"laravel","id":958072,"avatar_url":"https://avatars0.githubusercontent.com/u/958072?v=3","gravatar_id":"","url":"https://api.github.com/users/laravel","html_url":"https://github.com/laravel","followers_url":"https://api.github.com/users/laravel/followers","following_url":"https://api.github.com/users/laravel/following{/other_user}","gists_url":"https://api.github.com/users/laravel/gists{/gist_id}","starred_url":"https://api.github.com/users/laravel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/laravel/subscriptions","organizations_url":"https://api.github.com/users/laravel/orgs","repos_url":"https://api.github.com/users/laravel/repos","events_url":"https://api.github.com/users/laravel/events{/privacy}","received_events_url":"https://api.github.com/users/laravel/received_events","type":"Organization","site_admin":false},"repo":{"id":17388759,"name":"cashier","full_name":"laravel/cashier","owner":{"login":"laravel","id":958072,"avatar_url":"https://avatars0.githubusercontent.com/u/958072?v=3","gravatar_id":"","url":"https://api.github.com/users/laravel","html_url":"https://github.com/laravel","followers_url":"https://api.github.com/users/laravel/followers","following_url":"https://api.github.com/users/laravel/following{/other_user}","gists_url":"https://api.github.com/users/laravel/gists{/gist_id}","starred_url":"https://api.github.com/users/laravel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/laravel/subscriptions","organizations_url":"https://api.github.com/users/laravel/orgs","repos_url":"https://api.github.com/users/laravel/repos","events_url":"https://api.github.com/users/laravel/events{/privacy}","received_events_url":"https://api.github.com/users/laravel/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/laravel/cashier","description":null,"fork":false,"url":"https://api.github.com/repos/laravel/cashier","forks_url":"https://api.github.com/repos/laravel/cashier/forks","keys_url":"https://api.github.com/repos/laravel/cashier/keys{/key_id}","collaborators_url":"https://api.github.com/repos/laravel/cashier/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/laravel/cashier/teams","hooks_url":"https://api.github.com/repos/laravel/cashier/hooks","issue_events_url":"https://api.github.com/repos/laravel/cashier/issues/events{/number}","events_url":"https://api.github.com/repos/laravel/cashier/events","assignees_url":"https://api.github.com/repos/laravel/cashier/assignees{/user}","branches_url":"https://api.github.com/repos/laravel/cashier/branches{/branch}","tags_url":"https://api.github.com/repos/laravel/cashier/tags","blobs_url":"https://api.github.com/repos/laravel/cashier/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/laravel/cashier/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/laravel/cashier/git/refs{/sha}","trees_url":"https://api.github.com/repos/laravel/cashier/git/trees{/sha}","statuses_url":"https://api.github.com/repos/laravel/cashier/statuses/{sha}","languages_url":"https://api.github.com/repos/laravel/cashier/languages","stargazers_url":"https://api.github.com/repos/laravel/cashier/stargazers","contributors_url":"https://api.github.com/repos/laravel/cashier/contributors","subscribers_url":"https://api.github.com/repos/laravel/cashier/subscribers","subscription_url":"https://api.github.com/repos/laravel/cashier/subscription","commits_url":"https://api.github.com/repos/laravel/cashier/commits{/sha}","git_commits_url":"https://api.github.com/repos/laravel/cashier/git/commits{/sha}","comments_url":"https://api.github.com/repos/laravel/cashier/comments{/number}","issue_comment_url":"https://api.github.com/repos/laravel/cashier/issues/comments{/number}","contents_url":"https://api.github.com/repos/laravel/cashier/contents/{+path}","compare_url":"https://api.github.com/repos/laravel/cashier/compare/{base}...{head}","merges_url":"https://api.github.com/repos/laravel/cashier/merges","archive_url":"https://api.github.com/repos/laravel/cashier/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/laravel/cashier/downloads","issues_url":"https://api.github.com/repos/laravel/cashier/issues{/number}","pulls_url":"https://api.github.com/repos/laravel/cashier/pulls{/number}","milestones_url":"https://api.github.com/repos/laravel/cashier/milestones{/number}","notifications_url":"https://api.github.com/repos/laravel/cashier/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/laravel/cashier/labels{/name}","releases_url":"https://api.github.com/repos/laravel/cashier/releases{/id}","deployments_url":"https://api.github.com/repos/laravel/cashier/deployments","created_at":"2014-03-04T03:11:44Z","updated_at":"2017-07-02T03:03:47Z","pushed_at":"2017-07-04T02:24:28Z","git_url":"git://github.com/laravel/cashier.git","ssh_url":"git@github.com:laravel/cashier.git","clone_url":"https://github.com/laravel/cashier.git","svn_url":"https://github.com/laravel/cashier","homepage":"","size":45891,"stargazers_count":1073,"watchers_count":1073,"language":"PHP","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":274,"mirror_url":null,"open_issues_count":46,"forks":274,"open_issues":46,"watchers":1073,"default_branch":"7.0"}},"_links":{"self":{"href":"https://api.github.com/repos/laravel/cashier/pulls/423"},"html":{"href":"https://github.com/laravel/cashier/pull/423"},"issue":{"href":"https://api.github.com/repos/laravel/cashier/issues/423"},"comments":{"href":"https://api.github.com/repos/laravel/cashier/issues/423/comments"},"review_comments":{"href":"https://api.github.com/repos/laravel/cashier/pulls/423/comments"},"review_comment":{"href":"https://api.github.com/repos/laravel/cashier/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/laravel/cashier/pulls/423/commits"},"statuses":{"href":"https://api.github.com/repos/laravel/cashier/statuses/3d4e2d956f6d3e66ec9ac9275e28d6d064f641f1"}}}}
{"actor":{"display_login":"inxilpro"}}