|
|
@@ -3,19 +3,66 @@ declare(strict_types=1);
|
|
|
|
|
|
namespace SixShop\Lakala;
|
|
|
|
|
|
+use SixShop\Lakala\Dto\LocationInfo;
|
|
|
+use SixShop\Lakala\Facade\TransactionService;
|
|
|
+use SixShop\Lakala\OpenAPISDK\V3\Model\TradePreorderWechaAccBusiFields;
|
|
|
+use SixShop\Lakala\OpenAPISDK\V3\Model\TradePreorderWechaDetail;
|
|
|
+use SixShop\Lakala\OpenAPISDK\V3\Model\TradePreorderWechaGoodsDetail;
|
|
|
use SixShop\Payment\Contracts\PaymentNotifyResult;
|
|
|
use SixShop\Payment\Contracts\PaymentProviderInterface;
|
|
|
use SixShop\Payment\Contracts\PaymentQueryResult;
|
|
|
use SixShop\Payment\Contracts\PaymentRefundRequest;
|
|
|
use SixShop\Payment\Contracts\PaymentRefundResult;
|
|
|
use SixShop\Payment\Contracts\PaymentResponse;
|
|
|
+use SixShop\Payment\Entity\ExtensionPaymentEntity;
|
|
|
use SixShop\Payment\Enum\PaymentBizEnum;
|
|
|
+use SixShop\Payment\Enum\PaymentStatusEnum;
|
|
|
|
|
|
class PaymentProvider implements PaymentProviderInterface
|
|
|
{
|
|
|
+ public function __construct(
|
|
|
+ private readonly Config $config,
|
|
|
+ private readonly ExtensionPaymentEntity $extensionPaymentEntity
|
|
|
+ )
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
#[\Override] public function create(array $order, PaymentBizEnum $bizType): PaymentResponse
|
|
|
{
|
|
|
- throw new \Exception('Not implemented');
|
|
|
+ $payment = $this->extensionPaymentEntity->where([
|
|
|
+ 'order_id' => $order['id'],
|
|
|
+ 'pay_type' => Extension::EXTENSION_ID,
|
|
|
+ 'biz_type' => $bizType,
|
|
|
+ ])->findOrEmpty();
|
|
|
+ if (!$payment->isEmpty()) {
|
|
|
+ // todo 判断订单是否支付成功
|
|
|
+ // 支付时间结束关闭订单
|
|
|
+ // 订单未支付可重新支付
|
|
|
+ // 交易已关闭请重新下单
|
|
|
+ //订单已付款请勿重复操作
|
|
|
+ // 订单已退款请重新下单
|
|
|
+ //订单已撤销请重新下单
|
|
|
+ // 订单支付中请稍后再试
|
|
|
+ // 订单支付失败请重新下单
|
|
|
+ throw new \RuntimeException('开发测试中,请稍后再试');
|
|
|
+ }
|
|
|
+ $payment->transaction(function () use ($bizType, $order, $payment) {
|
|
|
+ $payment->save([
|
|
|
+ 'user_id' => $order['user_id'],
|
|
|
+ 'order_id' => $order['id'],
|
|
|
+ 'order_sn' => $order['order_sn'],
|
|
|
+ 'biz_type' => $bizType,
|
|
|
+ 'pay_type' => Extension::EXTENSION_ID,
|
|
|
+ 'amount' => $order['pay_amount'],
|
|
|
+ 'status' => PaymentStatusEnum::PENDING
|
|
|
+ ]);
|
|
|
+ $expireDuration = 15; // 分钟
|
|
|
+ $payment->expire_time = time() + $expireDuration * 60;
|
|
|
+ $payment->payment_param = $this->createPaymentParam($order, $payment, $expireDuration);
|
|
|
+ $payment->transaction_id = $payment->payment_param['transactionID'];
|
|
|
+ $payment->save();
|
|
|
+ });
|
|
|
+ return new PaymentResponse(orderNo: $payment->out_trade_no, type: self::PAYMENT_TYPE, raw: $payment->toArray());
|
|
|
}
|
|
|
|
|
|
#[\Override] public function notify(array $request): PaymentNotifyResult
|
|
|
@@ -37,4 +84,33 @@ class PaymentProvider implements PaymentProviderInterface
|
|
|
{
|
|
|
throw new \Exception('Not implemented');
|
|
|
}
|
|
|
+
|
|
|
+ private function createPaymentParam(array $order, ExtensionPaymentEntity $payment, int $expireDuration): array
|
|
|
+ {
|
|
|
+ $accBusiFields = new TradePreorderWechaAccBusiFields();
|
|
|
+ $accBusiFields->setTimeoutExpress($expireDuration);
|
|
|
+ $accBusiFields->setSubAppid($this->config->sub_appid);
|
|
|
+ $accBusiFields->setUserId($order['params']['openid']);
|
|
|
+ $detail = new TradePreorderWechaDetail();
|
|
|
+ $goodsDetailList = [];
|
|
|
+ foreach ($order['order_goods'] as $goods) {
|
|
|
+ $goodsDetail = new TradePreorderWechaGoodsDetail();
|
|
|
+ $goodsDetail->setGoodsId($goods['goods_id']);
|
|
|
+ $goodsDetail->setQuantity($goods['num']);
|
|
|
+ $goodsDetail->setPrice(round($goods['price'] * 100, 0));
|
|
|
+ $goodsDetail->setGoodsName($goods['goods_name']);
|
|
|
+ $goodsDetailList[] = $goodsDetail;
|
|
|
+ }
|
|
|
+ $detail->setGoodsDetail($goodsDetailList);
|
|
|
+ $accBusiFields->setDetail($detail);
|
|
|
+ TransactionService::preOrder(
|
|
|
+ outTradeNo: $payment['out_trade_no'],
|
|
|
+ totalAmount: $payment['amount'],
|
|
|
+ locationInfo: new LocationInfo(requestIP: $order['params']['ip']),
|
|
|
+ subject: '订单:' . $order['order_sn'],
|
|
|
+ settleType: '1', // 拉卡拉分账
|
|
|
+ remark: $order['description'],
|
|
|
+ accBusiFields: $accBusiFields,
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|