|
@@ -79,13 +79,13 @@ class PayStripeApi |
|
@@ -79,13 +79,13 @@ class PayStripeApi |
|
79
|
* @method :post
|
79
|
* @method :post
|
|
80
|
* @time :2024/12/24 10:38
|
80
|
* @time :2024/12/24 10:38
|
|
81
|
*/
|
81
|
*/
|
|
82
|
- public function createPaymentIntent($amount, $currency = 'usd')
|
82
|
+ public function createPaymentIntent($amount, $currency = 'usd', $paymentMethodTypes = 'card')
|
|
83
|
{
|
83
|
{
|
|
84
|
$url = "https://api.stripe.com/v1/payment_intents";
|
84
|
$url = "https://api.stripe.com/v1/payment_intents";
|
|
85
|
$data = [
|
85
|
$data = [
|
|
86
|
'amount' => $amount,
|
86
|
'amount' => $amount,
|
|
87
|
'currency' => $currency,
|
87
|
'currency' => $currency,
|
|
88
|
- 'payment_method_types[]' => $this->currency_types[$currency][0],
|
88
|
+ 'payment_method_types[]' => $paymentMethodTypes,
|
|
89
|
];
|
89
|
];
|
|
90
|
return $this->sendRequest($url, 'POST', $data);
|
90
|
return $this->sendRequest($url, 'POST', $data);
|
|
91
|
}
|
91
|
}
|
|
@@ -104,87 +104,6 @@ class PayStripeApi |
|
@@ -104,87 +104,6 @@ class PayStripeApi |
|
104
|
}
|
104
|
}
|
|
105
|
|
105
|
|
|
106
|
/**
|
106
|
/**
|
|
107
|
- * @remark :创建客户
|
|
|
|
108
|
- * @name :createCustomer
|
|
|
|
109
|
- * @author :lyh
|
|
|
|
110
|
- * @method :post
|
|
|
|
111
|
- * @time :2024/12/24 10:41
|
|
|
|
112
|
- */
|
|
|
|
113
|
- public function createCustomer($name, $email, $description = '')
|
|
|
|
114
|
- {
|
|
|
|
115
|
- $url = "https://api.stripe.com/v1/customers";
|
|
|
|
116
|
- $data = [
|
|
|
|
117
|
- 'name' => $name,
|
|
|
|
118
|
- 'email' => $email,
|
|
|
|
119
|
- 'description' => $description
|
|
|
|
120
|
- ];
|
|
|
|
121
|
- return $this->sendRequest($url, 'POST', $data);
|
|
|
|
122
|
- }
|
|
|
|
123
|
-
|
|
|
|
124
|
- /**
|
|
|
|
125
|
- * @remark :查询客户
|
|
|
|
126
|
- * @name :retrieveCustomer
|
|
|
|
127
|
- * @author :lyh
|
|
|
|
128
|
- * @method :post
|
|
|
|
129
|
- * @time :2024/12/24 10:41
|
|
|
|
130
|
- */
|
|
|
|
131
|
- public function retrieveCustomer($customerId)
|
|
|
|
132
|
- {
|
|
|
|
133
|
- $url = "https://api.stripe.com/v1/customers/{$customerId}";
|
|
|
|
134
|
- return $this->sendRequest($url, 'GET');
|
|
|
|
135
|
- }
|
|
|
|
136
|
-
|
|
|
|
137
|
- /**
|
|
|
|
138
|
- * @remark :删除客户
|
|
|
|
139
|
- * @name :deleteCustomer
|
|
|
|
140
|
- * @author :lyh
|
|
|
|
141
|
- * @method :post
|
|
|
|
142
|
- * @time :2024/12/24 10:42
|
|
|
|
143
|
- */
|
|
|
|
144
|
- public function deleteCustomer($customerId)
|
|
|
|
145
|
- {
|
|
|
|
146
|
- $url = "https://api.stripe.com/v1/customers/{$customerId}";
|
|
|
|
147
|
- return $this->sendRequest($url, 'DELETE');
|
|
|
|
148
|
- }
|
|
|
|
149
|
-
|
|
|
|
150
|
- /**
|
|
|
|
151
|
- * @remark :创建支付方法
|
|
|
|
152
|
- * @name :createPaymentMethod
|
|
|
|
153
|
- * @author :lyh
|
|
|
|
154
|
- * @method :post
|
|
|
|
155
|
- * @time :2024/12/24 10:42
|
|
|
|
156
|
- */
|
|
|
|
157
|
- public function createPaymentMethod($cardNumber, $expMonth, $expYear, $cvc)
|
|
|
|
158
|
- {
|
|
|
|
159
|
- $url = "https://api.stripe.com/v1/payment_methods";
|
|
|
|
160
|
- $data = [
|
|
|
|
161
|
- 'type' => 'card',
|
|
|
|
162
|
- 'card[number]' => $cardNumber,
|
|
|
|
163
|
- 'card[exp_month]' => $expMonth,
|
|
|
|
164
|
- 'card[exp_year]' => $expYear,
|
|
|
|
165
|
- 'card[cvc]' => $cvc,
|
|
|
|
166
|
- ];
|
|
|
|
167
|
-
|
|
|
|
168
|
- return $this->sendRequest($url, 'POST', $data);
|
|
|
|
169
|
- }
|
|
|
|
170
|
-
|
|
|
|
171
|
- /**
|
|
|
|
172
|
- * @remark :绑定支付方法到客户
|
|
|
|
173
|
- * @name :attachPaymentMethodToCustomer
|
|
|
|
174
|
- * @author :lyh
|
|
|
|
175
|
- * @method :post
|
|
|
|
176
|
- * @time :2024/12/24 10:42
|
|
|
|
177
|
- */
|
|
|
|
178
|
- public function attachPaymentMethodToCustomer($paymentMethodId, $customerId)
|
|
|
|
179
|
- {
|
|
|
|
180
|
- $url = "https://api.stripe.com/v1/payment_methods/{$paymentMethodId}/attach";
|
|
|
|
181
|
- $data = [
|
|
|
|
182
|
- 'customer' => $customerId,
|
|
|
|
183
|
- ];
|
|
|
|
184
|
- return $this->sendRequest($url, 'POST', $data);
|
|
|
|
185
|
- }
|
|
|
|
186
|
-
|
|
|
|
187
|
- /**
|
|
|
|
188
|
* @remark :创建退款
|
107
|
* @remark :创建退款
|
|
189
|
* @name :createRefund
|
108
|
* @name :createRefund
|
|
190
|
* @author :lyh
|
109
|
* @author :lyh
|
|
@@ -198,7 +117,6 @@ class PayStripeApi |
|
@@ -198,7 +117,6 @@ class PayStripeApi |
|
198
|
if ($amount) {
|
117
|
if ($amount) {
|
|
199
|
$data['amount'] = $amount;
|
118
|
$data['amount'] = $amount;
|
|
200
|
}
|
119
|
}
|
|
201
|
-
|
|
|
|
202
|
return $this->sendRequest($url, 'POST', $data);
|
120
|
return $this->sendRequest($url, 'POST', $data);
|
|
203
|
}
|
121
|
}
|
|
204
|
|
122
|
|
|
@@ -216,50 +134,72 @@ class PayStripeApi |
|
@@ -216,50 +134,72 @@ class PayStripeApi |
|
216
|
}
|
134
|
}
|
|
217
|
|
135
|
|
|
218
|
/**
|
136
|
/**
|
|
219
|
- * @remark :创建订阅
|
|
|
|
220
|
- * @name :createSubscription
|
|
|
|
221
|
- * @author :lyh
|
|
|
|
222
|
- * @method :post
|
|
|
|
223
|
- * @time :2024/12/24 10:42
|
|
|
|
224
|
- */
|
|
|
|
225
|
- public function createSubscription($customerId, $priceId)
|
|
|
|
226
|
- {
|
|
|
|
227
|
- $url = "https://api.stripe.com/v1/subscriptions";
|
|
|
|
228
|
- $data = [
|
|
|
|
229
|
- 'customer' => $customerId,
|
|
|
|
230
|
- 'items[0][price]' => $priceId,
|
|
|
|
231
|
- ];
|
|
|
|
232
|
- return $this->sendRequest($url, 'POST', $data);
|
|
|
|
233
|
- }
|
|
|
|
234
|
-
|
|
|
|
235
|
- /**
|
|
|
|
236
|
- * @remark :取消订阅
|
|
|
|
237
|
- * @name :cancelSubscription
|
137
|
+ * @remark :处理 Webhook
|
|
|
|
138
|
+ * @name :handleWebhook
|
|
238
|
* @author :lyh
|
139
|
* @author :lyh
|
|
239
|
* @method :post
|
140
|
* @method :post
|
|
240
|
* @time :2024/12/24 10:43
|
141
|
* @time :2024/12/24 10:43
|
|
241
|
*/
|
142
|
*/
|
|
242
|
- public function cancelSubscription($subscriptionId)
|
143
|
+ public static function handleWebhook()
|
|
243
|
{
|
144
|
{
|
|
244
|
- $url = "https://api.stripe.com/v1/subscriptions/{$subscriptionId}";
|
|
|
|
245
|
- return $this->sendRequest($url, 'DELETE');
|
145
|
+ try {
|
|
|
|
146
|
+ // Webhook 签名密钥(从 Stripe 仪表盘获取)
|
|
|
|
147
|
+ $endpointSecret = 'whsec_garhW2TrCIrduyM3rve9mFS2sn69B9Yt';
|
|
|
|
148
|
+ // 获取原始请求内容
|
|
|
|
149
|
+ $payload = request()->getContent();
|
|
|
|
150
|
+ // 获取 Stripe 签名头
|
|
|
|
151
|
+ $sigHeader = request()->header('Stripe-Signature');
|
|
|
|
152
|
+ // 验证签名
|
|
|
|
153
|
+ if (!self::verifySignature($payload, $sigHeader, $endpointSecret)) {
|
|
|
|
154
|
+ http_response_code(400);
|
|
|
|
155
|
+ throw new Exception('Invalid signature');
|
|
|
|
156
|
+ }
|
|
|
|
157
|
+ $event = json_decode($payload, true);
|
|
|
|
158
|
+ // 获取事件类型
|
|
|
|
159
|
+ $eventType = $event['type'];
|
|
|
|
160
|
+ $eventData = $event['data']['object'];
|
|
|
|
161
|
+ // 根据事件类型处理
|
|
|
|
162
|
+ switch ($eventType) {
|
|
|
|
163
|
+ case 'payment_intent.succeeded':
|
|
|
|
164
|
+ // 处理支付成功逻辑
|
|
|
|
165
|
+ @file_put_contents(storage_path('logs/lyh_error.log'), var_export($eventType, true) . PHP_EOL, FILE_APPEND);
|
|
|
|
166
|
+ @file_put_contents(storage_path('logs/lyh_error.log'), var_export($eventData, true) . PHP_EOL, FILE_APPEND);
|
|
|
|
167
|
+ $paymentIntentId = $eventData['id'];
|
|
|
|
168
|
+ break;
|
|
|
|
169
|
+ case 'payment_intent.payment_failed':
|
|
|
|
170
|
+ // 处理支付失败逻辑
|
|
|
|
171
|
+ $error = $eventData['last_payment_error'];
|
|
|
|
172
|
+ break;
|
|
|
|
173
|
+ case 'charge.refunded':
|
|
|
|
174
|
+ // 处理退款逻辑
|
|
|
|
175
|
+ $chargeId = $eventData['id'];
|
|
|
|
176
|
+ break;
|
|
|
|
177
|
+ default:
|
|
|
|
178
|
+ throw new Exception('Unhandled event type: ' . $eventType);
|
|
|
|
179
|
+ }
|
|
|
|
180
|
+ return $event;
|
|
|
|
181
|
+ } catch (Exception $e) {
|
|
|
|
182
|
+ throw new Exception('Webhook Error: ' . $e->getMessage());
|
|
|
|
183
|
+ }
|
|
246
|
}
|
184
|
}
|
|
247
|
|
185
|
|
|
248
|
/**
|
186
|
/**
|
|
249
|
- * @remark :处理 Webhook
|
|
|
|
250
|
- * @name :handleWebhook
|
187
|
+ * @remark :验证签名
|
|
|
|
188
|
+ * @name :verifySignature
|
|
251
|
* @author :lyh
|
189
|
* @author :lyh
|
|
252
|
* @method :post
|
190
|
* @method :post
|
|
253
|
- * @time :2024/12/24 10:43
|
191
|
+ * @time :2024/12/24 15:55
|
|
254
|
*/
|
192
|
*/
|
|
255
|
- public static function handleWebhook($payload, $sigHeader, $endpointSecret)
|
193
|
+ private function verifySignature($payload, $sigHeader, $endpointSecret)
|
|
256
|
{
|
194
|
{
|
|
257
|
- try {
|
|
|
|
258
|
- $event = json_decode($payload, true);
|
|
|
|
259
|
- // 检查事件类型
|
|
|
|
260
|
- return $event; // 返回解析后的事件
|
|
|
|
261
|
- } catch (Exception $e) {
|
|
|
|
262
|
- throw new Exception('Webhook Error: ' . $e->getMessage());
|
195
|
+ // 获取 Stripe 签名
|
|
|
|
196
|
+ $signatures = [];
|
|
|
|
197
|
+ if (preg_match_all('/t=\d+,v1=([a-f0-9]+)/', $sigHeader, $matches)) {
|
|
|
|
198
|
+ $signatures = $matches[1];
|
|
263
|
}
|
199
|
}
|
|
|
|
200
|
+ // 计算签名哈希值
|
|
|
|
201
|
+ $expectedSignature = hash_hmac('sha256', $payload, $endpointSecret);
|
|
|
|
202
|
+ return in_array($expectedSignature, $signatures, true);
|
|
264
|
}
|
203
|
}
|
|
|
|
204
|
+
|
|
265
|
} |
205
|
} |