Passed
Push — v3.0 ( 85fb60...4ec5e5 )
by Raza
02:30
created

Helpers::addAnnualPlan()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 12
rs 10
1
<?php
2
3
namespace Srmklive\PayPal\Traits\PayPalAPI\Subscriptions;
4
5
use Carbon\Carbon;
6
use Illuminate\Support\Str;
7
use Throwable;
8
9
trait Helpers
10
{
11
    /**
12
     * @var array
13
     */
14
    protected $trial_pricing = [];
15
16
    /**
17
     * @var int
18
     */
19
    protected $payment_failure_threshold = 3;
20
21
    /**
22
     * @var array
23
     */
24
    protected $product;
25
26
    /**
27
     * @var array
28
     */
29
    protected $billing_plan;
30
31
    /**
32
     * Setup a subscription.
33
     *
34
     * @param string $customer_name
35
     * @param string $customer_email
36
     * @param string $start_date
37
     *
38
     * @throws Throwable
39
     *
40
     * @return array|\Psr\Http\Message\StreamInterface|string
41
     */
42
    public function setupSubscription(string $customer_name, string $customer_email, string $start_date = '')
43
    {
44
        $start_date = isset($start_date) ? Carbon::parse($start_date)->toIso8601String() : Carbon::now()->toIso8601String();
45
46
        $subscription = $this->createSubscription([
0 ignored issues
show
Bug introduced by
It seems like createSubscription() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
        /** @scrutinizer ignore-call */ 
47
        $subscription = $this->createSubscription([
Loading history...
47
            'plan_id'    => $this->billing_plan['id'],
48
            'start_time' => $start_date,
49
            'quantity'   => 1,
50
            'subscriber' => [
51
                'name'          => [
52
                    'given_name' => $customer_name,
53
                ],
54
                'email_address' => $customer_email,
55
            ],
56
        ]);
57
58
        unset($this->product);
59
        unset($this->billing_plan);
60
        unset($this->trial_pricing);
61
62
        return $subscription;
63
    }
64
65
    /**
66
     * Add a subscription trial pricing tier.
67
     *
68
     * @param string    $interval_type
69
     * @param string    $interval_count
70
     * @param float|int $price
71
     *
72
     * @return \Srmklive\PayPal\Services\PayPal
73
     */
74
    public function addSubscriptionTrialPricing(string $interval_type, string $interval_count, float $price = 0): \Srmklive\PayPal\Services\PayPal
75
    {
76
        $this->trial_pricing = $this->addPlanBillingCycle($interval_type, $interval_count, $price, true);
0 ignored issues
show
Bug introduced by
$interval_count of type string is incompatible with the type integer expected by parameter $interval_count of Srmklive\PayPal\Traits\P...::addPlanBillingCycle(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
        $this->trial_pricing = $this->addPlanBillingCycle($interval_type, /** @scrutinizer ignore-type */ $interval_count, $price, true);
Loading history...
77
78
        return $this;
79
    }
80
81
    /**
82
     * Create a recurring monthly billing plan.
83
     *
84
     * @param string    $name
85
     * @param string    $description
86
     * @param float|int $price
87
     *
88
     * @throws Throwable
89
     *
90
     * @return \Srmklive\PayPal\Services\PayPal
91
     */
92
    public function addMonthlyPlan(string $name, string $description, float $price): \Srmklive\PayPal\Services\PayPal
93
    {
94
        if (isset($this->billing_plan)) {
95
            return $this;
96
        }
97
98
        $plan_pricing = $this->addPlanBillingCycle('MONTH', 1, $price);
99
        $billing_cycles = collect([$this->trial_pricing, $plan_pricing])->filter()->toArray();
100
101
        $this->addBillingPlan($name, $description, $billing_cycles);
102
103
        return $this;
104
    }
105
106
    /**
107
     * Create a recurring annual billing plan.
108
     *
109
     * @param string    $name
110
     * @param string    $description
111
     * @param float|int $price
112
     *
113
     * @throws Throwable
114
     *
115
     * @return \Srmklive\PayPal\Services\PayPal
116
     */
117
    public function addAnnualPlan(string $name, string $description, float $price): \Srmklive\PayPal\Services\PayPal
118
    {
119
        if (isset($this->billing_plan)) {
120
            return $this;
121
        }
122
123
        $plan_pricing = $this->addPlanBillingCycle('YEAR', 1, $price);
124
        $billing_cycles = collect([$this->trial_pricing, $plan_pricing])->filter()->toArray();
125
126
        $this->addBillingPlan($name, $description, $billing_cycles);
127
128
        return $this;
129
    }
130
131
    /**
132
     * Add Plan's Billing cycle.
133
     *
134
     * @param string $interval_unit
135
     * @param int    $interval_count
136
     * @param float  $price
137
     * @param bool   $trial
138
     *
139
     * @return array
140
     */
141
    protected function addPlanBillingCycle(string $interval_unit, int $interval_count, float $price, bool $trial = false): array
142
    {
143
        $pricing_scheme = [
144
            'fixed_price' => [
145
                'value'         => $price,
146
                'currency_code' => $this->getCurrency(),
0 ignored issues
show
Bug introduced by
It seems like getCurrency() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

146
                'currency_code' => $this->/** @scrutinizer ignore-call */ getCurrency(),
Loading history...
147
            ],
148
        ];
149
150
        return [
151
            'frequency' => [
152
                'interval_unit'  => $interval_unit,
153
                'interval_count' => $interval_count,
154
            ],
155
            'tenure_type'    => ($trial === true) ? 'TRIAL' : 'REGULAR',
156
            'sequence'       => ($trial === true) ? 1 : 2,
157
            'total_cycles'   => ($trial === true) ? 1 : 0,
158
            'pricing_scheme' => $pricing_scheme,
159
        ];
160
    }
161
162
    /**
163
     * Create a product for a subscription's billing plan.
164
     *
165
     * @param string $name
166
     * @param string $description
167
     * @param string $type
168
     * @param string $category
169
     *
170
     * @throws Throwable
171
     *
172
     * @return \Srmklive\PayPal\Services\PayPal
173
     */
174
    public function addProduct(string $name, string $description, string $type, string $category): \Srmklive\PayPal\Services\PayPal
175
    {
176
        if (isset($this->product)) {
177
            return $this;
178
        }
179
180
        $request_id = Str::random();
181
182
        $this->product = $this->createProduct([
0 ignored issues
show
Bug introduced by
It seems like createProduct() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

182
        /** @scrutinizer ignore-call */ 
183
        $this->product = $this->createProduct([
Loading history...
183
            'name'          => $name,
184
            'description'   => $description,
185
            'type'          => $type,
186
            'category'      => $category,
187
        ], $request_id);
188
189
        return $this;
190
    }
191
192
    /**
193
     * Add subscription's billing plan's product by ID.
194
     *
195
     * @param string $product_id
196
     *
197
     * @return \Srmklive\PayPal\Services\PayPal
198
     */
199
    public function addProductById(string $product_id): \Srmklive\PayPal\Services\PayPal
200
    {
201
        $this->product = [
202
            'id' => $product_id,
203
        ];
204
205
        return $this;
206
    }
207
208
    /**
209
     * Add subscription's billing plan by ID.
210
     *
211
     * @param string $plan_id
212
     *
213
     * @return \Srmklive\PayPal\Services\PayPal
214
     */
215
    public function addBillingPlanById(string $plan_id): \Srmklive\PayPal\Services\PayPal
216
    {
217
        $this->billing_plan = [
218
            'id' => $plan_id,
219
        ];
220
221
        return $this;
222
    }
223
224
    /**
225
     * Create a product for a subscription's billing plan.
226
     *
227
     * @param string $name
228
     * @param string $description
229
     * @param array  $billing_cycles
230
     *
231
     * @throws Throwable
232
     *
233
     * @return void
234
     */
235
    protected function addBillingPlan(string $name, string $description, array $billing_cycles): void
236
    {
237
        $request_id = Str::random();
238
239
        $plan_params = [
240
            'product_id'          => $this->product['id'],
241
            'name'                => $name,
242
            'description'         => $description,
243
            'status'              => 'ACTIVE',
244
            'billing_cycles'      => $billing_cycles,
245
            'payment_preferences' => [
246
                'auto_bill_outstanding'     => true,
247
                'setup_fee_failure_action'  => 'CONTINUE',
248
                'payment_failure_threshold' => $this->payment_failure_threshold,
249
            ],
250
        ];
251
252
        $this->billing_plan = $this->createPlan($plan_params, $request_id);
0 ignored issues
show
Bug introduced by
It seems like createPlan() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

252
        /** @scrutinizer ignore-call */ 
253
        $this->billing_plan = $this->createPlan($plan_params, $request_id);
Loading history...
253
    }
254
}
255