|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @remark :
|
|
|
|
* @name :PayStripeApi.php
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:35
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace App\Helper;
|
|
|
|
|
|
|
|
class PayStripeApi
|
|
|
|
{
|
|
|
|
private $secretKey;
|
|
|
|
//币种对应支付方式
|
|
|
|
public $currency_types = [
|
|
|
|
'usd' => ['card', 'alipay', 'wechat_pay', 'cashapp', 'link', 'afterpay_clearpay'],
|
|
|
|
'eur' => ['card', 'ideal', 'giropay', 'sofort', 'bancontact', 'klarna', 'link'],
|
|
|
|
'gbp' => ['card', 'apple_pay', 'google_pay', 'klarna', 'link', 'afterpay_clearpay'],
|
|
|
|
'aud' => ['card', 'afterpay_clearpay', 'apple_pay', 'google_pay'],
|
|
|
|
'cad' => ['card', 'apple_pay', 'google_pay', 'link'],
|
|
|
|
'sgd' => ['card', 'grabpay', 'fpx', 'wechat_pay', 'apple_pay', 'google_pay'],
|
|
|
|
'jpy' => ['card', 'apple_pay', 'google_pay'],
|
|
|
|
'cny' => ['alipay', 'wechat_pay'],
|
|
|
|
'brl' => ['card', 'boleto', 'pix'],
|
|
|
|
'mxn' => ['card', 'oxxo'],
|
|
|
|
'inr' => ['card', 'upi', 'netbanking'],
|
|
|
|
'php' => ['card', 'paymaya', 'gcash'],
|
|
|
|
'myr' => ['card', 'fpx'],
|
|
|
|
'thb' => ['card', 'promptpay'],
|
|
|
|
'idr' => ['card', 'bank_transfer'],
|
|
|
|
'zar' => ['card'],
|
|
|
|
'ngn' => ['card'],
|
|
|
|
'aed' => ['card', 'apple_pay', 'google_pay']
|
|
|
|
];
|
|
|
|
|
|
|
|
// 构造函数设置密钥
|
|
|
|
public function __construct($secretKey)
|
|
|
|
{
|
|
|
|
$this->secretKey = 'sk_test_51MyseXIWCYVeLww1tbPZzRe1Qk4lS5d2VLiDjpju7G0ToiX1RJcFinQXNlftq9eCjZE0n2gjaz1mfy1g0mxTusdf00m636Gv62';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :通用的 cURL 请求方法
|
|
|
|
* @name :sendRequest
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:38
|
|
|
|
*/
|
|
|
|
private function sendRequest($url, $method = 'POST', $data = [])
|
|
|
|
{
|
|
|
|
$ch = curl_init();
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
|
|
"Authorization: Bearer {$this->secretKey}",
|
|
|
|
"Content-Type: application/x-www-form-urlencoded"
|
|
|
|
]);
|
|
|
|
if ($method === 'POST') {
|
|
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
|
|
|
} elseif ($method === 'GET') {
|
|
|
|
curl_setopt($ch, CURLOPT_HTTPGET, true);
|
|
|
|
} elseif ($method === 'DELETE') {
|
|
|
|
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
|
|
|
}
|
|
|
|
$response = curl_exec($ch);
|
|
|
|
if (curl_errno($ch)) {
|
|
|
|
throw new Exception('cURL Error: ' . curl_error($ch));
|
|
|
|
}
|
|
|
|
curl_close($ch);
|
|
|
|
return json_decode($response, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :创建支付意图
|
|
|
|
* @name :createPaymentIntent
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:38
|
|
|
|
*/
|
|
|
|
public function createPaymentIntent($amount, $currency = 'usd')
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/payment_intents";
|
|
|
|
$data = [
|
|
|
|
'amount' => $amount,
|
|
|
|
'currency' => $currency,
|
|
|
|
'payment_method_types[]' => $this->currency_types[$currency],
|
|
|
|
];
|
|
|
|
return $this->sendRequest($url, 'POST', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :查询支付意图
|
|
|
|
* @name :retrievePaymentIntent
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:38
|
|
|
|
*/
|
|
|
|
public function retrievePaymentIntent($paymentIntentId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/payment_intents/{$paymentIntentId}";
|
|
|
|
return $this->sendRequest($url, 'GET');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :创建客户
|
|
|
|
* @name :createCustomer
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:41
|
|
|
|
*/
|
|
|
|
public function createCustomer($name, $email, $description = '')
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/customers";
|
|
|
|
$data = [
|
|
|
|
'name' => $name,
|
|
|
|
'email' => $email,
|
|
|
|
'description' => $description
|
|
|
|
];
|
|
|
|
return $this->sendRequest($url, 'POST', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :查询客户
|
|
|
|
* @name :retrieveCustomer
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:41
|
|
|
|
*/
|
|
|
|
public function retrieveCustomer($customerId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/customers/{$customerId}";
|
|
|
|
return $this->sendRequest($url, 'GET');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :删除客户
|
|
|
|
* @name :deleteCustomer
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:42
|
|
|
|
*/
|
|
|
|
public function deleteCustomer($customerId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/customers/{$customerId}";
|
|
|
|
return $this->sendRequest($url, 'DELETE');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :创建支付方法
|
|
|
|
* @name :createPaymentMethod
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:42
|
|
|
|
*/
|
|
|
|
public function createPaymentMethod($cardNumber, $expMonth, $expYear, $cvc)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/payment_methods";
|
|
|
|
$data = [
|
|
|
|
'type' => 'card',
|
|
|
|
'card[number]' => $cardNumber,
|
|
|
|
'card[exp_month]' => $expMonth,
|
|
|
|
'card[exp_year]' => $expYear,
|
|
|
|
'card[cvc]' => $cvc,
|
|
|
|
];
|
|
|
|
|
|
|
|
return $this->sendRequest($url, 'POST', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :绑定支付方法到客户
|
|
|
|
* @name :attachPaymentMethodToCustomer
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:42
|
|
|
|
*/
|
|
|
|
public function attachPaymentMethodToCustomer($paymentMethodId, $customerId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/payment_methods/{$paymentMethodId}/attach";
|
|
|
|
$data = [
|
|
|
|
'customer' => $customerId,
|
|
|
|
];
|
|
|
|
return $this->sendRequest($url, 'POST', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :创建退款
|
|
|
|
* @name :createRefund
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:42
|
|
|
|
*/
|
|
|
|
public function createRefund($chargeId, $amount = null)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/refunds";
|
|
|
|
$data = ['charge' => $chargeId];
|
|
|
|
if ($amount) {
|
|
|
|
$data['amount'] = $amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->sendRequest($url, 'POST', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :查询退款
|
|
|
|
* @name :retrieveRefund
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:42
|
|
|
|
*/
|
|
|
|
public function retrieveRefund($refundId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/refunds/{$refundId}";
|
|
|
|
return $this->sendRequest($url, 'GET');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :创建订阅
|
|
|
|
* @name :createSubscription
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:42
|
|
|
|
*/
|
|
|
|
public function createSubscription($customerId, $priceId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/subscriptions";
|
|
|
|
$data = [
|
|
|
|
'customer' => $customerId,
|
|
|
|
'items[0][price]' => $priceId,
|
|
|
|
];
|
|
|
|
return $this->sendRequest($url, 'POST', $data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :取消订阅
|
|
|
|
* @name :cancelSubscription
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:43
|
|
|
|
*/
|
|
|
|
public function cancelSubscription($subscriptionId)
|
|
|
|
{
|
|
|
|
$url = "https://api.stripe.com/v1/subscriptions/{$subscriptionId}";
|
|
|
|
return $this->sendRequest($url, 'DELETE');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @remark :处理 Webhook
|
|
|
|
* @name :handleWebhook
|
|
|
|
* @author :lyh
|
|
|
|
* @method :post
|
|
|
|
* @time :2024/12/24 10:43
|
|
|
|
*/
|
|
|
|
public static function handleWebhook($payload, $sigHeader, $endpointSecret)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
$event = json_decode($payload, true);
|
|
|
|
// 检查事件类型
|
|
|
|
return $event; // 返回解析后的事件
|
|
|
|
} catch (Exception $e) {
|
|
|
|
throw new Exception('Webhook Error: ' . $e->getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} |
...
|
...
|
|