Xboard/app/Payments/StripeALLInOne.php
LinusX 261487437b [update] 新增stripe聚合支付方式,采用全新的paymentIntents API
[fix] 修改支付方式中的小bug
[update] 将stripe-php版本升级至最新
2024-06-05 07:55:49 +08:00

174 lines
6.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* 自己写别抄抄NMB抄
*/
namespace App\Payments;
use App\Exceptions\ApiException;
use Illuminate\Support\Facades\Log;
class StripeALLInOne {
public function __construct($config)
{
$this->config = $config;
}
public function form()
{
return [
'currency' => [
'label' => '货币单位',
'description' => '请使用符合ISO 4217标准的三位字母例如GBP',
'type' => 'input',
],
'stripe_sk_live' => [
'label' => 'SK_LIVE',
'description' => '',
'type' => 'input',
],
'stripe_webhook_key' => [
'label' => 'WebHook密钥签名',
'description' => 'whsec_....',
'type' => 'input',
],
'description' => [
'label' => '自定义商品介绍',
'description' => '',
'type' => 'input',
],
'payment_method' => [
'label' => '支付方式',
'description' => '请输入alipay或者wechat_pay',
'type' => 'input',
]
];
}
public function pay($order)
{
$currency = $this->config['currency'];
$exchange = $this->exchange('CNY', strtoupper($currency));
if (!$exchange) {
throw new ApiException(__('Currency conversion has timed out, please try again later'));
}
$stripe = new \Stripe\StripeClient($this->config['stripe_sk_live']);
$stripePaymentMethod = $stripe->paymentMethods->create([
'type' => $this->config['payment_method'],
]);
// 准备支付意图的基础参数
$params = [
'amount' => floor($order['total_amount'] * $exchange),
'currency' => $currency,
'confirm' => true,
'payment_method' => $stripePaymentMethod->id,
'automatic_payment_methods' => ['enabled' => true],
'statement_descriptor' => 'sub-' . $order['user_id'] . '-' . substr($order['trade_no'], -8),
'description' => $this->config['description'],
'metadata' => [
'user_id' => $order['user_id'],
'out_trade_no' => $order['trade_no'],
'identifier' => ''
],
'return_url' => $order['return_url']
];
// 如果支付方式为 wechat_pay添加相应的支付方式选项
if ($this->config['payment_method'] === 'wechat_pay') {
$params['payment_method_options'] = [
'wechat_pay' => [
'client' => 'web'
],
];
}
//更新支持最新的paymentIntents方法Sources API将在今年被彻底替
$stripeIntents = $stripe->paymentIntents->create($params);
$nextAction = null;
//jump url
$jumpUrl = null;
$actionType = 0;
if (!$stripeIntents['next_action']) {
throw new ApiException(__('Payment gateway request failed'));
}else {
$nextAction = $stripeIntents['next_action'];
}
switch ($this->config['payment_method']){
case "alipay":
if (isset($nextAction['alipay_handle_redirect'])){
$jumpUrl = $nextAction['alipay_handle_redirect']['url'];
$actionType = 1;
}else {
throw new ApiException('unable get alipay redirect url', 500);
}
break;
case "wechat_pay":
if (isset($nextAction['wechat_pay_display_qr_code'])){
$jumpUrl = $nextAction['wechat_pay_display_qr_code']['data'];
Log::info($jumpUrl);
}else {
throw new ApiException('unable get alipay redirect url', 500);
}
}
return [
'type' => $actionType,
'data' => $jumpUrl
];
}
public function notify($params)
{
try {
\Stripe\Stripe::setApiKey($this->config['stripe_sk_live']);
//Workerman不支持使用php://input, stripe同时要求验证签名的payload不能经过修改所以使用这个方法
$payload = $GLOBALS['HTTP_RAW_POST_DATA'];
$headers = getallheaders();
$headerName = 'Stripe-Signature';
$signatureHeader = $headers[$headerName] ?? '';
$event = \Stripe\Webhook::constructEvent(
$payload,
$signatureHeader,
$this->config['stripe_webhook_key']
);
} catch (\UnexpectedValueException $e){
throw new ApiException('Error parsing payload', 400);
}
catch (\Stripe\Exception\SignatureVerificationException $e) {
throw new ApiException('signature not match', 400);
}
switch ($event->type) {
case 'payment_intent.succeeded':
$object = $event->data->object;
if ($object->status === 'succeeded') {
if (!isset($object->metadata->out_trade_no)) {
return('order error');
}
$metaData = $object->metadata;
$tradeNo = $metaData->out_trade_no;
return [
'trade_no' => $tradeNo,
'callback_no' => $object->id
];
}
break;
default:
throw new ApiException('event is not support');
}
return('success');
}
private function exchange($from, $to)
{
$from = strtolower($from);
$to = strtolower($to);
$result = file_get_contents("https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/" . $from . ".min.json");
$result = json_decode($result, true);
return $result[$from][$to];
}
}