PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.4.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.4.1
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Modules / PaymentMethods / PayPalGateway / PayPalSubscriptions.php

PayPalSubscriptions.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.4.1, at app/Modules/PaymentMethods/PayPalGateway/PayPalSubscriptions.php

189 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Modules\PaymentMethods\PayPalGateway;
4
5 use FluentCart\App\Helpers\Helper;
6 use FluentCart\App\Helpers\Status;
7 use FluentCart\App\Models\OrderTransaction;
8 use FluentCart\App\Models\Subscription;
9 use FluentCart\App\Modules\PaymentMethods\Core\AbstractSubscriptionModule;
10 use FluentCart\App\Modules\PaymentMethods\PayPalGateway\API\API;
11 use FluentCart\App\Modules\Subscriptions\Services\SubscriptionService;
12 use FluentCart\App\Services\DateTime\DateTime;
13 use FluentCart\Framework\Support\Arr;
14
15 class PayPalSubscriptions extends AbstractSubscriptionModule
16 {
17 public function reSyncSubscriptionFromRemote(Subscription $subscriptionModel)
18 {
19 $order = $subscriptionModel->order;
20
21 $paypalSubscription = (new API())->verifySubscription($subscriptionModel->vendor_subscription_id, $order->mode);
22
23 if (is_wp_error($paypalSubscription)) {
24 return $paypalSubscription;
25 }
26
27 $newPayment = false;
28
29 $subscriptionStatus = (new SubscriptionManager)->getCorrectSubscriptionStatus(Arr::get($paypalSubscription, 'status'));
30 $nextBillingDate = Arr::get($paypalSubscription, 'billing_info.next_billing_time') ?? null;
31
32 $payer = Arr::get($paypalSubscription, 'subscriber', []);
33
34 if ($nextBillingDate) {
35 $nextBillingDate = gmdate('Y-m-d H:i:s', strtotime($nextBillingDate));
36 }
37
38 $subscriptionUpdateData = array_filter([
39 'current_payment_method' => 'paypal',
40 'status' => $subscriptionStatus
41 ]);
42
43 if ($nextBillingDate) {
44 $subscriptionUpdateData['next_billing_date'] = $nextBillingDate;
45 }
46
47 if (Arr::get($paypalSubscription, 'status') === 'CANCELLED') {
48 $statusUpdateTime = Arr::get($paypalSubscription, 'status_update_time');
49 if ($statusUpdateTime) {
50 $subscriptionUpdateData['canceled_at'] = gmdate('Y-m-d H:i:s', strtotime($statusUpdateTime));
51 }
52 }
53
54 $startTime = Arr::get($paypalSubscription, 'start_time');
55 $endTime = DateTime::gmtNow()->format('Y-m-d\TH:i:s.v\Z');
56
57 $response = (new API())->getResource('billing/subscriptions/' . $subscriptionModel->vendor_subscription_id . '/transactions', [
58 'start_time' => $startTime,
59 'end_time' => $endTime
60 ], $order->mode);
61
62 if (is_wp_error($response)) {
63 return $response;
64 }
65
66 // reverse the array to get the latest transaction last
67 $paypalTransactions = array_reverse(Arr::get($response, 'transactions', []));
68
69
70 if (!empty($paypalTransactions)) {
71 foreach ($paypalTransactions as $paypalTransaction) {
72
73 $amount = Helper::toCent(Arr::get($paypalTransaction, 'amount_with_breakdown.gross_amount.value', 0));
74 $chargeId = Arr::get($paypalTransaction, 'id');
75
76 $status = strtolower(Arr::get($paypalTransaction, 'status'));
77
78 if ($status == 'completed') {
79 $transaction = OrderTransaction::query()
80 ->select(['id', 'order_id'])
81 ->where('vendor_charge_id', $chargeId)
82 ->first();
83
84 if (!$transaction) {
85 // check if any transaction related to this subscription exists without vendor_charge_id, mainly for first cycle payment
86 $transaction = OrderTransaction::query()
87 ->select(['id', 'order_id'])
88 ->where('subscription_id', $subscriptionModel->id)
89 ->where('vendor_charge_id', '')
90 ->where('total', $amount)
91 ->where('transaction_type', Status::TRANSACTION_TYPE_CHARGE)
92 ->first();
93
94 if ($transaction) {
95 $transaction->update([
96 'vendor_charge_id' => $chargeId,
97 'status' => Status::TRANSACTION_SUCCEEDED,
98 'payment_method_type' => 'PayPal',
99 'meta' => array_merge($transaction->meta, [
100 'payer' => $payer
101 ])
102 ]);
103 continue;
104 }
105
106 $transactionData = [
107 'subscription_id' => $subscriptionModel->id,
108 'payment_method' => 'paypal',
109 'vendor_charge_id' => $chargeId,
110 'payment_method_type' => 'PayPal',
111 'total' => $amount,
112 'meta' => [
113 'payer' => $payer
114 ],
115 'created_at' => DateTime::anyTimeToGmt(Arr::get($paypalTransaction, 'time'))->format('Y-m-d H:i:s'),
116 ];
117
118 $newPayment = true;
119 SubscriptionService::recordRenewalPayment($transactionData, $subscriptionModel, $subscriptionUpdateData);
120 } else if ($transaction->status !== Status::TRANSACTION_SUCCEEDED) {
121 $transaction->update([
122 'vendor_charge_id' => $chargeId,
123 'status' => Status::TRANSACTION_SUCCEEDED,
124 'meta' => array_merge($transaction->meta, [
125 'payer' => $payer
126 ])
127 ]);
128 }
129 }
130 }
131 }
132
133 if (!$newPayment) {
134 $subscriptionModel = SubscriptionService::syncSubscriptionStates($subscriptionModel, $subscriptionUpdateData);
135 } else {
136 $subscriptionModel = Subscription::query()->find($subscriptionModel->id);
137 }
138
139 return $subscriptionModel;
140 }
141
142 public function cancel($vendorSubscriptionId, $args = [])
143 {
144 if (!$vendorSubscriptionId) {
145 return new \WP_Error('invalid_subscription', __('Invalid vendor subscription ID.', 'fluent-cart'));
146 }
147
148 // first check , before canceling the subscription
149 $paypalSubscription = (new API())->verifySubscription($vendorSubscriptionId, Arr::get($args, 'mode', ''));
150
151 if (is_wp_error($paypalSubscription)) {
152 return $paypalSubscription;
153 }
154
155 $subscriptionStatus = (new SubscriptionManager)->getCorrectSubscriptionStatus(Arr::get($paypalSubscription, 'status'));
156
157 if ($subscriptionStatus === Status::SUBSCRIPTION_CANCELED) {
158 $statusUpdateTime = Arr::get($paypalSubscription, 'status_update_time');
159 return [
160 'status' => Status::SUBSCRIPTION_CANCELED,
161 'canceled_at' => $statusUpdateTime ? gmdate('Y-m-d H:i:s', strtotime($statusUpdateTime)) : NULL
162 ];
163 }
164
165 $response = API::createResource('billing/subscriptions/' . $vendorSubscriptionId . '/cancel', [
166 'reason' => Arr::get($args, 'reason', __('Subscription canceled.', 'fluent-cart')),
167 ], Arr::get($args, 'mode', ''));
168
169 if (is_wp_error($response)) {
170 return $response;
171 }
172
173 return [
174 'status' => Status::SUBSCRIPTION_CANCELED
175 ];
176 }
177
178 public function getOrCreateNewPlan($subscriptionId, $reason)
179 {
180 (new SubscriptionManager())->getOrCreateNewPlan($subscriptionId, $reason);
181 }
182
183 public function confirmSubscriptionSwitch($data, $subscriptionId)
184 {
185 (new SubscriptionManager())->confirmSubscriptionSwitch($data, $subscriptionId);
186 }
187
188 }
189