-
Notifications
You must be signed in to change notification settings - Fork 1
/
Dues.php
105 lines (90 loc) · 3.56 KB
/
Dues.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
namespace TeamGantt\Dues;
use TeamGantt\Dues\Contracts\EventListener;
use TeamGantt\Dues\Contracts\EventListenerContainer;
use TeamGantt\Dues\Contracts\SubscriptionGateway;
use TeamGantt\Dues\Event\Dispatcher;
use TeamGantt\Dues\Exception\CustomerNotUpdatedException;
use TeamGantt\Dues\Exception\SubscriptionNotCreatedException;
use TeamGantt\Dues\Model\Customer;
use TeamGantt\Dues\Model\PaymentMethod;
use TeamGantt\Dues\Model\Subscription;
use TeamGantt\Dues\Model\Subscription\Status;
use TeamGantt\Dues\Processor\ProcessesSubscriptions;
/**
* Dues does subscriptions dawgz.
*/
class Dues implements SubscriptionGateway, EventListenerContainer
{
/*
* Dues processes subscriptions. Includes the ProcessesSubscriptions trait
* in order to provide the basic gateway API, but allows this class to focus
* on the things that make Dues special and unique
*/
use ProcessesSubscriptions {
createSubscription as traitCreateSubscription;
}
private SubscriptionGateway $gateway;
private Dispatcher $events;
public function __construct(SubscriptionGateway $gateway)
{
$this->gateway = $gateway;
$dispatcher = new Dispatcher();
$this->setDispatcher($dispatcher);
$gateway->setDispatcher($dispatcher);
}
public function addListener(EventListener $listener): void
{
$this->events->addListener($listener);
}
public function removeListener(EventListener $listener): void
{
$this->events->removeListener($listener);
}
public function setDispatcher(Dispatcher $events): void
{
$this->events = $events;
}
/**
* Create a new subscription. Supports creating a new customer in tandem with
* the new subscription. If subscription creation fails when a new user is present,
* the user will be rolled back to prevent orphaned customers.
*/
public function createSubscription(Subscription $subscription): Subscription
{
try {
return $this->traitCreateSubscription($subscription);
} catch (SubscriptionNotCreatedException $e) { // rollback any new customers
if ($customer = $e->getCustomer()) {
$this->deleteCustomer($customer->getId());
}
throw $e;
}
}
/**
* Change a customer's payment method. Supports new and existing payment methods.
* The given payment method will be set to the default payment method, and all
* active subscriptions will be updated to use the new payment method.
*/
public function changePaymentMethod(Customer $customer, PaymentMethod $paymentMethod): Customer
{
// Attach the payment method and set it as the default payment method
$paymentMethod->setIsDefaultPaymentMethod(true);
$customer->addPaymentMethod($paymentMethod);
$customer = $this->updateCustomer($customer);
// Update all subscriptions with the new payment method
$paymentMethod = $customer->getDefaultPaymentMethod();
if (null === $paymentMethod) {
throw new CustomerNotUpdatedException('Failed to set default payment method for Customer');
}
$subscriptions = $this->findSubscriptionsByCustomerId($customer->getId());
foreach ($subscriptions as $subscription) {
if ($subscription->isNot(Status::active(), Status::pending(), Status::pastDue())) {
continue;
}
$subscription->setPaymentMethod($paymentMethod);
$this->updateSubscription($subscription);
}
return $customer;
}
}