Passed
Pull Request — v3.0 (#478)
by Raza
02:03
created

Helpers::addProductById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
rs 10
c 2
b 0
f 0
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 addPlanTrialPricing(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 weekly 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 addWeeklyPlan(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('WEEK', 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 monthly 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 addMonthlyPlan(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('MONTH', 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
     * Create a recurring annual billing plan.
133
     *
134
     * @param string    $name
135
     * @param string    $description
136
     * @param float|int $price
137
     *
138
     * @throws Throwable
139
     *
140
     * @return \Srmklive\PayPal\Services\PayPal
141
     */
142
    public function addAnnualPlan(string $name, string $description, float $price): \Srmklive\PayPal\Services\PayPal
143
    {
144
        if (isset($this->billing_plan)) {
145
            return $this;
146
        }
147
148
        $plan_pricing = $this->addPlanBillingCycle('YEAR', 1, $price);
149
        $billing_cycles = collect([$this->trial_pricing, $plan_pricing])->filter()->toArray();
150
151
        $this->addBillingPlan($name, $description, $billing_cycles);
152
153
        return $this;
154
    }
155
156
    /**
157
     * Add Plan's Billing cycle.
158
     *
159
     * @param string $interval_unit
160
     * @param int    $interval_count
161
     * @param float  $price
162
     * @param bool   $trial
163
     *
164
     * @return array
165
     */
166
    protected function addPlanBillingCycle(string $interval_unit, int $interval_count, float $price, bool $trial = false): array
167
    {
168
        $pricing_scheme = [
169
            'fixed_price' => [
170
                'value'         => $price,
171
                '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

171
                'currency_code' => $this->/** @scrutinizer ignore-call */ getCurrency(),
Loading history...
172
            ],
173
        ];
174
175
        return [
176
            'frequency' => [
177
                'interval_unit'  => $interval_unit,
178
                'interval_count' => $interval_count,
179
            ],
180
            'tenure_type'    => ($trial === true) ? 'TRIAL' : 'REGULAR',
181
            'sequence'       => ($trial === true) ? 1 : 2,
182
            'total_cycles'   => ($trial === true) ? 1 : 0,
183
            'pricing_scheme' => $pricing_scheme,
184
        ];
185
    }
186
187
    /**
188
     * Create a product for a subscription's billing plan.
189
     *
190
     * @param string $name
191
     * @param string $description
192
     * @param string $type
193
     * @param string $category
194
     *
195
     * @throws Throwable
196
     *
197
     * @return \Srmklive\PayPal\Services\PayPal
198
     */
199
    public function addProduct(string $name, string $description, string $type, string $category): \Srmklive\PayPal\Services\PayPal
200
    {
201
        if (isset($this->product)) {
202
            return $this;
203
        }
204
205
        $request_id = Str::random();
206
207
        $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

207
        /** @scrutinizer ignore-call */ 
208
        $this->product = $this->createProduct([
Loading history...
208
            'name'          => $name,
209
            'description'   => $description,
210
            'type'          => $type,
211
            'category'      => $category,
212
        ], $request_id);
213
214
        return $this;
215
    }
216
217
    /**
218
     * Add subscription's billing plan's product by ID.
219
     *
220
     * @param string $product_id
221
     *
222
     * @return \Srmklive\PayPal\Services\PayPal
223
     */
224
    public function addProductById(string $product_id): \Srmklive\PayPal\Services\PayPal
225
    {
226
        $this->product = [
227
            'id' => $product_id,
228
        ];
229
230
        return $this;
231
    }
232
233
    /**
234
     * Add subscription's billing plan by ID.
235
     *
236
     * @param string $plan_id
237
     *
238
     * @return \Srmklive\PayPal\Services\PayPal
239
     */
240
    public function addBillingPlanById(string $plan_id): \Srmklive\PayPal\Services\PayPal
241
    {
242
        $this->billing_plan = [
243
            'id' => $plan_id,
244
        ];
245
246
        return $this;
247
    }
248
249
    /**
250
     * Create a product for a subscription's billing plan.
251
     *
252
     * @param string $name
253
     * @param string $description
254
     * @param array  $billing_cycles
255
     *
256
     * @throws Throwable
257
     *
258
     * @return void
259
     */
260
    protected function addBillingPlan(string $name, string $description, array $billing_cycles): void
261
    {
262
        $request_id = Str::random();
263
264
        $plan_params = [
265
            'product_id'          => $this->product['id'],
266
            'name'                => $name,
267
            'description'         => $description,
268
            'status'              => 'ACTIVE',
269
            'billing_cycles'      => $billing_cycles,
270
            'payment_preferences' => [
271
                'auto_bill_outstanding'     => true,
272
                'setup_fee_failure_action'  => 'CONTINUE',
273
                'payment_failure_threshold' => $this->payment_failure_threshold,
274
            ],
275
        ];
276
277
        $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

277
        /** @scrutinizer ignore-call */ 
278
        $this->billing_plan = $this->createPlan($plan_params, $request_id);
Loading history...
278
    }
279
}
280