PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.15.5
GiveWP – Donation Plugin and Fundraising Platform v4.15.5
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.15.5, at src/PaymentGateways/Gateways/Stripe/StripePaymentElementGateway/StripePaymentElementRepository.php

216 lines 7.0 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 * @throws ApiErrorException
39 */
40 protected function refundStripePayment(Donation $donation): Refund
41 {
42 return Refund::create([
43 'payment_intent' => $donation->gatewayTransactionId,
44 ]);
45 }
46
47 /**
48 * Get or create Stripe Customer from Donation
49 *
50 * @since 3.0.0
51 * @throws Exception
52 * @throws ApiErrorException
53 */
54 public function getOrCreateStripeCustomerFromDonation(
55 string $connectAccountId,
56 Donation $donation
57 ): Customer
58 {
59 $donorCustomerId = give_stripe_get_customer_id($donation->email);
60
61 // create a new customer if the donor does not have a stripe id
62 if (!$donorCustomerId) {
63 $customer = $this->createCustomer($donation, $connectAccountId);
64 } else {
65 try {
66 // if the donor has a stripe ID, try retrieving the customer from Stripe.
67 $customer = $this->retrieveCustomer($donorCustomerId, $connectAccountId);
68
69 // if the customer is deleted, create a new customer
70 if ($customer->isDeleted()) {
71 $customer = $this->createCustomer($donation, $connectAccountId);
72 }
73 } catch (InvalidRequestException $exception) {
74 // If the donor has a stripe id but is not valid with this account,
75 // a resource_missing error will be thrown. In this case, we need to
76 // create a new customer. The newer Stripe api has a search functionality
77 // that would make more sense here.
78 if ($exception->getStripeCode() === ErrorObject::CODE_RESOURCE_MISSING) {
79 $customer = $this->createCustomer($donation, $connectAccountId);
80 } else {
81 throw $exception;
82 }
83 }
84 }
85
86 DonationNote::create([
87 'donationId' => $donation->id,
88 'content' => sprintf(__('Stripe Customer ID: %s', 'give'), $customer->id)
89 ]);
90
91
92 // save the stripe ID to donor meta
93 // it appears this does not account for multiple stripe accounts
94 if ($customer->id !== $donorCustomerId) {
95 give()->donor_meta->update_meta($donation->donorId, give_stripe_get_customer_key(), $customer->id);
96 }
97
98 // also save to donation meta
99 give_update_meta($donation->id, give_stripe_get_customer_key(), $customer->id);
100
101 return $customer;
102 }
103
104 /**
105 * @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`.
106 * @since 3.0.0
107 *
108 * @throws InvalidPropertyName
109 */
110 protected function getPaymentIntentDataFromDonation(
111 Donation $donation,
112 Customer $customer
113 ): StripePaymentIntentData {
114 // Collect intent args to be updated
115 $intentArgs = [
116 'amount' => $donation->amount->formatToMinorAmount(),
117 'currency' => $donation->amount->getCurrency()->getCode(),
118 'customer' => $customer->id,
119 'description' => (new SaveDonationSummary)($donation)->getSummaryWithDonor(),
120 'metadata' => give_stripe_prepare_metadata($donation->id),
121 'automatic_payment_methods' => ['enabled' => true],
122 ];
123
124 // Add application fee, if the Stripe premium add-on is not active.
125 if (ApplicationFee::canAddfee()) {
126 $intentArgs['application_fee_amount'] = give_stripe_get_application_fee_amount(
127 $donation->amount->getAmount()
128 );
129 }
130
131 // Send Stripe Receipt emails when enabled.
132 if (give_is_setting_enabled(give_get_option('stripe_receipt_emails'))) {
133 $intentArgs['receipt_email'] = $donation->email;
134 }
135
136 return StripePaymentIntentData::fromArray($intentArgs);
137 }
138
139 /**
140 * @since 3.0.0
141 *
142 * @return void
143 * @throws Exception
144 */
145 protected function updateDonationMetaFromPaymentIntent(
146 Donation $donation,
147 PaymentIntent $intent
148 ) {
149 $donation->status = DonationStatus::PROCESSING();
150 $donation->gatewayTransactionId = $intent->id;
151 $donation->save();
152
153 DonationNote::create([
154 'donationId' => $donation->id,
155 'content' => sprintf(__('Stripe Charge/Payment Intent ID: %s', 'give'), $intent->id)
156 ]);
157
158 DonationNote::create([
159 'donationId' => $donation->id,
160 'content' => sprintf(__('Stripe Payment Intent Client Secret: %s', 'give'), $intent->client_secret)
161 ]);
162 }
163
164 /**
165 * @since 3.0.0
166 */
167 protected function getStripePublishableKey(int $formId): string
168 {
169 return give_stripe_get_publishable_key($formId);
170 }
171
172 /**
173 * @since 3.0.0
174 */
175 protected function getStripeConnectedAccountKey(int $formId): string
176 {
177 return give_stripe_get_connected_account_id($formId);
178 }
179
180 /**
181 * @since 3.0.0
182 *
183 * @return void;
184 */
185 protected function setUpStripeAppInfo(int $formId)
186 {
187 give_stripe_set_app_info($formId);
188 }
189
190 /**
191 * @since 3.0.0
192 *
193 * @throws ApiErrorException
194 */
195 protected function createCustomer(Donation $donation, string $connectAccountId): Customer
196 {
197 return Customer::create(
198 [
199 'name' => "$donation->firstName $donation->lastName",
200 'email' => $donation->email,
201 ],
202 ['stripe_account' => $connectAccountId]
203 );
204 }
205
206 /**
207 * @since 3.0.0
208 *
209 * @throws ApiErrorException|InvalidRequestException
210 */
211 protected function retrieveCustomer(string $customerId, string $connectAccountId): Customer
212 {
213 return Customer::retrieve($customerId, ['stripe_account' => $connectAccountId]);
214 }
215 }
216