PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.18.0
GiveWP – Donation Plugin and Fundraising Platform v4.18.0
4.18.0 4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 All 257 releases
give / src / PaymentGateways / Gateways / Stripe / StripePaymentElementGateway / StripePaymentElementRepository.php

StripePaymentElementRepository.php in GiveWP – Donation Plugin and Fundraising Platform 4.18.0, at src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/StripePaymentElementRepository.php

227 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Give\PaymentGateways\Gateways\Stripe\StripePaymentElementGateway;
4
5 use Give\Donations\Models\Donation;
6 use Give\Donations\Models\DonationNote;
7 use Give\Donations\ValueObjects\DonationStatus;
8 use Give\Framework\Exceptions\Primitives\Exception;
9 use Give\PaymentGateways\Exceptions\InvalidPropertyName;
10 use Give\PaymentGateways\Gateways\Stripe\Actions\SaveDonationSummary;
11 use Give\PaymentGateways\Gateways\Stripe\StripePaymentElementGateway\DataTransferObjects\StripePaymentIntentData;
12 use Give\PaymentGateways\Stripe\ApplicationFee;
13 use Stripe\Customer;
14 use Stripe\ErrorObject;
15 use Stripe\Exception\ApiErrorException;
16 use Stripe\Exception\InvalidRequestException;
17 use Stripe\PaymentIntent;
18 use Stripe\Refund;
19
20 trait StripePaymentElementRepository
21 {
22 /**
23 * @since 3.0.0
24 * @throws ApiErrorException
25 */
26 protected function generateStripePaymentIntent(
27 string $stripeConnectAccountId,
28 StripePaymentIntentData $data
29 ): PaymentIntent {
30 return PaymentIntent::create(
31 $data->toParams(),
32 $data->toOptions($stripeConnectAccountId)
33 );
34 }
35
36 /**
37 * @since 4.7.0
38 *
39 * @param Donation $donation
40 *
41 * @throws ApiErrorException
42 */
43 protected function refundStripePayment(Donation $donation): Refund
44 {
45 $stripeConnectAccountId = give_stripe_get_connected_account_id($donation->formId);
46
47 $options = [];
48 if ($stripeConnectAccountId !== '') {
49 $options['stripe_account'] = $stripeConnectAccountId;
50 }
51
52 return Refund::create(
53 ['payment_intent' => $donation->gatewayTransactionId],
54 $options
55 );
56 }
57
58 /**
59 * Get or create Stripe Customer from Donation
60 *
61 * @since 3.0.0
62 * @throws Exception
63 * @throws ApiErrorException
64 */
65 public function getOrCreateStripeCustomerFromDonation(
66 string $connectAccountId,
67 Donation $donation
68 ): Customer
69 {
70 $donorCustomerId = give_stripe_get_customer_id($donation->email);
71
72 // create a new customer if the donor does not have a stripe id
73 if (!$donorCustomerId) {
74 $customer = $this->createCustomer($donation, $connectAccountId);
75 } else {
76 try {
77 // if the donor has a stripe ID, try retrieving the customer from Stripe.
78 $customer = $this->retrieveCustomer($donorCustomerId, $connectAccountId);
79
80 // if the customer is deleted, create a new customer
81 if ($customer->isDeleted()) {
82 $customer = $this->createCustomer($donation, $connectAccountId);
83 }
84 } catch (InvalidRequestException $exception) {
85 // If the donor has a stripe id but is not valid with this account,
86 // a resource_missing error will be thrown. In this case, we need to
87 // create a new customer. The newer Stripe api has a search functionality
88 // that would make more sense here.
89 if ($exception->getStripeCode() === ErrorObject::CODE_RESOURCE_MISSING) {
90 $customer = $this->createCustomer($donation, $connectAccountId);
91 } else {
92 throw $exception;
93 }
94 }
95 }
96
97 DonationNote::create([
98 'donationId' => $donation->id,
99 'content' => sprintf(__('Stripe Customer ID: %s', 'give'), $customer->id)
100 ]);
101
102
103 // save the stripe ID to donor meta
104 // it appears this does not account for multiple stripe accounts
105 if ($customer->id !== $donorCustomerId) {
106 give()->donor_meta->update_meta($donation->donorId, give_stripe_get_customer_key(), $customer->id);
107 }
108
109 // also save to donation meta
110 give_update_meta($donation->id, give_stripe_get_customer_key(), $customer->id);
111
112 return $customer;
113 }
114
115 /**
116 * @since 3.20.0 removed statement_descriptor. As of 01/02/2024, Stripe no longer supports the `statement_descriptor` parameter on the PaymentIntent API for PaymentIntents in which one of the supported `payment_method_types` is `card`.
117 * @since 3.0.0
118 *
119 * @throws InvalidPropertyName
120 */
121 protected function getPaymentIntentDataFromDonation(
122 Donation $donation,
123 Customer $customer
124 ): StripePaymentIntentData {
125 // Collect intent args to be updated
126 $intentArgs = [
127 'amount' => $donation->amount->formatToMinorAmount(),
128 'currency' => $donation->amount->getCurrency()->getCode(),
129 'customer' => $customer->id,
130 'description' => (new SaveDonationSummary)($donation)->getSummaryWithDonor(),
131 'metadata' => give_stripe_prepare_metadata($donation->id),
132 'automatic_payment_methods' => ['enabled' => true],
133 ];
134
135 // Add application fee, if the Stripe premium add-on is not active.
136 if (ApplicationFee::canAddfee()) {
137 $intentArgs['application_fee_amount'] = give_stripe_get_application_fee_amount(
138 $donation->amount->getAmount()
139 );
140 }
141
142 // Send Stripe Receipt emails when enabled.
143 if (give_is_setting_enabled(give_get_option('stripe_receipt_emails'))) {
144 $intentArgs['receipt_email'] = $donation->email;
145 }
146
147 return StripePaymentIntentData::fromArray($intentArgs);
148 }
149
150 /**
151 * @since 3.0.0
152 *
153 * @return void
154 * @throws Exception
155 */
156 protected function updateDonationMetaFromPaymentIntent(
157 Donation $donation,
158 PaymentIntent $intent
159 ) {
160 $donation->status = DonationStatus::PROCESSING();
161 $donation->gatewayTransactionId = $intent->id;
162 $donation->save();
163
164 DonationNote::create([
165 'donationId' => $donation->id,
166 'content' => sprintf(__('Stripe Charge/Payment Intent ID: %s', 'give'), $intent->id)
167 ]);
168
169 DonationNote::create([
170 'donationId' => $donation->id,
171 'content' => sprintf(__('Stripe Payment Intent Client Secret: %s', 'give'), $intent->client_secret)
172 ]);
173 }
174
175 /**
176 * @since 3.0.0
177 */
178 protected function getStripePublishableKey(int $formId): string
179 {
180 return give_stripe_get_publishable_key($formId);
181 }
182
183 /**
184 * @since 3.0.0
185 */
186 protected function getStripeConnectedAccountKey(int $formId): string
187 {
188 return give_stripe_get_connected_account_id($formId);
189 }
190
191 /**
192 * @since 3.0.0
193 *
194 * @return void;
195 */
196 protected function setUpStripeAppInfo(int $formId)
197 {
198 give_stripe_set_app_info($formId);
199 }
200
201 /**
202 * @since 3.0.0
203 *
204 * @throws ApiErrorException
205 */
206 protected function createCustomer(Donation $donation, string $connectAccountId): Customer
207 {
208 return Customer::create(
209 [
210 'name' => "$donation->firstName $donation->lastName",
211 'email' => $donation->email,
212 ],
213 ['stripe_account' => $connectAccountId]
214 );
215 }
216
217 /**
218 * @since 3.0.0
219 *
220 * @throws ApiErrorException|InvalidRequestException
221 */
222 protected function retrieveCustomer(string $customerId, string $connectAccountId): Customer
223 {
224 return Customer::retrieve($customerId, ['stripe_account' => $connectAccountId]);
225 }
226 }
227